/*

 Copyright 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(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.makeIterator=function(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):$jscomp.arrayIterator(a)};$jscomp.arrayFromIterator=function(a){for(var b,c=[];!(b=a.next()).done;)c.push(b.value);return c};
$jscomp.arrayFromIterable=function(a){return a instanceof Array?a:$jscomp.arrayFromIterator($jscomp.makeIterator(a))};$jscomp.findInternal=function(a,b,c){a instanceof String&&(a=String(a));for(var d=a.length,e=0;e<d;e++){var f=a[e];if(b.call(c,f,e,a))return{i:e,v:f}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.ISOLATE_POLYFILLS=!1;
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};$jscomp.getGlobal=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(a,b){var c=$jscomp.propertyToPolyfillSymbol[b];if(null==c)return a[b];c=a[c];return void 0!==c?c:a[b]};
$jscomp.polyfill=function(a,b,c,d){b&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(a,b,c,d):$jscomp.polyfillUnisolated(a,b,c,d))};$jscomp.polyfillUnisolated=function(a,b,c,d){c=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))return;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:b})};
$jscomp.polyfillIsolated=function(a,b,c,d){var e=a.split(".");a=1===e.length;d=e[0];d=!a&&d in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var f=0;f<e.length-1;f++){var g=e[f];if(!(g in d))return;d=d[g]}e=e[e.length-1];c=$jscomp.IS_SYMBOL_NATIVE&&"es6"===c?d[e]:null;b=b(c);null!=b&&(a?$jscomp.defineProperty($jscomp.polyfills,e,{configurable:!0,writable:!0,value:b}):b!==c&&($jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE?$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+e,e=
$jscomp.propertyToPolyfillSymbol[e],$jscomp.defineProperty(d,e,{configurable:!0,writable:!0,value:b})))};$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(b,c){return $jscomp.findInternal(this,b,c).v}},"es6","es3");
var PlayExampleClassName={PLAY_HREF:".js-exampleHref",PLAY_CONTAINER:".js-exampleContainer",EXAMPLE_INPUT:".Documentation-exampleCode",EXAMPLE_OUTPUT:".Documentation-exampleOutput",EXAMPLE_ERROR:".Documentation-exampleError",PLAY_BUTTON:".Documentation-examplePlayButton"},PlaygroundExampleController=function(a){var b=this,c=!1;a||(console.warn("Must provide playground example element"),c=!0);this._exampleEl=a;var d=a.querySelector("a");d||(console.warn("anchor tag is not detected"),c=!0);this._anchorEl=
d;(d=a.querySelector(PlayExampleClassName.EXAMPLE_ERROR))||(c=!0);this._errorEl=d;(d=a.querySelector(PlayExampleClassName.PLAY_BUTTON))||(c=!0);this._playButtonEl=d;d=a.querySelector(PlayExampleClassName.EXAMPLE_INPUT);d||(console.warn("Input element is not detected"),c=!0);this._inputEl=d;this._outputEl=a.querySelector(PlayExampleClassName.EXAMPLE_OUTPUT);c||this._playButtonEl.addEventListener("click",function(e){return b.handlePlayButtonClick(e)})};
PlaygroundExampleController.prototype.getAnchorHash=function(){return this._anchorEl.hash};PlaygroundExampleController.prototype.expand=function(){this._exampleEl.open=!0};PlaygroundExampleController.prototype.setOutputText=function(a){this._outputEl&&(this._outputEl.textContent=a)};PlaygroundExampleController.prototype.setErrorText=function(a){this._errorEl.textContent=a;this.setOutputText("An error has occurred\u2026")};
PlaygroundExampleController.prototype.handlePlayButtonClick=function(a){var b=this;this.setOutputText("Waiting for remote server\u2026");fetch("/play/",{method:"POST",body:this._inputEl.textContent}).then(function(c){return c.text()}).then(function(c){window.open("//play.golang.org/p/"+c)}).catch(function(c){b.setErrorText(c)})};var exampleHashRegex=location.hash.match(/^#(example-.*)$/);
if(exampleHashRegex){var exampleHashEl=document.getElementById(exampleHashRegex[1]);exampleHashEl&&(exampleHashEl.open=!0)}var exampleHrefs=[].concat($jscomp.arrayFromIterable(document.querySelectorAll(PlayExampleClassName.PLAY_HREF))),findExampleHash=function(a){return exampleHrefs.find(function(b){return b.hash===a.getAnchorHash()})};
document.querySelectorAll(PlayExampleClassName.PLAY_CONTAINER).forEach(function(a){var b=new PlaygroundExampleController(a);(a=findExampleHash(b))?a.addEventListener("click",function(){b.expand()}):console.warn("example href not found")});
