/*

 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(b){var c=0;return function(){return c<b.length?{done:!1,value:b[c++]}:{done:!0}}};$jscomp.arrayIterator=function(b){return{next:$jscomp.arrayIteratorImpl(b)}};$jscomp.makeIterator=function(b){var c="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];return c?c.call(b):$jscomp.arrayIterator(b)};
(function(b,c){"object"===typeof exports&&"undefined"!==typeof module?module.exports=c():"function"===typeof define&&define.amd?define(c):(b=b||self,b.dialogPolyfill=c())})(this,function(){function b(a){for(;a&&a!==document.body;){var h=window.getComputedStyle(a),b=function(a,b){return!(void 0===h[a]||h[a]===b)};if(1>h.opacity||b("zIndex","auto")||b("transform","none")||b("mixBlendMode","normal")||b("filter","none")||b("perspective","none")||"isolate"===h.isolation||"fixed"===h.position||"touch"===
h.webkitOverflowScrolling)return!0;a=a.parentElement}return!1}function c(a){for(;a;){if("dialog"===a.localName)return a;a=a.parentElement}return null}function e(a){a&&a.blur&&a!==document.body&&a.blur()}function d(a){return a&&a.hasAttribute("method")?"dialog"===a.getAttribute("method").toLowerCase():!1}function g(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,c=function(){b?this.downgradeModal():this.maybeHideModal();b=!1}.bind(this),d,f=function(h){h.target===a&&(b|="DOMNodeRemoved"===h.type.substr(0,14),window.clearTimeout(d),d=window.setTimeout(c,0))};["DOMAttrModified","DOMNodeRemoved","DOMNodeRemovedFromDocument"].forEach(function(b){a.addEventListener(b,
f)})}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 l=window.CustomEvent;l&&"object"!==typeof l||(l=function(a,b){b=b||{};var h=document.createEvent("CustomEvent");h.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail||null);return h},l.prototype=window.Event.prototype);g.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_),f.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(a){return a+":not([disabled])"}),a.push('[tabindex]:not([disabled]):not([tabindex=""])'),a=this.dialog_.querySelector(a.join(", ")));e(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(!f.dm.pushDialog(this))throw Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");
b(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;f.needsCentering(this.dialog_)?(f.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 l("close",{bubbles:!1,cancelable:!1});if(this.dialog_.onclose instanceof Function)this.dialog_.onclose(a);this.dialog_.dispatchEvent(a)}};var f={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 c=document.styleSheets[b],d=null;try{d=
c.cssRules}catch(m){}if(d)for(c=0;c<d.length;++c){var f=d[c],e=null;try{e=document.querySelectorAll(f.selectorText)}catch(m){}var g;if(!(g=!e)){a:{for(g=0;g<e.length;++g)if(e[g]===a){e=!0;break a}e=!1}g=!e}if(!g&&(e=f.style.getPropertyValue("top"),f=f.style.getPropertyValue("bottom"),e&&"auto"!==e||f&&"auto"!==f))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:!f.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 g(a)},registerDialog:function(a){a.showModal||f.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 c=[];b.forEach(function(a){for(var b=0,h;h=a.removedNodes[b];++b)h instanceof Element&&("dialog"===h.localName&&c.push(h),
c=c.concat(h.querySelectorAll("dialog")))});c.length&&a(c)}))}};f.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})};f.DialogManager.prototype.unblockDocument=function(){document.documentElement.removeEventListener("focus",this.handleFocus_,!0);document.removeEventListener("keydown",this.handleKey_);this.mo_&&this.mo_.disconnect()};
f.DialogManager.prototype.updateStacking=function(){for(var a=this.zIndexHigh_,b=0,c;c=this.pendingDialogStack[b];++b)c.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)};f.DialogManager.prototype.containedByTopDialog_=function(a){for(;a=c(a);){for(var b=0,d;d=this.pendingDialogStack[b];++b)if(d.dialog===a)return 0===b;
a=a.parentElement}return!1};f.DialogManager.prototype.handleFocus_=function(a){if(!this.containedByTopDialog_(a.target)&&document.activeElement!==document.documentElement&&(a.preventDefault(),a.stopPropagation(),e(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}};f.DialogManager.prototype.handleKey_=
function(a){this.forwardTab_=void 0;if(27===a.keyCode){a.preventDefault();a.stopPropagation();a=new l("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)};f.DialogManager.prototype.checkDOM_=function(a){this.pendingDialogStack.slice().forEach(function(b){-1!==a.indexOf(b.dialog)?b.downgradeModal():b.maybeHideModal()})};f.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};f.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())};f.dm=new f.DialogManager;f.formSubmitter=null;f.useValue=null;if(void 0===window.HTMLDialogElement){var k=document.createElement("form");k.setAttribute("method",
"dialog");if("dialog"!==k.method&&(k=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"method"))){var n=k.get;k.get=function(){return d(this)?"dialog":n.call(this)};var p=k.set;k.set=function(a){return"string"===typeof a&&"dialog"===a.toLowerCase()?this.setAttribute("method",a):p.call(this,a)};Object.defineProperty(HTMLFormElement.prototype,"method",k)}document.addEventListener("click",function(a){f.formSubmitter=null;f.useValue=null;if(!a.defaultPrevented){var b=a.target;if(b&&d(b.form)){if(!("submit"===
b.type&&-1<["button","input"].indexOf(b.localName))){if("input"!==b.localName||"image"!==b.type)return;f.useValue=a.offsetX+","+a.offsetY}c(b)&&(f.formSubmitter=b)}}},!1);var q=HTMLFormElement.prototype.submit;HTMLFormElement.prototype.submit=function(){if(!d(this))return q.call(this);var a=c(this);a&&a.close()};document.addEventListener("submit",function(a){if(!a.defaultPrevented){var b=a.target;if(d(b)&&(a.preventDefault(),a=c(b))){var e=f.formSubmitter;e&&e.form===b?a.close(f.useValue||e.value):
a.close();f.formSubmitter=null}}},!1)}return f});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 b=[],c=document.querySelector(".Documentation"),e=$jscomp.makeIterator(c.querySelectorAll("[data-kind]")),d=e.next();!d.done;d=e.next())b.push(newJumpListItem(d.value));0==b.length&&(b=collectJumpListItemsFallback(c));c=$jscomp.makeIterator(b);for(e=c.next();!e.done;e=c.next())e.value.link.addEventListener("click",function(){jumpDialog.close()});b.sort(function(b,c){return b.lower.localeCompare(c.lower)});return b}
function collectJumpListItemsFallback(b){var c=[],e={};b=$jscomp.makeIterator(b.querySelectorAll("*[id]"));for(var d=b.next();!d.done;d=b.next()){d=d.value;var g=d.getAttribute("id");!e[g]&&/^[^_][^-]*$/.test(g)&&(e[g]=!0,c.push(newJumpListItem(d)))}return c}
function newJumpListItem(b){var c=document.createElement("a"),e=b.getAttribute("id");c.setAttribute("href","#"+e);c.setAttribute("tabindex","-1");var d=b.getAttribute("data-kind");d||(d=guessKind(b));return{link:c,name:e,kind:d,lower:e.toLowerCase()}}
function guessKind(b){switch(b.getAttribute("class")){case "Documentation-functionHeader":case "Documentation-typeFuncHeader":return"function";case "Documentation-typeHeader":return"type";case "Documentation-typeMethodHeader":return"method";default:switch(b.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(b){lastFilterValue=b;jumpListItems||(jumpListItems=collectJumpListItems());for(setActiveJumpItem(-1);jumpList.firstChild;)jumpList.firstChild.remove();for(var c=new RegExp(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"gi"),e=$jscomp.makeIterator(jumpListItems),d=e.next();!d.done;d=e.next()){d=d.value;var g=d.name;if(b&&(g=g.replace(c,function(b){return"<b>"+b+"</b>"}),g==d.name))continue;d.link.innerHTML=g+" <i>"+d.kind+"</i>";jumpList.appendChild(d.link)}jumpBody.scrollTop=
0;0<jumpList.children.length&&setActiveJumpItem(0)}function setActiveJumpItem(b){var c=jumpList.children;0<=activeJumpItem&&c[activeJumpItem].classList.remove("JumpDialog-active");b>=c.length&&(b=c.length-1);if(0<=b){c[b].classList.add("JumpDialog-active");var e=c[b].offsetTop-c[0].offsetTop;c=e+c[b].clientHeight;e<jumpBody.scrollTop?jumpBody.scrollTop=e:c>jumpBody.scrollTop+jumpBody.clientHeight&&(jumpBody.scrollTop=c-jumpBody.clientHeight)}activeJumpItem=b}
function incActiveJumpItem(b){0>activeJumpItem||(b=activeJumpItem+b,0>b&&(b=0),setActiveJumpItem(b))}jumpFilter.addEventListener("keyup",function(b){jumpFilter.value.toUpperCase()!=lastFilterValue.toUpperCase()&&updateJumpList(jumpFilter.value)});jumpFilter.addEventListener("keydown",function(b){switch(b.which){case 38:incActiveJumpItem(-1);b.preventDefault();break;case 40:incActiveJumpItem(1);b.preventDefault();break;case 13:0<=activeJumpItem&&jumpList.children[activeJumpItem].click()}});
var shortcutsDialog=document.querySelector(".ShortcutsDialog");shortcutsDialog.showModal||dialogPolyfill.registerDialog(shortcutsDialog);
document.addEventListener("keypress",function(b){if(!jumpDialog.open&&!shortcutsDialog.open){var c=b.target.tagName;if("INPUT"!=c&&"SELECT"!=c&&"TEXTAREA"!=c&&!(b.target.contentEditable&&"true"==b.target.contentEditable||b.metaKey||b.ctrlKey))switch(String.fromCharCode(b.which)){case "f":case "F":b.preventDefault();jumpFilter.value="";jumpDialog.showModal();updateJumpList("");break;case "?":shortcutsDialog.showModal();break;case "/":b.preventDefault(),searchInput.focus()}}});
