1 line
1.1 MiB
1 line
1.1 MiB
{"version":3,"sources":["../../node_modules/google-closure-library/closure/goog/base.js","src/com/google/javascript/jscomp/js/es6/util/arrayiterator.js","src/com/google/javascript/jscomp/js/es6/util/makeiterator.js","src/com/google/javascript/jscomp/js/util/objectcreate.js","src/com/google/javascript/jscomp/js/util/defineproperty.js","src/com/google/javascript/jscomp/js/util/global.js","src/com/google/javascript/jscomp/js/util/polyfill.js","src/com/google/javascript/jscomp/js/es6/util/setprototypeof.js","src/com/google/javascript/jscomp/js/es6/symbol.js","src/com/google/javascript/jscomp/js/es6/promise/promise.js","src/com/google/javascript/jscomp/js/es6/util/iteratorfromarray.js","src/com/google/javascript/jscomp/js/es6/array/values.js","src/com/google/javascript/jscomp/js/es6/array/keys.js","src/com/google/javascript/jscomp/js/util/owns.js","src/com/google/javascript/jscomp/js/es6/weakmap.js","src/com/google/javascript/jscomp/js/es6/map.js","src/com/google/javascript/jscomp/js/es6/array/find.js","src/com/google/javascript/jscomp/js/util/findinternal.js","src/com/google/javascript/jscomp/js/es6/array/entries.js","src/com/google/javascript/jscomp/js/es6/array/from.js","src/com/google/javascript/jscomp/js/es6/set.js","../../node_modules/google-closure-library/closure/goog/disposable/disposable.js","../../node_modules/google-closure-library/closure/goog/array/array.js","../../node_modules/google-closure-library/closure/goog/events/event.js","../../node_modules/google-closure-library/closure/goog/events/browserfeature.js","../../node_modules/google-closure-library/closure/goog/string/internal.js","../../node_modules/google-closure-library/closure/goog/labs/useragent/util.js","../../node_modules/google-closure-library/closure/goog/reflect/reflect.js","../../node_modules/google-closure-library/closure/goog/math/integer.js","../../node_modules/google-closure-library/closure/goog/useragent/useragent.js","../../node_modules/google-closure-library/closure/goog/labs/useragent/browser.js","../../node_modules/google-closure-library/closure/goog/labs/useragent/engine.js","../../node_modules/google-closure-library/closure/goog/events/browserevent.js","../../node_modules/google-closure-library/closure/goog/events/eventtype.js","../../node_modules/google-closure-library/closure/goog/events/listenable.js","../../node_modules/google-closure-library/closure/goog/events/listenablekey.js","../../node_modules/google-closure-library/closure/goog/events/listener.js","../../node_modules/google-closure-library/closure/goog/events/listenermap.js","../../node_modules/google-closure-library/closure/goog/object/object.js","../../node_modules/google-closure-library/closure/goog/events/events.js","../../node_modules/google-closure-library/closure/goog/events/eventtarget.js","../../node_modules/google-closure-library/closure/goog/json/json.js","../../node_modules/google-closure-library/closure/goog/async/freelist.js","../../node_modules/google-closure-library/closure/goog/async/workqueue.js","../../node_modules/google-closure-library/closure/goog/async/run.js","../../node_modules/google-closure-library/closure/goog/string/string.js","../../node_modules/google-closure-library/closure/goog/net/xhrio.js","../../node_modules/google-closure-library/closure/goog/async/throwexception.js","../../node_modules/google-closure-library/closure/goog/timer/timer.js","../../node_modules/google-closure-library/closure/goog/async/throttle.js","src/com/google/javascript/jscomp/js/es6/util/inherits.js","../../node_modules/google-closure-library/closure/goog/events/eventhandler.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/webchanneldebug.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/requeststats.js","../../node_modules/google-closure-library/closure/goog/net/errorcode.js","../../node_modules/google-closure-library/closure/goog/net/eventtype.js","../../node_modules/google-closure-library/closure/goog/net/xmlhttpfactory.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel.js","../../node_modules/google-closure-library/closure/goog/net/xmlhttp.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/channelrequest.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/environment.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/webchannelbase.js","../../node_modules/google-closure-library/closure/goog/uri/uri.js","../../node_modules/google-closure-library/closure/goog/disposable/dispose.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/wirev8.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/forwardchannelrequestpool.js","../../node_modules/google-closure-library/closure/goog/structs/structs.js","../../node_modules/google-closure-library/closure/goog/uri/utils.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/wire.js","../../node_modules/google-closure-library/closure/goog/json/nativejsonprocessor.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/netutils.js","../../node_modules/google-closure-library/closure/goog/net/fetchxmlhttpfactory.js","../../node_modules/google-closure-library/closure/goog/functions/functions.js","../../node_modules/google-closure-library/closure/goog/json/hybrid.js","../../node_modules/google-closure-library/closure/goog/net/httpstatus.js","../../node_modules/google-closure-library/closure/goog/net/rpc/httpcors.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchanneltransport.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchannel/webchannelbasetransport.js","../../node_modules/google-closure-library/closure/goog/crypt/hash.js","../../node_modules/google-closure-library/closure/goog/crypt/md5.js","src/index.js","../../node_modules/google-closure-library/closure/goog/labs/net/webchanneltransportfactory.js"],"names":["$jscomp.arrayIteratorImpl","$jscomp.objectCreate","$jscomp.defineProperty","$jscomp.global","$jscomp.getGlobal","$jscomp.setPrototypeOf","$jscomp.polyfill","$jscomp.iteratorPrototype","$jscomp.makeIterator","$jscomp.iteratorFromArray","$jscomp.owns","goog","goog.global","self","goog.isArrayLike","val","s","Array","isArray","type","length","goog.isObject","goog.getUid","obj","Object","prototype","hasOwnProperty","call","goog.UID_PROPERTY_","goog.uidCounter_","Math","random","goog.bindNative_","fn","selfObj","var_args","apply","bind","arguments","goog.bindJs_","Error","boundArgs","slice","newArgs","unshift","goog.bind","Function","toString","indexOf","goog.bindapply","goog.partial","args","push","goog.inherits","childCtor","parentCtor","tempCtor","superClass_","constructor","base","childCtor.base","me","methodName","i","goog.Disposable","goog.Disposable.MONITORING_MODE","goog.Disposable.MonitoringMode.OFF","goog.Disposable.instances_","disposed_","onDisposeCallbacks_","OFF","dispose","goog.Disposable.prototype.dispose","disposeInternal","uid","goog.Disposable.prototype.disposeInternal","shift","arr","opt_fromIndex","fromIndex","toArray","object","rv","extend","arr1","arr2","len1","len2","j","goog.events.Event","opt_target","currentTarget","target","defaultPrevented","preventDefault","goog.events.Event.prototype.preventDefault","PASSIVE_EVENTS","goog.globaladdEventListener","addEventListener","defineProperty","passive","options","get","nullFunction","goog.globalremoveEventListener","removeEventListener","e","goog.string.internal.isEmptyOrWhitespace","str","test","getNativeUserAgentString","navigator","goog.globalnavigator","userAgent","matchUserAgent","goog.reflect.sinkValue","x","goog.reflect.cache","key","valueFn","cacheObj","goog.math.Integer.IntCache_","goog.userAgent.OPERA","goog.userAgent.IE","goog.userAgent.EDGE","goog.userAgent.EDGE_OR_IE","goog.userAgent.GECKO","toLowerCase","subString","goog.userAgent.WEBKIT","goog.userAgent.getDocumentMode_","doc","undefined","goog.userAgent.VERSION","version","goog.userAgent.getVersionRegexResult_","exec","docMode","parseFloat","String","documentMode","parseInt","ieVersion","goog.userAgent.DOCUMENT_MODE","goog.events.BrowserEvent","opt_e","opt_currentTarget","goog.events.Eventcall","goog.events.BrowserEvent.base","relatedTarget","button","screenY","screenX","clientY","clientX","metaKey","shiftKey","altKey","ctrlKey","state","pointerId","pointerType","event_","init","relevantTouch","changedTouches","srcElement","MOUSEOVER","fromElement","MOUSEOUT","toElement","pageX","pageY","goog.events.BrowserEvent.IE_POINTER_TYPE_MAP","goog.events.BrowserEventsuperClass_preventDefaultcall","arg","TOUCH","PEN","MOUSE","goog.events.BrowserEvent.prototype.preventDefault","be","returnValue","goog.events.Listenable.IMPLEMENTED_BY_PROP","goog.events.ListenableKey.counter_","goog.events.Listener","listener","src","capture","opt_handler","proxy","handler","removed","callOnce","goog.events.Listener.prototype.markAsRemoved","forEach","f","opt_obj","map","clone","res","PROTOTYPE_FIELDS","source","goog.events.ListenerMap","listeners","typeCount_","add","goog.events.ListenerMap.prototype.add","opt_useCapture","opt_listenerScope","typeStr","listenerArray","index","goog.events.ListenerMap.findListenerIndex_","listenerObj","goog.events.ListenerMap.prototype.removeByKey","splice","markAsRemoved","goog.events.LISTENER_MAP_PROP_","goog.events.onStringMap_","goog.events.listenerCountEstimate_","goog.events.listen","opt_options","once","goog.events.listenOnce","goog.events.wrapListener","listen","goog.events.listen_","listenerMap","goog.events.getListenerMap_","goog.events.getProxy","goog.events.BrowserFeature.PASSIVE_EVENTS","attachEvent","goog.events.getOnString_","addListener","removeListener","eventObject","proxyCallbackFunction","goog.events.handleBrowserEvent_","listenOnce","goog.events.unlisten","eventTargetListeners_","goog.events.unlistenByKey","removeByKey","detachEvent","goog.events.onString_","opt_evt","listenerFn","listenerHandler","goog.events.LISTENER_WRAPPER_PROP_","handleEvent","goog.events.EventTarget","goog.Disposablecall","actualEventTarget_","parentEventTarget_","goog.events.EventTarget.prototype.removeEventListener","opt_capture","opt_handlerScope","goog.events.EventTarget.prototype.dispatchEvent","ancestorsTree","ancestor","getParentEventTarget","oldEvent","opt_ancestorsTree","fireListeners","goog.events.EventTarget.prototype.disposeInternal","goog.events.EventTargetsuperClass_disposeInternalcall","removeAllListeners","count","goog.events.EventTarget.prototype.listen","goog.events.EventTarget.prototype.listenOnce","goog.events.EventTarget.prototype.fireListeners","concat","unlistenByKey","goog.json.serialize","FreeList","create","reset","create_","reset_","occupants_","head_","item","next","WorkQueue","workTail_","workHead_","scope","module$contents$goog$async$WorkQueue_WorkQueue.freelist_get","set","remove","workQueue","module$contents$goog$async$WorkQueue_WorkQueue.freelist_","WorkItem","goog.string.splitLimit","limit","parts","split","separator","returnVal","join","throwException","exception","goog.globalsetTimeout","setTimeout","schedule","workQueueScheduled","run","callback","context","initializeRunner","promise","goog.globalPromiseresolve","Promise","resolve","then","module$contents$goog$async$run_run.processWorkQueue","run.processWorkQueue","put","module$contents$goog$async$WorkQueue_WorkQueue.freelist_put","module$contents$goog$async$WorkQueue_WorkQueue.DEFAULT_MAX_UNUSED","goog.Timer","opt_interval","opt_timerObject","goog.events.EventTargetcall","interval_","timerObject_","boundTick_","tick_","last_","Date","now","goog.Timer.prototype","JSC$2231_enabled","JSC$2231_timer_","goog.Timer.prototype.tick_","enabled","elapsed","goog.Timer.intervalScale","timer_","clearTimeout","dispatchEvent","dispatchTick","goog.Timer.TICK","stop","start","goog.Timer.prototype.start","goog.Timer.prototype.stop","goog.Timer.prototype.disposeInternal","goog.TimersuperClass_disposeInternalcall","goog.Timer.callOnce","opt_delay","goog.Timer.MAX_TIMEOUT_","Number","goog.Timer.INVALID_TIMEOUT_ID_","Throttle","interval","listener_","args_","shouldFire_","fire","doAction_","super","goog.globalclearTimeout","onTimer_","goog.events.EventHandler","opt_scope","handler_","keys_","goog.events.EventHandler.typeArray_","goog.events.EventHandler.prototype.listen_","opt_fn","goog.events.EventHandler.prototype.removeAll","goog.events.EventHandler.prototype.disposeInternal","goog.events.EventHandlersuperClass_disposeInternalcall","removeAll","goog.events.EventHandler.prototype.handleEvent","goog.labs.net.webChannel.WebChannelDebug","redactEnabled_","disableRedact","WebChannelDebug.prototype.disableRedact","WebChannelDebug.prototype.xmlHttpChannelRequest","verb","uri","id","attempt","postData","info","out","params","keyValue","param","value","keyParts","WebChannelDebug.prototype.xmlHttpChannelResponseMetaData","readyState","statusCode","WebChannelDebug.prototype.xmlHttpChannelResponseText","responseText","opt_desc","redactResponse_","WebChannelDebug.prototype.timeoutResponse","WebChannelDebug.prototype.info","WebChannelDebug.prototype.redactResponse_","responseArray","JSON","parse","array","dataPart","goog.labs.net.webChannel.requestStats.Event","goog.labs.net.webChannel.requestStats.eventTarget_","requestStats.getStatEventTarget_","goog.labs.net.webChannel.requestStats.EventSERVER_REACHABILITY_EVENT","SERVER_REACHABILITY_EVENT","requestStats.ServerReachabilityEvent","goog.labs.net.webChannel.requestStats.ServerReachabilityEvent","requestStats.notifyServerReachabilityEvent","reachabilityType","goog.labs.net.webChannel.requestStats.getStatEventTarget_","goog.labs.net.webChannel.requestStats.EventSTAT_EVENT","STAT_EVENT","requestStats.StatEvent","eventTarget","stat","goog.labs.net.webChannel.requestStats.StatEvent","requestStats.notifyStatEvent","goog.labs.net.webChannel.requestStats.EventTIMING_EVENT","TIMING_EVENT","requestStats.TimingEvent","size","goog.labs.net.webChannel.requestStats.TimingEvent","requestStats.setTimeout","ms","goog.net.ErrorCode","NO_ERROR","ACCESS_DENIED","FILE_NOT_FOUND","FF_SILENT_ERROR","CUSTOM_ERROR","EXCEPTION","HTTP_ERROR","ABORT","TIMEOUT","OFFLINE","goog.net.EventType","COMPLETE","SUCCESS","ERROR","READY","READY_STATE_CHANGE","INCREMENTAL_DATA","PROGRESS","DOWNLOAD_PROGRESS","UPLOAD_PROGRESS","goog.net.XmlHttpFactory","cachedOptions_","goog.net.XmlHttpFactory.prototype.getOptions","internalGetOptions","goog.net.WebChannel","goog.net.WebChannel.EventType","OPEN","CLOSE","MESSAGE","goog.net.WebChannel.MessageEvent","goog.net.WebChannel.MessageEvent.base","goog.net.WebChannel.ErrorEvent","goog.net.WebChannel.ErrorEvent.base","goog.net.DefaultXmlHttpFactory","createInstance","goog.net.DefaultXmlHttpFactory.prototype.createInstance","XMLHttpRequest","goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions","goog.net.XmlHttp.factory_","factory","goog.labs.net.webChannel.ChannelRequest","channel","channelDebug","opt_requestId","opt_retryId","channel_","channelDebug_","rid_","retryId_","eventHandler_","timeout_","goog.labs.net.webChannel.ChannelRequest.TIMEOUT_MS_","EDGE_POLLING_INTERVAL_","pollingTimer_","extraHeaders_","successful_","postData_","requestUri_","baseUri_","type_","requestStartTime_","watchDogTimeoutTime_","watchDogTimerId_","pendingMessages_","xmlHttp_","xmlHttpChunkStart_","lastError_","verb_","lastStatusCode_","cancelled_","readyStateChangeThrottleMs_","readyStateChangeThrottle_","firstByteReceived_","initialResponseDecoded_","decodeInitialResponse_","decodeChunks_","fetchResponseState_","goog.labs.net.webChannel.FetchResponseState","textDecoder","responseBuffer","responseArrivedForFetch","goog.labs.net.webChannel.ChannelRequest.INVALID_CHUNK_","goog.labs.net.webChannel.ChannelRequest.INCOMPLETE_CHUNK_","goog.labs.net.webChannel.ChannelRequest.prototype","ChannelRequest.prototype.setTimeout","timeout","ChannelRequest.prototype.xmlHttpPost","XML_HTTP","makeUnique","decodeChunks","sendXmlHttp_","ChannelRequest.prototype.sendXmlHttp_","hostPrefix","ensureWatchDogTimer_","values","setValues","queryData_","useSecondaryDomains","supportsCrossDomainXhrs_","createXhrIo","xmlHttpHandler_","listen_","readyStateChangeHandler_","headers","send","goog.labs.net.webChannel.requestStats.notifyServerReachabilityEvent","REQUEST_MADE","xmlHttpChannelRequest","ChannelRequest.prototype.readyStateChangeHandler_","evt","xhr","throttle","INTERACTIVE","getReadyState","ChannelRequest.prototype.xmlHttpHandler_","xmlhttp","onXmlHttpReadyStateChanged_","errorCode","getLastErrorCode","getStatus","getResponseText","getResponse","REQUEST_FAILED","REQUEST_SUCCEEDED","cancelWatchDogTimer_","status","useFetchStreamsForResponse_","responseChunks","responseLength","requestCompleted","TextDecoder","cleanup_","dispatchFailure_","goog.globalTextDecoder","decode","stream","xmlHttpChannelResponseMetaData","xhr_","getResponseHeader","goog.net.WebChannel.X_HTTP_INITIAL_RESPONSE","initialResponse","xmlHttpChannelResponseText","safeOnRequestData_","UNKNOWN_SESSION_ID","goog.labs.net.webChannel.requestStats.notifyStatEvent","REQUEST_UNKNOWN_SESSION_ID","decodeNextChunks_","pollResponse_","onRequestComplete","getResponseHeaders","STATUS","REQUEST_BAD_STATUS","ex","ChannelRequest.prototype.useFetchStreamsForResponse_","CLOSE_REQUEST","usesFetchStreams_","ChannelRequest.prototype.decodeNextChunks_","decodeNextChunksSuccessful","chunkText","getNextChunk_","BAD_DATA","REQUEST_INCOMPLETE_DATA","REQUEST_BAD_DATA","NO_DATA","REQUEST_NO_DATA","backChannelRequest_","request","detectBufferingProxy_","bpDetectionDone_","clearBpDetectionTimer_","NOPROXY","ChannelRequest.prototype.pollResponse_","ChannelRequest.prototype.getNextChunk_","sizeStartIndex","sizeEndIndex","substring","sizeAsString","isNaN","chunkStartIndex","cancel","ChannelRequest.prototype.cancel","ChannelRequest.prototype.ensureWatchDogTimer_","startWatchDogTimer_","ChannelRequest.prototype.startWatchDogTimer_","time","goog.labs.net.webChannel.requestStats.setTimeout","onWatchDogTimeout_","ChannelRequest.prototype.cancelWatchDogTimer_","ChannelRequest.prototype.onWatchDogTimeout_","timeoutResponse","handleTimeout_","REQUEST_TIMEOUT","ChannelRequest.prototype.dispatchFailure_","CLOSED","state_","ChannelRequest.prototype.cleanup_","abort","ChannelRequest.prototype.safeOnRequestData_","data","hasRequest","forwardChannelRequestPool_","OPENED","response","wireCodec_","parser_","responseValues","backChannelTimerId_","handlePostResponse_","goog.labs.net.webChannel.WebChannelBase.RTT_ESTIMATE","clearDeadBackchannelTimer_","cancelBackChannelRequest_","maybeRetryBackChannel_","BACKCHANNEL_MISSING","lastPostResponseArrayId_","lastArrayId_","goog.labs.net.webChannel.WebChannelBase.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF","numOutstandingBackchannelBytes","enableStreaming_","backChannelRetryCount_","deadBackChannelTimerId_","onBackChannelDead_","getRequestCount","onForwardChannelFlushed_","forwardChannelFlushedCallback_","signalError_","BAD_RESPONSE","nextArray","onInput_","OPENING","sid_","hostPrefix_","serverHostPrefix","negotiatedVersion","channelVersion_","negotiatedServerVersion","serverVersion_","serverKeepaliveMs","backChannelRequestTimeoutMs_","applyControlHeaders_","clientProtocol","goog.net.WebChannel.X_CLIENT_WIRE_PROTOCOL","requestPool_","maxSize_","maxPoolSizeConfigured_","Set","request_","addRequest","getHttpSessionIdParam","httpSessionIdParam_","httpSessionIdHeader","goog.net.WebChannel.X_HTTP_SESSION_ID","setHttpSessionId","httpSessionId_","setParameterValue","forwardChannelUri_","channelOpened","handshakeRttMs_","startBackchannelAfterHandshake_","backChannelUri_","createDataUri","getBackChannelUri","path_","removeRequest","opt_timeout","ensureBackChannel_","outgoingMaps_","ensureForwardChannel_","STOP","disconnect","channelHandleArray","BACK_CHANNEL_ACTIVITY","goog.structs.getValues","col","getValues","Map","from","l","goog.structs.getKeys","getKeys","keys","goog.structs.forEach","goog.uri.utils.splitRe_","RegExp","goog.uri.utils.parseQueryData","encodedQuery","pairs","indexOfEquals","name","decodeURIComponent","replace","goog.Uri","opt_uri","domain_","userInfo_","scheme_","port_","fragment_","ignoreCase_","m","setScheme","setUserInfo","setDomain","setPort","setPath","setQueryData","setFragment","match","result","SCHEME","goog.Uri.decodeOrEmpty_","USER_INFO","DOMAIN","PORT","PATH","QUERY_DATA","FRAGMENT","goog.Uri.QueryData","goog.Uri.prototype.toString","scheme","getScheme","goog.Uri.encodeSpecialChars_","goog.Uri.reDisallowedInSchemeOrUserInfo_","domain","getDomain","userInfo","getUserInfo","encodeURIComponent","doubleEncodedString","port","getPort","path","getPath","hasDomain","charAt","goog.Uri.reDisallowedInAbsolutePath_","goog.Uri.reDisallowedInRelativePath_","query","getEncodedQuery","fragment","getFragment","goog.Uri.reDisallowedInFragment_","goog.Uri.prototype.resolve","relativeUri","absoluteUri","overridden","hasPath","lastSlashIndex","lastIndexOf","leadingSlash","prefix","segments","pos","segment","pop","goog.Uri.prototype.clone","goog.Uri.prototype.setScheme","newScheme","opt_decode","goog.Uri.prototype.setPort","newPort","goog.Uri.prototype.setQueryData","queryData","setIgnoreCase","goog.Uri.reDisallowedInQuery_","goog.Uri.prototype.setParameterValue","goog.Uri.prototype.makeUnique","RANDOM","floor","abs","opt_preserveReserved","decodeURI","unescapedPart","extra","opt_removeDoubleEncoding","encoded","encodeURI","goog.Uri.encodeChar_","ch","n","charCodeAt","opt_query","opt_ignoreCase","count_","keyMap_","encodedQuery_","goog.Uri.QueryData.prototype.ensureKeyMapInitialized_","goog.Uri.QueryData.prototype","goog.Uri.QueryData.prototype.add","ensureKeyMapInitialized_","invalidateCache_","getKeyName_","goog.Uri.QueryData.prototype.remove","has","delete","goog.Uri.QueryData.prototype.containsKey","goog.Uri.QueryData.prototype.forEach","goog.Uri.QueryData.prototype.getKeys","vals","goog.Uri.QueryData.prototype.getValues","opt_key","containsKey","goog.Uri.QueryData.prototype.set","goog.Uri.QueryData.prototype.get","opt_default","goog.Uri.QueryData.prototype.setValues","goog.Uri.QueryData.prototype.toString","sb","encodedKey","goog.Uri.QueryData.prototype.clone","goog.Uri.QueryData.prototype.getKeyName_","keyName","goog.Uri.QueryData.prototype.setIgnoreCase","ignoreCase","lowerCase","mapId","ForwardChannelRequestPool","opt_maxPoolSize","module$contents$goog$labs$net$webChannel$ForwardChannelRequestPool_ForwardChannelRequestPool.MAX_POOL_SIZE_","goog.globalPerformanceNavigationTiming","PerformanceNavigationTiming","entrys","goog.globalperformancegetEntriesByType","performance","getEntriesByType","nextHopProtocol","goog.globalchrome","chrome","goog.globalchromeloadTimes","loadTimes","wasFetchedViaSpdy","ForwardChannelRequestPool.prototype.isFull","ForwardChannelRequestPool.prototype.getRequestCount","ForwardChannelRequestPool.prototype.hasRequest","req","ForwardChannelRequestPool.prototype.addRequest","ForwardChannelRequestPool.prototype.removeRequest","ForwardChannelRequestPool.prototype.cancel","getPendingMessages","clear","ForwardChannelRequestPool.prototype.getPendingMessages","goog.json.NativeJsonProcessor","stringify","opt_replacer","opt_reviver","goog.labs.net.webChannel.WireV8","WireV8.prototype.encodeMessage","message","buffer","opt_prefix","encodedValue","netUtils.testLoadImage","url","goog.globalImage","Image","img","onload","goog.labs.net.webChannel.netUtils.imageCallback_","onerror","onabort","ontimeout","goog.labs.net.webChannel.netUtils.NETWORK_TIMEOUT","netUtils.imageCallback_","debugText","goog.net.FetchXmlHttpFactory","opts","worker_","worker","streamBinaryChunks_","streamBinaryChunks","goog.net.FetchXmlHttpFactory.prototype.createInstance","instance","goog.net.FetchXmlHttp","goog.functions.constant","retValue","goog.net.FetchXmlHttp.base","credentialsMode_","goog.net.FetchXmlHttp.RequestState.UNSENT","responseType","statusText","onreadystatechange","requestHeaders_","Headers","responseHeaders_","method_","url_","inProgress_","textDecoder_","currentReader_","fetchResponse_","UNSENT","goog.net.FetchXmlHttp.prototype","open","goog.net.FetchXmlHttp.prototype.open","method","dispatchCallback_","goog.net.FetchXmlHttp.prototype.send","opt_data","requestInit","credentials","cache","fetch","Request","handleResponse_","handleSendFailure_","goog.net.FetchXmlHttp.prototype.abort","catch","DONE","requestDone_","goog.net.FetchXmlHttp.prototype.handleResponse_","HEADER_RECEIVED","LOADING","arrayBuffer","handleResponseArrayBuffer_","goog.globalReadableStream","ReadableStream","body","getReader","readInputFromFetch_","text","handleResponseText_","goog.net.FetchXmlHttp.prototype.readInputFromFetch_","read","handleDataFromStream_","goog.net.FetchXmlHttp.prototype.handleDataFromStream_","dataPacket","Uint8Array","newText","done","goog.net.FetchXmlHttp.prototype.handleResponseText_","goog.net.FetchXmlHttp.prototype.handleResponseArrayBuffer_","responseArrayBuffer","goog.net.FetchXmlHttp.prototype.handleSendFailure_","goog.net.FetchXmlHttp.prototype.requestDone_","setRequestHeader","goog.net.FetchXmlHttp.prototype.setRequestHeader","header","append","goog.net.FetchXmlHttp.prototype.getResponseHeader","getAllResponseHeaders","goog.net.FetchXmlHttp.prototype.getAllResponseHeaders","lines","iter","entries","entry","pair","goog.net.FetchXmlHttp.prototype.dispatchCallback_","getCredentialsMode","setCredentialsMode","credentialsMode","goog.json.hybrid.parse","goog.net.XhrIo","opt_xmlHttpFactory","goog.net.XhrIo.base","xmlHttpFactory_","active_","xhrOptions_","lastUri_","lastErrorCode_","inAbort_","inOpen_","inSend_","errorDispatched_","timeoutInterval_","timeoutId_","responseType_","goog.net.XhrIo.ResponseType.DEFAULT","useXhr2Timeout_","withCredentials_","DEFAULT","goog.net.XhrIo.HTTP_SCHEME_PATTERN","goog.net.XhrIo.METHODS_WITH_FORM_DATA","goog.net.XhrIo.prototype","setWithCredentials","goog.net.XhrIo.prototype.setWithCredentials","withCredentials","JSC$2324_send","goog.net.XhrIo.prototype.send","opt_method","opt_content","opt_headers","toUpperCase","createXhr","goog.net.XmlHttp.factory_createInstance","getOptions","goog.net.XmlHttp.factory_getOptions","onReadyStateChange_","err","error_","content","getPrototypeOf","contentTypeKey","find","contentIsFormData","goog.net.XhrIo.CONTENT_TYPE_HEADER","goog.net.XhrIo.FORM_CONTENT_TYPE","cleanUpTimeoutTimer_","goog.net.XhrIo.shouldUseXhr2Timeout_","JSC$2324_timeout_","goog.net.XhrIo.prototype.timeout_","goog.net.XhrIo.prototype.error_","dispatchErrors_","cleanUpXhr_","goog.net.XhrIo.prototype.dispatchErrors_","goog.net.XhrIo.prototype.abort","opt_failureCode","goog.net.XhrIo.prototype.disposeInternal","goog.net.XhrIosuperClass_disposeInternalcall","goog.net.XhrIo.prototype.disposeInternal.base","goog.net.XhrIo.prototype.onReadyStateChange_","isDisposed","onReadyStateChangeHelper_","onReadyStateChangeEntryPoint_","goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_","goog.net.XhrIo.prototype.onReadyStateChangeHelper_","LOCAL_REQUEST_ERROR","isComplete","isSuccess","OK","CREATED","ACCEPTED","NO_CONTENT","PARTIAL_CONTENT","NOT_MODIFIED","QUIRK_IE_NO_CONTENT","goog.globalself","goog.globalselflocation","location","goog.globalselflocationprotocol","protocol","goog.net.XhrIo.HTTP_SCHEME_PATTERNtest","LOADED","getStatusText","goog.net.XhrIo.prototype.cleanUpXhr_","opt_fromDispose","clearedOnReadyStateChange","USE_NULL_FUNCTION","goog.net.XhrIo.prototype.cleanUpTimeoutTimer_","isActive","goog.net.XhrIo.prototype.isActive","goog.net.XhrIo.prototype.getReadyState","UNINITIALIZED","goog.net.XhrIo.prototype.getStatus","goog.net.XhrIo.prototype.getResponseText","getResponseJson","goog.net.XhrIo.prototype.getResponseJson","opt_xssiPrefix","goog.net.XhrIo.prototype.getResponse","TEXT","ARRAY_BUFFER","mozResponseArrayBuffer","goog.net.XhrIo.prototype.getResponseHeaders","headersObject","headersArray","trim","goog.net.XhrIo.prototype.getLastErrorCode","JSC$2324_getLastError","goog.net.XhrIo.prototype.getLastError","exports.generateHttpHeadersOverwriteParam","exports.setHttpHeadersWithOverwriteParam","urlParam","extraHeaders","httpHeaders","module$exports$goog$net$rpc$HttpCors.generateHttpHeadersOverwriteParam","getInternalChannelParam","paramName","defaultValue","internalChannelParams","goog.labs.net.webChannel.WebChannelBase","extraParams_","httpHeadersOverwriteParam_","initHeaders_","nextMapId_","nextRid_","failFast_","forwardChannelTimerId_","allowStreamingMode_","backChannelAttemptId_","forwardChannelRetryCount_","baseRetryDelayMs_","retryDelaySeedMs_","forwardChannelMaxRetries_","forwardChannelRequestTimeoutMs_","xmlHttpFactory","useFetchStreams","supportsCrossDomainXhr","concurrentRequestLimit","fastHandshake_","fastHandshake","encodeInitMessageHeaders_","encodeInitMessageHeaders","blockingHandshake_","blockingHandshake","forceLongPolling","detectBufferingProxy","longPollingTimeout_","longPollingTimeout","nonAckedMapsAtChannelClose_","bpDetectionTimerId_","goog.labs.net.webChannel.WebChannelBase.prototype","goog.labs.net.webChannel.Wire.LATEST_CHANNEL_VERSION","JSC$2331_state_","INIT","WebChannelBase.prototype.disconnect","cancelRequests_","rid","addAdditionalParams_","requestSent","goog.globalnavigatorsendBeacon","sendBeacon","eltImg","onClose_","WebChannelBase.prototype.cancelBackChannelRequest_","WebChannelBase.prototype.cancelRequests_","clearForwardChannelTimer_","WebChannelBase.prototype.ensureForwardChannel_","isFull","onStartForwardChannelTimer_","WebChannelBase.prototype.maybeRetryForwardChannel_","getForwardChannelMaxRetries","getRetryTime_","WebChannelBase.prototype.onStartForwardChannelTimer_","opt_retryRequest","startForwardChannel_","total","goog.labs.net.webChannel.Wire.RAW_DATA_KEY","goog.labs.net.webChannel.WebChannelBase.MAX_CHARS_PER_GET_","goog.labs.net.webChannel.WebChannelBase.MAX_MAPS_PER_REQUEST_","requestText","dequeueOutgoingMaps_","goog.net.WebChannelTransport.CLIENT_VERSION","encodedHeaders","module$exports$goog$net$rpc$HttpCors.setHttpHeadersWithOverwriteParam","xmlHttpPost","makeForwardChannelRequest_","WebChannelBase.prototype.makeForwardChannelRequest_","requeuePendingMaps_","round","WebChannelBase.prototype.addAdditionalParams_","WebChannelBase.prototype.dequeueOutgoingMaps_","maxNum","min","badMapHandler","badMapError","offset","messageQueue","max","encodeMessage","pendingMessages","WebChannelBase.prototype.ensureBackChannel_","onStartBackChannelTimer_","WebChannelBase.prototype.maybeRetryBackChannel_","goog.labs.net.webChannel.WebChannelBase.BACK_CHANNEL_MAX_RETRIES","WebChannelBase.prototype.onStartBackChannelTimer_","startBackChannel_","bpDetectionTimeout","onBpDetectionTimer_","WebChannelBase.prototype.onBpDetectionTimer_","PROXY","WebChannelBase.prototype.clearBpDetectionTimer_","WebChannelBase.prototype.startBackChannel_","WebChannelBase.prototype.onBackChannelDead_","BACKCHANNEL_DEAD","WebChannelBase.prototype.clearDeadBackchannelTimer_","WebChannelBase.prototype.onRequestComplete","BACK_CHANNEL","FORWARD_CHANNEL","rtt","retries","lastError","maybeRetryForwardChannel_","WebChannelBase.prototype.getRetryTime_","retryCount","retryTime","goog.labs.net.webChannel.WebChannelBase.INACTIVE_CHANNEL_RETRY_FACTOR","WebChannelBase.prototype.signalError_","error","imageUri","testNetworkCallback_","goog.globallocation","goog.globallocationprotocol","goog.labs.net.webChannel.netUtils.testLoadImage","ERROR_OTHER","onError_","channelError","WebChannelBase.prototype.testNetworkCallback_","networkUp","ERROR_NETWORK","WebChannelBase.prototype.onClose_","channelClosed","WebChannelBase.prototype.createDataUri","locationPage","hostName","hostname","opt_scheme","opt_domain","opt_port","getHttpSessionId","WebChannelBase.prototype.createXhrIo","isStreaming","WebChannelBase.prototype.isActive","WebChannelBase.Handler","goog.labs.net.webChannel.WebChannelBase.Handler.prototype","WebChannelBase.Handler.prototype.channelOpened","WebChannelBase.Handler.prototype.channelHandleArray","WebChannelBase.Handler.prototype.channelError","WebChannelBase.Handler.prototype.channelClosed","WebChannelBase.Handler.prototype.isActive","WebChannelBase.Handler.prototype.badMapError","goog.labs.net.webChannel.WebChannelBaseTransport","createWebChannel","WebChannelBaseTransport.prototype.createWebChannel","goog.labs.net.webChannel.WebChannelBaseTransport.Channel","WebChannelBaseTransport.Channel","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.base","messageUrlParams_","messageUrlParams","messageHeaders","clientProtocolHeaderRequired","goog.net.WebChannel.X_CLIENT_PROTOCOL","goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL","initHeaders","initMessageHeaders","messageContentType","goog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE","clientProfile","goog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE","httpHeadersOverwriteParam","supportsCrossDomainXhr_","sendRawJson_","sendRawJson","httpSessionIdParam","channelHandler_","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.Handler_","WebChannelBaseTransport.Channel.prototype.open","supportCrossDomain","CONNECT_ATTEMPT","channelPath","opt_extraParams","connectChannel_","close","WebChannelBaseTransport.Channel.prototype.close","WebChannelBaseTransport.Channel.prototype.send","rawJson","messageToMapObject_","goog.labs.net.webChannel.Wire.QueuedMap","WebChannelBaseTransport.Channel.prototype.disposeInternal","goog.labs.net.webChannel.WebChannelBaseTransport.ChannelsuperClass_disposeInternalcall","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.disposeInternal.base","WebChannelBaseTransport.Channel.MessageEvent","goog.net.WebChannel.MessageEventcall","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.MessageEvent.base","metadata","metadataKey","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.MessageEvent","WebChannelBaseTransport.Channel.ErrorEvent","goog.net.WebChannel.ErrorEventcall","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.ErrorEvent.base","NETWORK_ERROR","goog.labs.net.webChannel.WebChannelBaseTransport.Channel.ErrorEvent","WebChannelBaseTransport.Channel.Handler_","goog.labs.net.webChannel.WebChannelBase.Handler","WebChannelBaseTransport.Channel.Handler_.prototype.channelOpened","WebChannelBaseTransport.Channel.Handler_.prototype.channelHandleArray","WebChannelBaseTransport.Channel.Handler_.prototype.channelError","WebChannelBaseTransport.Channel.Handler_.prototype.channelClosed","goog.crypt.Hash","blockSize","goog.crypt.Md5","chain_","block_","totalLength_","blockLength_","goog.crypt.Md5.prototype.reset","goog.crypt.Md5.prototype.compress_","buf","opt_offset","X","A","B","C","D","sum","update","goog.crypt.Md5.prototype.update","bytes","opt_length","lengthMinusBlock","block","blockLength","compress_","digest","goog.crypt.Md5.prototype.digest","pad","totalBits","goog.math.Integer","bits","sign","sign_","localBits","top","bits_","goog.math.Integer.fromInt","goog.math.Integer.fromNumber","isFinite","goog.math.Integer.ZERO","negate","pow","goog.math.Integer.TWO_PWR_32_DBL_","goog.math.Integer.fromString","opt_radix","radix","radixToPower","power","multiply","goog.math.Integer.ONE","goog.math.Integer.TWO_PWR_24_","goog.math.Integer.prototype","toNumber","goog.math.Integer.prototype.toNumber","isNegative","getBitsUnsigned","getBits","goog.math.Integer.prototype.toString","isZero","rem","remDiv","divideAndRemainder","quotient","toInt","subtract","digits","goog.math.Integer.prototype.getBits","goog.math.Integer.prototype.isZero","goog.math.Integer.prototype.isNegative","JSC$2356_compare","goog.math.Integer.prototype.compare","other","diff","goog.math.Integer.prototype.negate","len","not","goog.math.Integer.prototype.abs","goog.math.Integer.prototype.add","carry","c0","c1","high","goog.math.Integer.prototype.subtract","JSC$2356_multiply","goog.math.Integer.prototype.multiply","lessThan","compare","a1","a0","b1","b0","goog.math.Integer.carry16_","goog.math.Integer.DivisionResult","remainder","goog.math.Integer.prototype.divideAndRemainder","slowDivide_","twoPower","multiple","shiftLeft","shiftRight","total2","approx","log2","ceil","log","LN2","delta","approxRes","approxRem","modulo","goog.math.Integer.prototype.modulo","and","goog.math.Integer.prototype.and","or","goog.math.Integer.prototype.or","xor","goog.math.Integer.prototype.xor","goog.math.Integer.prototype.shiftLeft","bit_delta","goog.math.Integer.prototype.shiftRight","numBits","arr_delta","getLastError","module","goog.net.createWebChannelTransport","requestStats.getStatEventTarget","goog.labs.net.webChannel.requestStats.Stat","TEST_STAGE_ONE_START","TEST_STAGE_TWO_START","TEST_STAGE_TWO_DATA_ONE","TEST_STAGE_TWO_DATA_TWO","TEST_STAGE_TWO_DATA_BOTH","TEST_STAGE_ONE_FAILED","TEST_STAGE_TWO_FAILED","BROWSER_OFFLINE"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Bootstrap for the Google JS Library (Closure).\n *\n * In uncompiled mode base.js will attempt to load Closure's deps file, unless\n * the global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects\n * to include their own deps file(s) from different locations.\n *\n * Avoid including base.js more than once. This is strictly discouraged and not\n * supported. goog.require(...) won't work properly in that case.\n *\n * @suppress {deprecated} Users cannot remove deprecated uses here.\n * @provideGoog\n */\n\n\n/**\n * @define {boolean} Overridden to true by the compiler.\n */\nvar COMPILED = false;\n\n\n/**\n * Base namespace for the Closure library. Checks to see goog is already\n * defined in the current scope before assigning to prevent clobbering if\n * base.js is loaded more than once.\n *\n * @const\n */\nvar goog = goog || {};\n\n/**\n * Reference to the global object.\n * https://www.ecma-international.org/ecma-262/9.0/index.html#sec-global-object\n *\n * More info on this implementation here:\n * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit\n *\n * @const\n * @suppress {undefinedVars} self won't be referenced unless `this` is falsy.\n * @type {!Global}\n */\ngoog.global =\n // Check `this` first for backwards compatibility.\n // Valid unless running as an ES module or in a function wrapper called\n // without setting `this` properly.\n // Note that base.js can't usefully be imported as an ES module, but it may\n // be compiled into bundles that are loadable as ES modules.\n this ||\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/self\n // For in-page browser environments and workers.\n self;\n\n\n/**\n * A hook for overriding the define values in uncompiled mode.\n *\n * In uncompiled mode, `CLOSURE_UNCOMPILED_DEFINES` may be defined before\n * loading base.js. If a key is defined in `CLOSURE_UNCOMPILED_DEFINES`,\n * `goog.define` will use the value instead of the default value. This\n * allows flags to be overwritten without compilation (this is normally\n * accomplished with the compiler's \"define\" flag).\n *\n * Example:\n * <pre>\n * var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};\n * </pre>\n *\n * @type {Object<string, (string|number|boolean)>|undefined}\n */\ngoog.global.CLOSURE_UNCOMPILED_DEFINES;\n\n\n/**\n * A hook for overriding the define values in uncompiled or compiled mode,\n * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code. In\n * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.\n *\n * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or\n * string literals or the compiler will emit an error.\n *\n * While any @define value may be set, only those set with goog.define will be\n * effective for uncompiled code.\n *\n * Example:\n * <pre>\n * var CLOSURE_DEFINES = {'goog.DEBUG': false} ;\n * </pre>\n *\n * Currently the Closure Compiler will only recognize very simple definitions of\n * this value when looking for values to apply to compiled code and ignore all\n * other references. Specifically, it looks the value defined at the variable\n * declaration, as with the example above.\n *\n * TODO(user): Improve the recognized definitions.\n *\n * @type {!Object<string, (string|number|boolean)>|null|undefined}\n */\ngoog.global.CLOSURE_DEFINES;\n\n\n/**\n * Builds an object structure for the provided namespace path, ensuring that\n * names that already exist are not overwritten. For example:\n * \"a.b.c\" -> a = {};a.b={};a.b.c={};\n * Used by goog.provide and goog.exportSymbol.\n * @param {string} name The name of the object that this file defines.\n * @param {*=} object The object to expose at the end of the path.\n * @param {boolean=} overwriteImplicit If object is set and a previous call\n * implicitly constructed the namespace given by name, this parameter\n * controls whether object should overwrite the implicitly constructed\n * namespace or be merged into it. Defaults to false.\n * @param {?Object=} objectToExportTo The object to add the path to; if this\n * field is not specified, its value defaults to `goog.global`.\n * @private\n */\ngoog.exportPath_ = function(name, object, overwriteImplicit, objectToExportTo) {\n var parts = name.split('.');\n var cur = objectToExportTo || goog.global;\n\n // Internet Explorer exhibits strange behavior when throwing errors from\n // methods externed in this manner. See the testExportSymbolExceptions in\n // base_test.html for an example.\n if (!(parts[0] in cur) && typeof cur.execScript != 'undefined') {\n cur.execScript('var ' + parts[0]);\n }\n\n for (var part; parts.length && (part = parts.shift());) {\n if (!parts.length && object !== undefined) {\n if (!overwriteImplicit && goog.isObject(object) &&\n goog.isObject(cur[part])) {\n // Merge properties on object (the input parameter) with the existing\n // implicitly defined namespace, so as to not clobber previously\n // defined child namespaces.\n for (var prop in object) {\n if (object.hasOwnProperty(prop)) {\n cur[part][prop] = object[prop];\n }\n }\n } else {\n // Either there is no existing implicit namespace, or overwriteImplicit\n // is set to true, so directly assign object (the input parameter) to\n // the namespace.\n cur[part] = object;\n }\n } else if (cur[part] && cur[part] !== Object.prototype[part]) {\n cur = cur[part];\n } else {\n cur = cur[part] = {};\n }\n }\n};\n\n\n/**\n * Defines a named value. In uncompiled mode, the value is retrieved from\n * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and\n * has the property specified, and otherwise used the defined defaultValue.\n * When compiled the default can be overridden using the compiler options or the\n * value set in the CLOSURE_DEFINES object. Returns the defined value so that it\n * can be used safely in modules. Note that the value type MUST be either\n * boolean, number, or string.\n *\n * @param {string} name The distinguished name to provide.\n * @param {T} defaultValue\n * @return {T} The defined value.\n * @template T\n */\ngoog.define = function(name, defaultValue) {\n var value = defaultValue;\n if (!COMPILED) {\n var uncompiledDefines = goog.global.CLOSURE_UNCOMPILED_DEFINES;\n var defines = goog.global.CLOSURE_DEFINES;\n if (uncompiledDefines &&\n // Anti DOM-clobbering runtime check (b/37736576).\n /** @type {?} */ (uncompiledDefines).nodeType === undefined &&\n Object.prototype.hasOwnProperty.call(uncompiledDefines, name)) {\n value = uncompiledDefines[name];\n } else if (\n defines &&\n // Anti DOM-clobbering runtime check (b/37736576).\n /** @type {?} */ (defines).nodeType === undefined &&\n Object.prototype.hasOwnProperty.call(defines, name)) {\n value = defines[name];\n }\n }\n return value;\n};\n\n\n/**\n * @define {number} Integer year indicating the set of browser features that are\n * guaranteed to be present. This is defined to include exactly features that\n * work correctly on all \"modern\" browsers that are stable on January 1 of the\n * specified year. For example,\n * ```js\n * if (goog.FEATURESET_YEAR >= 2019) {\n * // use APIs known to be available on all major stable browsers Jan 1, 2019\n * } else {\n * // polyfill for older browsers\n * }\n * ```\n * This is intended to be the primary define for removing\n * unnecessary browser compatibility code (such as ponyfills and workarounds),\n * and should inform the default value for most other defines:\n * ```js\n * const ASSUME_NATIVE_PROMISE =\n * goog.define('ASSUME_NATIVE_PROMISE', goog.FEATURESET_YEAR >= 2016);\n * ```\n *\n * The default assumption is that IE9 is the lowest supported browser, which was\n * first available Jan 1, 2012.\n *\n * TODO(user): Reference more thorough documentation when it's available.\n */\ngoog.FEATURESET_YEAR = goog.define('goog.FEATURESET_YEAR', 2012);\n\n\n/**\n * @define {boolean} DEBUG is provided as a convenience so that debugging code\n * that should not be included in a production. It can be easily stripped\n * by specifying --define goog.DEBUG=false to the Closure Compiler aka\n * JSCompiler. For example, most toString() methods should be declared inside an\n * \"if (goog.DEBUG)\" conditional because they are generally used for debugging\n * purposes and it is difficult for the JSCompiler to statically determine\n * whether they are used.\n */\ngoog.DEBUG = goog.define('goog.DEBUG', true);\n\n\n/**\n * @define {string} LOCALE defines the locale being used for compilation. It is\n * used to select locale specific data to be compiled in js binary. BUILD rule\n * can specify this value by \"--define goog.LOCALE=<locale_name>\" as a compiler\n * option.\n *\n * Take into account that the locale code format is important. You should use\n * the canonical Unicode format with hyphen as a delimiter. Language must be\n * lowercase, Language Script - Capitalized, Region - UPPERCASE.\n * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.\n *\n * See more info about locale codes here:\n * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers\n *\n * For language codes you should use values defined by ISO 693-1. See it here\n * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from\n * this rule: the Hebrew language. For legacy reasons the old code (iw) should\n * be used instead of the new code (he).\n *\n */\ngoog.LOCALE = goog.define('goog.LOCALE', 'en'); // default to en\n\n\n/**\n * @define {boolean} Whether this code is running on trusted sites.\n *\n * On untrusted sites, several native functions can be defined or overridden by\n * external libraries like Prototype, Datejs, and JQuery and setting this flag\n * to false forces closure to use its own implementations when possible.\n *\n * If your JavaScript can be loaded by a third party site and you are wary about\n * relying on non-standard implementations, specify\n * \"--define goog.TRUSTED_SITE=false\" to the compiler.\n */\ngoog.TRUSTED_SITE = goog.define('goog.TRUSTED_SITE', true);\n\n\n/**\n * @define {boolean} Whether code that calls {@link goog.setTestOnly} should\n * be disallowed in the compilation unit.\n */\ngoog.DISALLOW_TEST_ONLY_CODE =\n goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);\n\n\n/**\n * @define {boolean} Whether to use a Chrome app CSP-compliant method for\n * loading scripts via goog.require. @see appendScriptSrcNode_.\n */\ngoog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING =\n goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false);\n\n\n/**\n * Defines a namespace in Closure.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * The presence of one or more goog.provide() calls in a file indicates\n * that the file defines the given objects/namespaces.\n * Provided symbols must not be null or undefined.\n *\n * In addition, goog.provide() creates the object stubs for a namespace\n * (for example, goog.provide(\"goog.foo.bar\") will create the object\n * goog.foo.bar if it does not already exist).\n *\n * Build tools also scan for provide/require/module statements\n * to discern dependencies, build dependency files (see deps.js), etc.\n *\n * @see goog.require\n * @see goog.module\n * @param {string} name Namespace provided by this file in the form\n * \"goog.package.part\".\n * deprecated Use goog.module (see b/159289405)\n */\ngoog.provide = function(name) {\n if (goog.isInModuleLoader_()) {\n throw new Error('goog.provide cannot be used within a module.');\n }\n if (!COMPILED) {\n // Ensure that the same namespace isn't provided twice.\n // A goog.module/goog.provide maps a goog.require to a specific file\n if (goog.isProvided_(name)) {\n throw new Error('Namespace \"' + name + '\" already declared.');\n }\n }\n\n goog.constructNamespace_(name);\n};\n\n\n/**\n * @param {string} name Namespace provided by this file in the form\n * \"goog.package.part\".\n * @param {?Object=} object The object to embed in the namespace.\n * @param {boolean=} overwriteImplicit If object is set and a previous call\n * implicitly constructed the namespace given by name, this parameter\n * controls whether opt_obj should overwrite the implicitly constructed\n * namespace or be merged into it. Defaults to false.\n * @private\n */\ngoog.constructNamespace_ = function(name, object, overwriteImplicit) {\n if (!COMPILED) {\n delete goog.implicitNamespaces_[name];\n\n var namespace = name;\n while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {\n if (goog.getObjectByName(namespace)) {\n break;\n }\n goog.implicitNamespaces_[namespace] = true;\n }\n }\n\n goog.exportPath_(name, object, overwriteImplicit);\n};\n\n\n/**\n * According to the CSP3 spec a nonce must be a valid base64 string.\n * @see https://www.w3.org/TR/CSP3/#grammardef-base64-value\n * @private @const\n */\ngoog.NONCE_PATTERN_ = /^[\\w+/_-]+[=]{0,2}$/;\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {?Window=} opt_window The window context used to retrieve the nonce.\n * Defaults to global context.\n * @return {string} CSP nonce or empty string if no nonce is present.\n * @private\n */\ngoog.getScriptNonce_ = function(opt_window) {\n var doc = (opt_window || goog.global).document;\n var script = doc.querySelector && doc.querySelector('script[nonce]');\n if (script) {\n // Try to get the nonce from the IDL property first, because browsers that\n // implement additional nonce protection features (currently only Chrome) to\n // prevent nonce stealing via CSS do not expose the nonce via attributes.\n // See https://github.com/whatwg/html/issues/2369\n var nonce = script['nonce'] || script.getAttribute('nonce');\n if (nonce && goog.NONCE_PATTERN_.test(nonce)) {\n return nonce;\n }\n }\n return '';\n};\n\n\n/**\n * Module identifier validation regexp.\n * Note: This is a conservative check, it is very possible to be more lenient,\n * the primary exclusion here is \"/\" and \"\\\" and a leading \".\", these\n * restrictions are intended to leave the door open for using goog.require\n * with relative file paths rather than module identifiers.\n * @private\n */\ngoog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;\n\n\n/**\n * Defines a module in Closure.\n *\n * Marks that this file must be loaded as a module and claims the namespace.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * goog.module() has three requirements:\n * - goog.module may not be used in the same file as goog.provide.\n * - goog.module must be the first statement in the file.\n * - only one goog.module is allowed per file.\n *\n * When a goog.module annotated file is loaded, it is enclosed in\n * a strict function closure. This means that:\n * - any variables declared in a goog.module file are private to the file\n * (not global), though the compiler is expected to inline the module.\n * - The code must obey all the rules of \"strict\" JavaScript.\n * - the file will be marked as \"use strict\"\n *\n * NOTE: unlike goog.provide, goog.module does not declare any symbols by\n * itself. If declared symbols are desired, use\n * goog.module.declareLegacyNamespace().\n *\n *\n * See the public goog.module proposal: http://goo.gl/Va1hin\n *\n * @param {string} name Namespace provided by this file in the form\n * \"goog.package.part\", is expected but not required.\n * @return {void}\n */\ngoog.module = function(name) {\n if (typeof name !== 'string' || !name ||\n name.search(goog.VALID_MODULE_RE_) == -1) {\n throw new Error('Invalid module identifier');\n }\n if (!goog.isInGoogModuleLoader_()) {\n throw new Error(\n 'Module ' + name + ' has been loaded incorrectly. Note, ' +\n 'modules cannot be loaded as normal scripts. They require some kind of ' +\n 'pre-processing step. You\\'re likely trying to load a module via a ' +\n 'script tag or as a part of a concatenated bundle without rewriting the ' +\n 'module. For more info see: ' +\n 'https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.');\n }\n if (goog.moduleLoaderState_.moduleName) {\n throw new Error('goog.module may only be called once per module.');\n }\n\n // Store the module name for the loader.\n goog.moduleLoaderState_.moduleName = name;\n if (!COMPILED) {\n // Ensure that the same namespace isn't provided twice.\n // A goog.module/goog.provide maps a goog.require to a specific file\n if (goog.isProvided_(name)) {\n throw new Error('Namespace \"' + name + '\" already declared.');\n }\n delete goog.implicitNamespaces_[name];\n }\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n *\n * Note: This is not an alternative to goog.require, it does not\n * indicate a hard dependency, instead it is used to indicate\n * an optional dependency or to access the exports of a module\n * that has already been loaded.\n * @suppress {missingProvide}\n */\ngoog.module.get = function(name) {\n return goog.module.getInternal_(name);\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n * @private\n */\ngoog.module.getInternal_ = function(name) {\n if (!COMPILED) {\n if (name in goog.loadedModules_) {\n return goog.loadedModules_[name].exports;\n } else if (!goog.implicitNamespaces_[name]) {\n var ns = goog.getObjectByName(name);\n return ns != null ? ns : null;\n }\n }\n return null;\n};\n\n/**\n * Types of modules the debug loader can load.\n * @enum {string}\n */\ngoog.ModuleType = {\n ES6: 'es6',\n GOOG: 'goog'\n};\n\n\n/**\n * @private {?{\n * moduleName: (string|undefined),\n * declareLegacyNamespace:boolean,\n * type: ?goog.ModuleType\n * }}\n */\ngoog.moduleLoaderState_ = null;\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module or an es6 module is currently being\n * initialized.\n */\ngoog.isInModuleLoader_ = function() {\n return goog.isInGoogModuleLoader_() || goog.isInEs6ModuleLoader_();\n};\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module is currently being initialized.\n */\ngoog.isInGoogModuleLoader_ = function() {\n return !!goog.moduleLoaderState_ &&\n goog.moduleLoaderState_.type == goog.ModuleType.GOOG;\n};\n\n\n/**\n * @private\n * @return {boolean} Whether an es6 module is currently being initialized.\n */\ngoog.isInEs6ModuleLoader_ = function() {\n var inLoader = !!goog.moduleLoaderState_ &&\n goog.moduleLoaderState_.type == goog.ModuleType.ES6;\n\n if (inLoader) {\n return true;\n }\n\n var jscomp = goog.global['$jscomp'];\n\n if (jscomp) {\n // jscomp may not have getCurrentModulePath if this is a compiled bundle\n // that has some of the runtime, but not all of it. This can happen if\n // optimizations are turned on so the unused runtime is removed but renaming\n // and Closure pass are off (so $jscomp is still named $jscomp and the\n // goog.provide/require calls still exist).\n if (typeof jscomp.getCurrentModulePath != 'function') {\n return false;\n }\n\n // Bundled ES6 module.\n return !!jscomp.getCurrentModulePath();\n }\n\n return false;\n};\n\n\n/**\n * Provide the module's exports as a globally accessible object under the\n * module's declared name. This is intended to ease migration to goog.module\n * for files that have existing usages.\n * @suppress {missingProvide}\n */\ngoog.module.declareLegacyNamespace = function() {\n if (!COMPILED && !goog.isInGoogModuleLoader_()) {\n throw new Error(\n 'goog.module.declareLegacyNamespace must be called from ' +\n 'within a goog.module');\n }\n if (!COMPILED && !goog.moduleLoaderState_.moduleName) {\n throw new Error(\n 'goog.module must be called prior to ' +\n 'goog.module.declareLegacyNamespace.');\n }\n goog.moduleLoaderState_.declareLegacyNamespace = true;\n};\n\n\n/**\n * Associates an ES6 module with a Closure module ID so that is available via\n * goog.require. The associated ID acts like a goog.module ID - it does not\n * create any global names, it is merely available via goog.require /\n * goog.module.get / goog.forwardDeclare / goog.requireType. goog.require and\n * goog.module.get will return the entire module as if it was import *'d. This\n * allows Closure files to reference ES6 modules for the sake of migration.\n *\n * @param {string} namespace\n * @suppress {missingProvide}\n */\ngoog.declareModuleId = function(namespace) {\n if (!COMPILED) {\n if (!goog.isInEs6ModuleLoader_()) {\n throw new Error(\n 'goog.declareModuleId may only be called from ' +\n 'within an ES6 module');\n }\n if (goog.moduleLoaderState_ && goog.moduleLoaderState_.moduleName) {\n throw new Error(\n 'goog.declareModuleId may only be called once per module.');\n }\n if (namespace in goog.loadedModules_) {\n throw new Error(\n 'Module with namespace \"' + namespace + '\" already exists.');\n }\n }\n if (goog.moduleLoaderState_) {\n // Not bundled - debug loading.\n goog.moduleLoaderState_.moduleName = namespace;\n } else {\n // Bundled - not debug loading, no module loader state.\n var jscomp = goog.global['$jscomp'];\n if (!jscomp || typeof jscomp.getCurrentModulePath != 'function') {\n throw new Error(\n 'Module with namespace \"' + namespace +\n '\" has been loaded incorrectly.');\n }\n var exports = jscomp.require(jscomp.getCurrentModulePath());\n goog.loadedModules_[namespace] = {\n exports: exports,\n type: goog.ModuleType.ES6,\n moduleId: namespace\n };\n }\n};\n\n\n/**\n * Marks that the current file should only be used for testing, and never for\n * live code in production.\n *\n * In the case of unit tests, the message may optionally be an exact namespace\n * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra\n * provide (if not explicitly defined in the code).\n *\n * @param {string=} opt_message Optional message to add to the error that's\n * raised when used in production code.\n */\ngoog.setTestOnly = function(opt_message) {\n if (goog.DISALLOW_TEST_ONLY_CODE) {\n opt_message = opt_message || '';\n throw new Error(\n 'Importing test-only code into non-debug environment' +\n (opt_message ? ': ' + opt_message : '.'));\n }\n};\n\n\n/**\n * Forward declares a symbol. This is an indication to the compiler that the\n * symbol may be used in the source yet is not required and may not be provided\n * in compilation.\n *\n * The most common usage of forward declaration is code that takes a type as a\n * function parameter but does not need to require it. By forward declaring\n * instead of requiring, no hard dependency is made, and (if not required\n * elsewhere) the namespace may never be required and thus, not be pulled\n * into the JavaScript binary. If it is required elsewhere, it will be type\n * checked as normal.\n *\n * Before using goog.forwardDeclare, please read the documentation at\n * https://github.com/google/closure-compiler/wiki/Bad-Type-Annotation to\n * understand the options and tradeoffs when working with forward declarations.\n *\n * @param {string} name The namespace to forward declare in the form of\n * \"goog.package.part\".\n * @deprecated See go/noforwarddeclaration, Use `goog.requireType` instead.\n */\ngoog.forwardDeclare = function(name) {};\n\n\n/**\n * Forward declare type information. Used to assign types to goog.global\n * referenced object that would otherwise result in unknown type references\n * and thus block property disambiguation.\n */\ngoog.forwardDeclare('Document');\ngoog.forwardDeclare('HTMLScriptElement');\ngoog.forwardDeclare('XMLHttpRequest');\n\n\nif (!COMPILED) {\n /**\n * Check if the given name has been goog.provided. This will return false for\n * names that are available only as implicit namespaces.\n * @param {string} name name of the object to look for.\n * @return {boolean} Whether the name has been provided.\n * @private\n */\n goog.isProvided_ = function(name) {\n return (name in goog.loadedModules_) ||\n (!goog.implicitNamespaces_[name] && goog.getObjectByName(name) != null);\n };\n\n /**\n * Namespaces implicitly defined by goog.provide. For example,\n * goog.provide('goog.events.Event') implicitly declares that 'goog' and\n * 'goog.events' must be namespaces.\n *\n * @type {!Object<string, (boolean|undefined)>}\n * @private\n */\n goog.implicitNamespaces_ = {'goog.module': true};\n\n // NOTE: We add goog.module as an implicit namespace as goog.module is defined\n // here and because the existing module package has not been moved yet out of\n // the goog.module namespace. This satisifies both the debug loader and\n // ahead-of-time dependency management.\n}\n\n\n/**\n * Returns an object based on its fully qualified external name. The object\n * is not found if null or undefined. If you are using a compilation pass that\n * renames property names beware that using this function will not find renamed\n * properties.\n *\n * @param {string} name The fully qualified name.\n * @param {Object=} opt_obj The object within which to look; default is\n * |goog.global|.\n * @return {?} The value (object or primitive) or, if not found, null.\n */\ngoog.getObjectByName = function(name, opt_obj) {\n var parts = name.split('.');\n var cur = opt_obj || goog.global;\n for (var i = 0; i < parts.length; i++) {\n cur = cur[parts[i]];\n if (cur == null) {\n return null;\n }\n }\n return cur;\n};\n\n\n/**\n * Adds a dependency from a file to the files it requires.\n * @param {string} relPath The path to the js file.\n * @param {!Array<string>} provides An array of strings with\n * the names of the objects this file provides.\n * @param {!Array<string>} requires An array of strings with\n * the names of the objects this file requires.\n * @param {boolean|!Object<string>=} opt_loadFlags Parameters indicating\n * how the file must be loaded. The boolean 'true' is equivalent\n * to {'module': 'goog'} for backwards-compatibility. Valid properties\n * and values include {'module': 'goog'} and {'lang': 'es6'}.\n */\ngoog.addDependency = function(relPath, provides, requires, opt_loadFlags) {\n if (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n goog.debugLoader_.addDependency(relPath, provides, requires, opt_loadFlags);\n }\n};\n\n\n// NOTE(nnaze): The debug DOM loader was included in base.js as an original way\n// to do \"debug-mode\" development. The dependency system can sometimes be\n// confusing, as can the debug DOM loader's asynchronous nature.\n//\n// With the DOM loader, a call to goog.require() is not blocking -- the script\n// will not load until some point after the current script. If a namespace is\n// needed at runtime, it needs to be defined in a previous script, or loaded via\n// require() with its registered dependencies.\n//\n// User-defined namespaces may need their own deps file. For a reference on\n// creating a deps file, see:\n// Externally: https://developers.google.com/closure/library/docs/depswriter\n//\n// Because of legacy clients, the DOM loader can't be easily removed from\n// base.js. Work was done to make it disableable or replaceable for\n// different environments (DOM-less JavaScript interpreters like Rhino or V8,\n// for example). See bootstrap/ for more information.\n\n\n/**\n * @define {boolean} Whether to enable the debug loader.\n *\n * If enabled, a call to goog.require() will attempt to load the namespace by\n * appending a script tag to the DOM (if the namespace has been registered).\n *\n * If disabled, goog.require() will simply assert that the namespace has been\n * provided (and depend on the fact that some outside tool correctly ordered\n * the script).\n */\ngoog.ENABLE_DEBUG_LOADER = goog.define('goog.ENABLE_DEBUG_LOADER', false);\n\n\n/**\n * @param {string} msg\n * @private\n */\ngoog.logToConsole_ = function(msg) {\n if (goog.global.console) {\n goog.global.console['error'](msg);\n }\n};\n\n\n/**\n * Implements a system for the dynamic resolution of dependencies that works in\n * parallel with the BUILD system.\n *\n * Note that all calls to goog.require will be stripped by the compiler.\n *\n * @see goog.provide\n * @param {string} namespace Namespace (as was given in goog.provide,\n * goog.module, or goog.declareModuleId) in the form\n * \"goog.package.part\".\n * @return {?} If called within a goog.module or ES6 module file, the associated\n * namespace or module otherwise null.\n */\ngoog.require = function(namespace) {\n if (!COMPILED) {\n // Might need to lazy load on old IE.\n if (goog.ENABLE_DEBUG_LOADER) {\n goog.debugLoader_.requested(namespace);\n }\n\n // If the object already exists we do not need to do anything.\n if (goog.isProvided_(namespace)) {\n if (goog.isInModuleLoader_()) {\n return goog.module.getInternal_(namespace);\n }\n } else if (goog.ENABLE_DEBUG_LOADER) {\n var moduleLoaderState = goog.moduleLoaderState_;\n goog.moduleLoaderState_ = null;\n try {\n goog.debugLoader_.load_(namespace);\n } finally {\n goog.moduleLoaderState_ = moduleLoaderState;\n }\n }\n\n return null;\n }\n};\n\n\n/**\n * Requires a symbol for its type information. This is an indication to the\n * compiler that the symbol may appear in type annotations, yet it is not\n * referenced at runtime.\n *\n * When called within a goog.module or ES6 module file, the return value may be\n * assigned to or destructured into a variable, but it may not be otherwise used\n * in code outside of a type annotation.\n *\n * Note that all calls to goog.requireType will be stripped by the compiler.\n *\n * @param {string} namespace Namespace (as was given in goog.provide,\n * goog.module, or goog.declareModuleId) in the form\n * \"goog.package.part\".\n * @return {?}\n */\ngoog.requireType = function(namespace) {\n // Return an empty object so that single-level destructuring of the return\n // value doesn't crash at runtime when using the debug loader. Multi-level\n // destructuring isn't supported.\n return {};\n};\n\n\n/**\n * Path for included scripts.\n * @type {string}\n */\ngoog.basePath = '';\n\n\n/**\n * A hook for overriding the base path.\n * @type {string|undefined}\n */\ngoog.global.CLOSURE_BASE_PATH;\n\n\n/**\n * Whether to attempt to load Closure's deps file. By default, when uncompiled,\n * deps files will attempt to be loaded.\n * @type {boolean|undefined}\n */\ngoog.global.CLOSURE_NO_DEPS;\n\n\n/**\n * A function to import a single script. This is meant to be overridden when\n * Closure is being run in non-HTML contexts, such as web workers. It's defined\n * in the global scope so that it can be set before base.js is loaded, which\n * allows deps.js to be imported properly.\n *\n * The first parameter the script source, which is a relative URI. The second,\n * optional parameter is the script contents, in the event the script needed\n * transformation. It should return true if the script was imported, false\n * otherwise.\n * @type {(function(string, string=): boolean)|undefined}\n */\ngoog.global.CLOSURE_IMPORT_SCRIPT;\n\n\n/**\n * When defining a class Foo with an abstract method bar(), you can do:\n * Foo.prototype.bar = goog.abstractMethod\n *\n * Now if a subclass of Foo fails to override bar(), an error will be thrown\n * when bar() is invoked.\n *\n * @type {!Function}\n * @throws {Error} when invoked to indicate the method should be overridden.\n * @deprecated Use \"@abstract\" annotation instead of goog.abstractMethod in new\n * code. See\n * https://github.com/google/closure-compiler/wiki/@abstract-classes-and-methods\n */\ngoog.abstractMethod = function() {\n throw new Error('unimplemented abstract method');\n};\n\n\n/**\n * Adds a `getInstance` static method that always returns the same\n * instance object.\n * @param {!Function} ctor The constructor for the class to add the static\n * method to.\n * @suppress {missingProperties} 'instance_' isn't a property on 'Function'\n * but we don't have a better type to use here.\n */\ngoog.addSingletonGetter = function(ctor) {\n // instance_ is immediately set to prevent issues with sealed constructors\n // such as are encountered when a constructor is returned as the export object\n // of a goog.module in unoptimized code.\n // Delcare type to avoid conformance violations that ctor.instance_ is unknown\n /** @type {undefined|!Object} @suppress {underscore} */\n ctor.instance_ = undefined;\n ctor.getInstance = function() {\n if (ctor.instance_) {\n return ctor.instance_;\n }\n if (goog.DEBUG) {\n // NOTE: JSCompiler can't optimize away Array#push.\n goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;\n }\n // Cast to avoid conformance violations that ctor.instance_ is unknown\n return /** @type {!Object|undefined} */ (ctor.instance_) = new ctor;\n };\n};\n\n\n/**\n * All singleton classes that have been instantiated, for testing. Don't read\n * it directly, use the `goog.testing.singleton` module. The compiler\n * removes this variable if unused.\n * @type {!Array<!Function>}\n * @private\n */\ngoog.instantiatedSingletons_ = [];\n\n\n/**\n * @define {boolean} Whether to load goog.modules using `eval` when using\n * the debug loader. This provides a better debugging experience as the\n * source is unmodified and can be edited using Chrome Workspaces or similar.\n * However in some environments the use of `eval` is banned\n * so we provide an alternative.\n */\ngoog.LOAD_MODULE_USING_EVAL = goog.define('goog.LOAD_MODULE_USING_EVAL', true);\n\n\n/**\n * @define {boolean} Whether the exports of goog.modules should be sealed when\n * possible.\n */\ngoog.SEAL_MODULE_EXPORTS = goog.define('goog.SEAL_MODULE_EXPORTS', goog.DEBUG);\n\n\n/**\n * The registry of initialized modules:\n * The module identifier or path to module exports map.\n * @private @const {!Object<string, {exports:?,type:string,moduleId:string}>}\n */\ngoog.loadedModules_ = {};\n\n\n/**\n * True if the debug loader enabled and used.\n * @const {boolean}\n */\ngoog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;\n\n\n/**\n * @define {string} How to decide whether to transpile. Valid values\n * are 'always', 'never', and 'detect'. The default ('detect') is to\n * use feature detection to determine which language levels need\n * transpilation.\n */\n// NOTE(sdh): we could expand this to accept a language level to bypass\n// detection: e.g. goog.TRANSPILE == 'es5' would transpile ES6 files but\n// would leave ES3 and ES5 files alone.\ngoog.TRANSPILE = goog.define('goog.TRANSPILE', 'detect');\n\n/**\n * @define {boolean} If true assume that ES modules have already been\n * transpiled by the jscompiler (in the same way that transpile.js would\n * transpile them - to jscomp modules). Useful only for servers that wish to use\n * the debug loader and transpile server side. Thus this is only respected if\n * goog.TRANSPILE is \"never\".\n */\ngoog.ASSUME_ES_MODULES_TRANSPILED =\n goog.define('goog.ASSUME_ES_MODULES_TRANSPILED', false);\n\n\n/**\n * @define {string} Trusted Types policy name. If non-empty then Closure will\n * use Trusted Types.\n */\ngoog.TRUSTED_TYPES_POLICY_NAME =\n goog.define('goog.TRUSTED_TYPES_POLICY_NAME', 'goog');\n\n\n/**\n * @package {?boolean}\n * Visible for testing.\n */\ngoog.hasBadLetScoping = null;\n\n\n/**\n * @param {function(?):?|string} moduleDef The module definition.\n */\ngoog.loadModule = function(moduleDef) {\n // NOTE: we allow function definitions to be either in the from\n // of a string to eval (which keeps the original source intact) or\n // in a eval forbidden environment (CSP) we allow a function definition\n // which in its body must call `goog.module`, and return the exports\n // of the module.\n var previousState = goog.moduleLoaderState_;\n try {\n goog.moduleLoaderState_ = {\n moduleName: '',\n declareLegacyNamespace: false,\n type: goog.ModuleType.GOOG\n };\n var origExports = {};\n var exports = origExports;\n if (typeof moduleDef === 'function') {\n exports = moduleDef.call(undefined, exports);\n } else if (typeof moduleDef === 'string') {\n exports = goog.loadModuleFromSource_.call(undefined, exports, moduleDef);\n } else {\n throw new Error('Invalid module definition');\n }\n\n var moduleName = goog.moduleLoaderState_.moduleName;\n if (typeof moduleName === 'string' && moduleName) {\n // Don't seal legacy namespaces as they may be used as a parent of\n // another namespace\n if (goog.moduleLoaderState_.declareLegacyNamespace) {\n // Whether exports was overwritten via default export assignment.\n // This is important for legacy namespaces as it dictates whether\n // previously a previously loaded implicit namespace should be clobbered\n // or not.\n var isDefaultExport = origExports !== exports;\n goog.constructNamespace_(moduleName, exports, isDefaultExport);\n } else if (\n goog.SEAL_MODULE_EXPORTS && Object.seal &&\n typeof exports == 'object' && exports != null) {\n Object.seal(exports);\n }\n\n var data = {\n exports: exports,\n type: goog.ModuleType.GOOG,\n moduleId: goog.moduleLoaderState_.moduleName\n };\n goog.loadedModules_[moduleName] = data;\n } else {\n throw new Error('Invalid module name \\\"' + moduleName + '\\\"');\n }\n } finally {\n goog.moduleLoaderState_ = previousState;\n }\n};\n\n\n/**\n * @private @const\n */\ngoog.loadModuleFromSource_ =\n /** @type {function(!Object, string):?} */ (function(exports) {\n // NOTE: we avoid declaring parameters or local variables here to avoid\n // masking globals or leaking values into the module definition.\n 'use strict';\n eval(goog.CLOSURE_EVAL_PREFILTER_.createScript(arguments[1]));\n return exports;\n });\n\n\n/**\n * Normalize a file path by removing redundant \"..\" and extraneous \".\" file\n * path components.\n * @param {string} path\n * @return {string}\n * @private\n */\ngoog.normalizePath_ = function(path) {\n var components = path.split('/');\n var i = 0;\n while (i < components.length) {\n if (components[i] == '.') {\n components.splice(i, 1);\n } else if (\n i && components[i] == '..' && components[i - 1] &&\n components[i - 1] != '..') {\n components.splice(--i, 2);\n } else {\n i++;\n }\n }\n return components.join('/');\n};\n\n\n/**\n * Provides a hook for loading a file when using Closure's goog.require() API\n * with goog.modules. In particular this hook is provided to support Node.js.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_LOAD_FILE_SYNC;\n\n\n/**\n * Loads file by synchronous XHR. Should not be used in production environments.\n * @param {string} src Source URL.\n * @return {?string} File contents, or null if load failed.\n * @private\n */\ngoog.loadFileSync_ = function(src) {\n if (goog.global.CLOSURE_LOAD_FILE_SYNC) {\n return goog.global.CLOSURE_LOAD_FILE_SYNC(src);\n } else {\n try {\n /** @type {XMLHttpRequest} */\n var xhr = new goog.global['XMLHttpRequest']();\n xhr.open('get', src, false);\n xhr.send();\n // NOTE: Successful http: requests have a status of 200, but successful\n // file: requests may have a status of zero. Any other status, or a\n // thrown exception (particularly in case of file: requests) indicates\n // some sort of error, which we treat as a missing or unavailable file.\n return xhr.status == 0 || xhr.status == 200 ? xhr.responseText : null;\n } catch (err) {\n // No need to rethrow or log, since errors should show up on their own.\n return null;\n }\n }\n};\n\n//==============================================================================\n// Language Enhancements\n//==============================================================================\n\n\n/**\n * This is a \"fixed\" version of the typeof operator. It differs from the typeof\n * operator in such a way that null returns 'null' and arrays return 'array'.\n * @param {?} value The value to get the type of.\n * @return {string} The name of the type.\n */\ngoog.typeOf = function(value) {\n var s = typeof value;\n\n if (s != 'object') {\n return s;\n }\n\n if (!value) {\n return 'null';\n }\n\n if (Array.isArray(value)) {\n return 'array';\n }\n return s;\n};\n\n\n/**\n * Returns true if the object looks like an array. To qualify as array like\n * the value needs to be either a NodeList or an object with a Number length\n * property. Note that for this function neither strings nor functions are\n * considered \"array-like\".\n *\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an array.\n */\ngoog.isArrayLike = function(val) {\n var type = goog.typeOf(val);\n // We do not use goog.isObject here in order to exclude function values.\n return type == 'array' || type == 'object' && typeof val.length == 'number';\n};\n\n\n/**\n * Returns true if the object looks like a Date. To qualify as Date-like the\n * value needs to be an object and have a getFullYear() function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a like a Date.\n */\ngoog.isDateLike = function(val) {\n return goog.isObject(val) && typeof val.getFullYear == 'function';\n};\n\n\n/**\n * Returns true if the specified value is an object. This includes arrays and\n * functions.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an object.\n */\ngoog.isObject = function(val) {\n var type = typeof val;\n return type == 'object' && val != null || type == 'function';\n // return Object(val) === val also works, but is slower, especially if val is\n // not an object.\n};\n\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. The unique ID is\n * guaranteed to be unique across the current session amongst objects that are\n * passed into `getUid`. There is no guarantee that the ID is unique or\n * consistent across sessions. It is unsafe to generate unique ID for function\n * prototypes.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {number} The unique ID for the object.\n */\ngoog.getUid = function(obj) {\n // TODO(arv): Make the type stricter, do not accept null.\n return Object.prototype.hasOwnProperty.call(obj, goog.UID_PROPERTY_) &&\n obj[goog.UID_PROPERTY_] ||\n (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);\n};\n\n\n/**\n * Whether the given object is already assigned a unique ID.\n *\n * This does not modify the object.\n *\n * @param {!Object} obj The object to check.\n * @return {boolean} Whether there is an assigned unique id for the object.\n */\ngoog.hasUid = function(obj) {\n return !!obj[goog.UID_PROPERTY_];\n};\n\n\n/**\n * Removes the unique ID from an object. This is useful if the object was\n * previously mutated using `goog.getUid` in which case the mutation is\n * undone.\n * @param {Object} obj The object to remove the unique ID field from.\n */\ngoog.removeUid = function(obj) {\n // TODO(arv): Make the type stricter, do not accept null.\n\n // In IE, DOM nodes are not instances of Object and throw an exception if we\n // try to delete. Instead we try to use removeAttribute.\n if (obj !== null && 'removeAttribute' in obj) {\n obj.removeAttribute(goog.UID_PROPERTY_);\n }\n\n try {\n delete obj[goog.UID_PROPERTY_];\n } catch (ex) {\n }\n};\n\n\n/**\n * Name for unique ID property. Initialized in a way to help avoid collisions\n * with other closure JavaScript on the same page.\n * @type {string}\n * @private\n */\ngoog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * Counter for UID.\n * @type {number}\n * @private\n */\ngoog.uidCounter_ = 0;\n\n\n/**\n * Clones a value. The input may be an Object, Array, or basic type. Objects and\n * arrays will be cloned recursively.\n *\n * WARNINGS:\n * <code>goog.cloneObject</code> does not detect reference loops. Objects that\n * refer to themselves will cause infinite recursion.\n *\n * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies\n * UIDs created by <code>getUid</code> into cloned results.\n *\n * @param {*} obj The value to clone.\n * @return {*} A clone of the input value.\n * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.\n */\ngoog.cloneObject = function(obj) {\n var type = goog.typeOf(obj);\n if (type == 'object' || type == 'array') {\n if (typeof obj.clone === 'function') {\n return obj.clone();\n }\n if (typeof Map !== 'undefined' && obj instanceof Map) {\n return new Map(obj);\n } else if (typeof Set !== 'undefined' && obj instanceof Set) {\n return new Set(obj);\n }\n var clone = type == 'array' ? [] : {};\n for (var key in obj) {\n clone[key] = goog.cloneObject(obj[key]);\n }\n return clone;\n }\n\n return obj;\n};\n\n\n/**\n * A native implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n * function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n * function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n * invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindNative_ = function(fn, selfObj, var_args) {\n return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));\n};\n\n\n/**\n * A pure-JS implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n * function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n * function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n * invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindJs_ = function(fn, selfObj, var_args) {\n if (!fn) {\n throw new Error();\n }\n\n if (arguments.length > 2) {\n var boundArgs = Array.prototype.slice.call(arguments, 2);\n return function() {\n // Prepend the bound arguments to the current arguments.\n var newArgs = Array.prototype.slice.call(arguments);\n Array.prototype.unshift.apply(newArgs, boundArgs);\n return fn.apply(selfObj, newArgs);\n };\n\n } else {\n return function() {\n return fn.apply(selfObj, arguments);\n };\n }\n};\n\n\n/**\n * Partially applies this function to a particular 'this object' and zero or\n * more arguments. The result is a new function with some arguments of the first\n * function pre-filled and the value of this 'pre-specified'.\n *\n * Remaining arguments specified at call-time are appended to the pre-specified\n * ones.\n *\n * Also see: {@link #partial}.\n *\n * Usage:\n * <pre>var barMethBound = goog.bind(myFunction, myObj, 'arg1', 'arg2');\n * barMethBound('arg3', 'arg4');</pre>\n *\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n * function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n * function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n * invoked as a method of.\n * @template T\n * @suppress {deprecated} See above.\n * @deprecated use `=> {}` or Function.prototype.bind instead.\n */\ngoog.bind = function(fn, selfObj, var_args) {\n // TODO(nicksantos): narrow the type signature.\n if (Function.prototype.bind &&\n // NOTE(nicksantos): Somebody pulled base.js into the default Chrome\n // extension environment. This means that for Chrome extensions, they get\n // the implementation of Function.prototype.bind that calls goog.bind\n // instead of the native one. Even worse, we don't want to introduce a\n // circular dependency between goog.bind and Function.prototype.bind, so\n // we have to hack this to make sure it works correctly.\n Function.prototype.bind.toString().indexOf('native code') != -1) {\n goog.bind = goog.bindNative_;\n } else {\n goog.bind = goog.bindJs_;\n }\n return goog.bind.apply(null, arguments);\n};\n\n\n/**\n * Like goog.bind(), except that a 'this object' is not required. Useful when\n * the target function is already bound.\n *\n * Usage:\n * var g = goog.partial(f, arg1, arg2);\n * g(arg3, arg4);\n *\n * @param {Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn.\n * @return {!Function} A partially-applied form of the function goog.partial()\n * was invoked as a method of.\n */\ngoog.partial = function(fn, var_args) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function() {\n // Clone the array (with slice()) and append additional arguments\n // to the existing arguments.\n var newArgs = args.slice();\n newArgs.push.apply(newArgs, arguments);\n return fn.apply(/** @type {?} */ (this), newArgs);\n };\n};\n\n\n/**\n * @return {number} An integer value representing the number of milliseconds\n * between midnight, January 1, 1970 and the current time.\n * @deprecated Use Date.now\n */\ngoog.now = function() {\n return Date.now();\n};\n\n\n/**\n * Evals JavaScript in the global scope.\n *\n * Throws an exception if neither execScript or eval is defined.\n * @param {string|!TrustedScript} script JavaScript string.\n */\ngoog.globalEval = function(script) {\n (0, eval)(script);\n};\n\n\n/**\n * Optional map of CSS class names to obfuscated names used with\n * goog.getCssName().\n * @private {!Object<string, string>|undefined}\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMapping_;\n\n\n/**\n * Optional obfuscation style for CSS class names. Should be set to either\n * 'BY_WHOLE' or 'BY_PART' if defined.\n * @type {string|undefined}\n * @private\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMappingStyle_;\n\n\n\n/**\n * A hook for modifying the default behavior goog.getCssName. The function\n * if present, will receive the standard output of the goog.getCssName as\n * its input.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAP_FN;\n\n\n/**\n * Handles strings that are intended to be used as CSS class names.\n *\n * This function works in tandem with @see goog.setCssNameMapping.\n *\n * Without any mapping set, the arguments are simple joined with a hyphen and\n * passed through unaltered.\n *\n * When there is a mapping, there are two possible styles in which these\n * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)\n * of the passed in css name is rewritten according to the map. In the BY_WHOLE\n * style, the full css name is looked up in the map directly. If a rewrite is\n * not specified by the map, the compiler will output a warning.\n *\n * When the mapping is passed to the compiler, it will replace calls to\n * goog.getCssName with the strings from the mapping, e.g.\n * var x = goog.getCssName('foo');\n * var y = goog.getCssName(this.baseClass, 'active');\n * becomes:\n * var x = 'foo';\n * var y = this.baseClass + '-active';\n *\n * If one argument is passed it will be processed, if two are passed only the\n * modifier will be processed, as it is assumed the first argument was generated\n * as a result of calling goog.getCssName.\n *\n * @param {string} className The class name.\n * @param {string=} opt_modifier A modifier to be appended to the class name.\n * @return {string} The class name or the concatenation of the class name and\n * the modifier.\n */\ngoog.getCssName = function(className, opt_modifier) {\n // String() is used for compatibility with compiled soy where the passed\n // className can be non-string objects.\n if (String(className).charAt(0) == '.') {\n throw new Error(\n 'className passed in goog.getCssName must not start with \".\".' +\n ' You passed: ' + className);\n }\n\n var getMapping = function(cssName) {\n return goog.cssNameMapping_[cssName] || cssName;\n };\n\n var renameByParts = function(cssName) {\n // Remap all the parts individually.\n var parts = cssName.split('-');\n var mapped = [];\n for (var i = 0; i < parts.length; i++) {\n mapped.push(getMapping(parts[i]));\n }\n return mapped.join('-');\n };\n\n var rename;\n if (goog.cssNameMapping_) {\n rename =\n goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts;\n } else {\n rename = function(a) {\n return a;\n };\n }\n\n var result =\n opt_modifier ? className + '-' + rename(opt_modifier) : rename(className);\n\n // The special CLOSURE_CSS_NAME_MAP_FN allows users to specify further\n // processing of the class name.\n if (goog.global.CLOSURE_CSS_NAME_MAP_FN) {\n return goog.global.CLOSURE_CSS_NAME_MAP_FN(result);\n }\n\n return result;\n};\n\n\n/**\n * Sets the map to check when returning a value from goog.getCssName(). Example:\n * <pre>\n * goog.setCssNameMapping({\n * \"goog\": \"a\",\n * \"disabled\": \"b\",\n * });\n *\n * var x = goog.getCssName('goog');\n * // The following evaluates to: \"a a-b\".\n * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')\n * </pre>\n * When declared as a map of string literals to string literals, the JSCompiler\n * will replace all calls to goog.getCssName() using the supplied map if the\n * --process_closure_primitives flag is set.\n *\n * @param {!Object} mapping A map of strings to strings where keys are possible\n * arguments to goog.getCssName() and values are the corresponding values\n * that should be returned.\n * @param {string=} opt_style The style of css name mapping. There are two valid\n * options: 'BY_PART', and 'BY_WHOLE'.\n * @see goog.getCssName for a description.\n */\ngoog.setCssNameMapping = function(mapping, opt_style) {\n goog.cssNameMapping_ = mapping;\n goog.cssNameMappingStyle_ = opt_style;\n};\n\n\n/**\n * To use CSS renaming in compiled mode, one of the input files should have a\n * call to goog.setCssNameMapping() with an object literal that the JSCompiler\n * can extract and use to replace all calls to goog.getCssName(). In uncompiled\n * mode, JavaScript code should be loaded before this base.js file that declares\n * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is\n * to ensure that the mapping is loaded before any calls to goog.getCssName()\n * are made in uncompiled mode.\n *\n * A hook for overriding the CSS name mapping.\n * @type {!Object<string, string>|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAPPING;\n\n\nif (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {\n // This does not call goog.setCssNameMapping() because the JSCompiler\n // requires that goog.setCssNameMapping() be called with an object literal.\n goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;\n}\n\n/**\n * Options bag type for `goog.getMsg()` third argument.\n *\n * It is important to note that these options need to be known at compile time,\n * so they must always be provided to `goog.getMsg()` as an actual object\n * literal in the function call. Otherwise, closure-compiler will report an\n * error.\n * @record\n */\ngoog.GetMsgOptions = function() {};\n\n/**\n * If `true`, escape '<' in the message string to '<'.\n *\n * Used by Closure Templates where the generated code size and performance is\n * critical which is why {@link goog.html.SafeHtmlFormatter} is not used.\n * The value must be literal `true` or `false`.\n * @type {boolean|undefined}\n */\ngoog.GetMsgOptions.prototype.html;\n\n/**\n * If `true`, unescape common html entities: >, <, ', " and\n * &.\n *\n * Used for messages not in HTML context, such as with the `textContent`\n * property.\n * The value must be literal `true` or `false`.\n * @type {boolean|undefined}\n */\ngoog.GetMsgOptions.prototype.unescapeHtmlEntities;\n\n/**\n * Associates placeholder names with strings showing how their values are\n * obtained.\n *\n * This field is intended for use in automatically generated JS code.\n * Human-written code should use meaningful placeholder names instead.\n *\n * closure-compiler uses this as the contents of the `<ph>` tag in the\n * XMB file it generates or defaults to `-` for historical reasons.\n *\n * Must be an object literal.\n * Ignored at runtime.\n * Keys are placeholder names.\n * Values are string literals indicating how the value is obtained.\n * Typically this is a snippet of source code.\n * @type {!Object<string, string>|undefined}\n */\ngoog.GetMsgOptions.prototype.original_code;\n\n/**\n * Associates placeholder names with example values.\n *\n * closure-compiler uses this as the contents of the `<ex>` tag in the\n * XMB file it generates or defaults to `-` for historical reasons.\n *\n * Must be an object literal.\n * Ignored at runtime.\n * Keys are placeholder names.\n * Values are string literals containing example placeholder values.\n * (e.g. \"George McFly\" for a name placeholder)\n * @type {!Object<string, string>|undefined}\n */\ngoog.GetMsgOptions.prototype.example;\n\n/**\n * Gets a localized message.\n *\n * This function is a compiler primitive. If you give the compiler a localized\n * message bundle, it will replace the string at compile-time with a localized\n * version, and expand goog.getMsg call to a concatenated string.\n *\n * Messages must be initialized in the form:\n * <code>\n * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});\n * </code>\n *\n * This function produces a string which should be treated as plain text. Use\n * {@link goog.html.SafeHtmlFormatter} in conjunction with goog.getMsg to\n * produce SafeHtml.\n *\n * @param {string} str Translatable string, places holders in the form {$foo}.\n * @param {!Object<string, string>=} opt_values Maps place holder name to value.\n * @param {!goog.GetMsgOptions=} opt_options see `goog.GetMsgOptions`\n * @return {string} message with placeholders filled.\n */\ngoog.getMsg = function(str, opt_values, opt_options) {\n if (opt_options && opt_options.html) {\n // Note that '&' is not replaced because the translation can contain HTML\n // entities.\n str = str.replace(/</g, '<');\n }\n if (opt_options && opt_options.unescapeHtmlEntities) {\n // Note that \"&\" must be the last to avoid \"creating\" new entities.\n str = str.replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/'/g, '\\'')\n .replace(/"/g, '\"')\n .replace(/&/g, '&');\n }\n if (opt_values) {\n str = str.replace(/\\{\\$([^}]+)}/g, function(match, key) {\n return (opt_values != null && key in opt_values) ? opt_values[key] :\n match;\n });\n }\n return str;\n};\n\n\n/**\n * Gets a localized message. If the message does not have a translation, gives a\n * fallback message.\n *\n * This is useful when introducing a new message that has not yet been\n * translated into all languages.\n *\n * This function is a compiler primitive. Must be used in the form:\n * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>\n * where MSG_A and MSG_B were initialized with goog.getMsg.\n *\n * @param {string} a The preferred message.\n * @param {string} b The fallback message.\n * @return {string} The best translated message.\n */\ngoog.getMsgWithFallback = function(a, b) {\n return a;\n};\n\n\n/**\n * Exposes an unobfuscated global namespace path for the given object.\n * Note that fields of the exported object *will* be obfuscated, unless they are\n * exported in turn via this function or goog.exportProperty.\n *\n * Also handy for making public items that are defined in anonymous closures.\n *\n * ex. goog.exportSymbol('public.path.Foo', Foo);\n *\n * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);\n * public.path.Foo.staticFunction();\n *\n * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',\n * Foo.prototype.myMethod);\n * new public.path.Foo().myMethod();\n *\n * @param {string} publicPath Unobfuscated name to export.\n * @param {*} object Object the name should point to.\n * @param {?Object=} objectToExportTo The object to add the path to; default\n * is goog.global.\n */\ngoog.exportSymbol = function(publicPath, object, objectToExportTo) {\n goog.exportPath_(\n publicPath, object, /* overwriteImplicit= */ true, objectToExportTo);\n};\n\n\n/**\n * Exports a property unobfuscated into the object's namespace.\n * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);\n * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);\n * @param {Object} object Object whose static property is being exported.\n * @param {string} publicName Unobfuscated name to export.\n * @param {*} symbol Object the name should point to.\n */\ngoog.exportProperty = function(object, publicName, symbol) {\n object[publicName] = symbol;\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * Usage:\n * <pre>\n * function ParentClass(a, b) { }\n * ParentClass.prototype.foo = function(a) { };\n *\n * function ChildClass(a, b, c) {\n * ChildClass.base(this, 'constructor', a, b);\n * }\n * goog.inherits(ChildClass, ParentClass);\n *\n * var child = new ChildClass('a', 'b', 'see');\n * child.foo(); // This works.\n * </pre>\n *\n * @param {!Function} childCtor Child class.\n * @param {!Function} parentCtor Parent class.\n * @suppress {strictMissingProperties} superClass_ and base is not defined on\n * Function.\n * @deprecated Use ECMAScript class syntax instead.\n */\ngoog.inherits = function(childCtor, parentCtor) {\n /** @constructor */\n function tempCtor() {}\n tempCtor.prototype = parentCtor.prototype;\n childCtor.superClass_ = parentCtor.prototype;\n childCtor.prototype = new tempCtor();\n /** @override */\n childCtor.prototype.constructor = childCtor;\n\n /**\n * Calls superclass constructor/method.\n *\n * This function is only available if you use goog.inherits to\n * express inheritance relationships between classes.\n *\n * NOTE: This is a replacement for goog.base and for superClass_\n * property defined in childCtor.\n *\n * @param {!Object} me Should always be \"this\".\n * @param {string} methodName The method name to call. Calling\n * superclass constructor can be done with the special string\n * 'constructor'.\n * @param {...*} var_args The arguments to pass to superclass\n * method/constructor.\n * @return {*} The return value of the superclass method/constructor.\n */\n childCtor.base = function(me, methodName, var_args) {\n // Copying using loop to avoid deop due to passing arguments object to\n // function. This is faster in many JS engines as of late 2014.\n var args = new Array(arguments.length - 2);\n for (var i = 2; i < arguments.length; i++) {\n args[i - 2] = arguments[i];\n }\n return parentCtor.prototype[methodName].apply(me, args);\n };\n};\n\n\n/**\n * Allow for aliasing within scope functions. This function exists for\n * uncompiled code - in compiled code the calls will be inlined and the aliases\n * applied. In uncompiled code the function is simply run since the aliases as\n * written are valid JavaScript.\n *\n *\n * @param {function()} fn Function to call. This function can contain aliases\n * to namespaces (e.g. \"var dom = goog.dom\") or classes\n * (e.g. \"var Timer = goog.Timer\").\n * @deprecated Use goog.module instead.\n */\ngoog.scope = function(fn) {\n if (goog.isInModuleLoader_()) {\n throw new Error('goog.scope is not supported within a module.');\n }\n fn.call(goog.global);\n};\n\n\n/*\n * To support uncompiled, strict mode bundles that use eval to divide source\n * like so:\n * eval('someSource;//# sourceUrl sourcefile.js');\n * We need to export the globally defined symbols \"goog\" and \"COMPILED\".\n * Exporting \"goog\" breaks the compiler optimizations, so we required that\n * be defined externally.\n * NOTE: We don't use goog.exportSymbol here because we don't want to trigger\n * extern generation when that compiler option is enabled.\n */\nif (!COMPILED) {\n goog.global['COMPILED'] = COMPILED;\n}\n\n\n//==============================================================================\n// goog.defineClass implementation\n//==============================================================================\n\n\n/**\n * Creates a restricted form of a Closure \"class\":\n * - from the compiler's perspective, the instance returned from the\n * constructor is sealed (no new properties may be added). This enables\n * better checks.\n * - the compiler will rewrite this definition to a form that is optimal\n * for type checking and optimization (initially this will be a more\n * traditional form).\n *\n * @param {Function} superClass The superclass, Object or null.\n * @param {goog.defineClass.ClassDescriptor} def\n * An object literal describing\n * the class. It may have the following properties:\n * \"constructor\": the constructor function\n * \"statics\": an object literal containing methods to add to the constructor\n * as \"static\" methods or a function that will receive the constructor\n * function as its only parameter to which static properties can\n * be added.\n * all other properties are added to the prototype.\n * @return {!Function} The class constructor.\n * @deprecated Use ECMAScript class syntax instead.\n */\ngoog.defineClass = function(superClass, def) {\n // TODO(johnlenz): consider making the superClass an optional parameter.\n var constructor = def.constructor;\n var statics = def.statics;\n // Wrap the constructor prior to setting up the prototype and static methods.\n if (!constructor || constructor == Object.prototype.constructor) {\n constructor = function() {\n throw new Error(\n 'cannot instantiate an interface (no constructor defined).');\n };\n }\n\n var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);\n if (superClass) {\n goog.inherits(cls, superClass);\n }\n\n // Remove all the properties that should not be copied to the prototype.\n delete def.constructor;\n delete def.statics;\n\n goog.defineClass.applyProperties_(cls.prototype, def);\n if (statics != null) {\n if (statics instanceof Function) {\n statics(cls);\n } else {\n goog.defineClass.applyProperties_(cls, statics);\n }\n }\n\n return cls;\n};\n\n\n/**\n * @typedef {{\n * constructor: (!Function|undefined),\n * statics: (Object|undefined|function(Function):void)\n * }}\n */\ngoog.defineClass.ClassDescriptor;\n\n\n/**\n * @define {boolean} Whether the instances returned by goog.defineClass should\n * be sealed when possible.\n *\n * When sealing is disabled the constructor function will not be wrapped by\n * goog.defineClass, making it incompatible with ES6 class methods.\n */\ngoog.defineClass.SEAL_CLASS_INSTANCES =\n goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);\n\n\n/**\n * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is\n * defined, this function will wrap the constructor in a function that seals the\n * results of the provided constructor function.\n *\n * @param {!Function} ctr The constructor whose results maybe be sealed.\n * @param {Function} superClass The superclass constructor.\n * @return {!Function} The replacement constructor.\n * @private\n */\ngoog.defineClass.createSealingConstructor_ = function(ctr, superClass) {\n if (!goog.defineClass.SEAL_CLASS_INSTANCES) {\n // Do now wrap the constructor when sealing is disabled. Angular code\n // depends on this for injection to work properly.\n return ctr;\n }\n\n // NOTE: The sealing behavior has been removed\n\n /**\n * @this {Object}\n * @return {?}\n */\n var wrappedCtr = function() {\n // Don't seal an instance of a subclass when it calls the constructor of\n // its super class as there is most likely still setup to do.\n var instance = ctr.apply(this, arguments) || this;\n instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];\n\n return instance;\n };\n\n return wrappedCtr;\n};\n\n\n\n// TODO(johnlenz): share these values with the goog.object\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {!Array<string>}\n * @private\n * @const\n */\ngoog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [\n 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\n 'toLocaleString', 'toString', 'valueOf'\n];\n\n\n// TODO(johnlenz): share this function with the goog.object\n/**\n * @param {!Object} target The object to add properties to.\n * @param {!Object} source The object to copy properties from.\n * @private\n */\ngoog.defineClass.applyProperties_ = function(target, source) {\n // TODO(johnlenz): update this to support ES5 getters/setters\n\n var key;\n for (key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n\n // For IE the for-in-loop does not contain any properties that are not\n // enumerable on the prototype object (for example isPrototypeOf from\n // Object.prototype) and it will also not include 'replace' on objects that\n // extend String and change 'replace' (not that it is common for anyone to\n // extend anything except Object).\n for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {\n key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n};\n\n/**\n * Returns the parameter.\n * @param {string} s\n * @return {string}\n * @private\n */\ngoog.identity_ = function(s) {\n return s;\n};\n\n\n/**\n * Creates Trusted Types policy if Trusted Types are supported by the browser.\n * The policy just blesses any string as a Trusted Type. It is not visibility\n * restricted because anyone can also call trustedTypes.createPolicy directly.\n * However, the allowed names should be restricted by a HTTP header and the\n * reference to the created policy should be visibility restricted.\n * @param {string} name\n * @return {?TrustedTypePolicy}\n */\ngoog.createTrustedTypesPolicy = function(name) {\n var policy = null;\n var policyFactory = goog.global.trustedTypes;\n if (!policyFactory || !policyFactory.createPolicy) {\n return policy;\n }\n // trustedTypes.createPolicy throws if called with a name that is already\n // registered, even in report-only mode. Until the API changes, catch the\n // error not to break the applications functionally. In such case, the code\n // will fall back to using regular Safe Types.\n // TODO(koto): Remove catching once createPolicy API stops throwing.\n try {\n policy = policyFactory.createPolicy(name, {\n createHTML: goog.identity_,\n createScript: goog.identity_,\n createScriptURL: goog.identity_\n });\n } catch (e) {\n goog.logToConsole_(e.message);\n }\n return policy;\n};\n\n// There's a bug in the compiler where without collapse properties the\n// Closure namespace defines do not guard code correctly. To help reduce code\n// size also check for !COMPILED even though it redundant until this is fixed.\nif (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n\n\n /**\n * Tries to detect whether the current browser is Edge, based on the user\n * agent. This matches only pre-Chromium Edge.\n * @see https://docs.microsoft.com/en-us/microsoft-edge/web-platform/user-agent-string\n * @return {boolean} True if the current browser is Edge.\n * @private\n */\n goog.isEdge_ = function() {\n var userAgent = goog.global.navigator && goog.global.navigator.userAgent ?\n goog.global.navigator.userAgent :\n '';\n var edgeRe = /Edge\\/(\\d+)(\\.\\d)*/i;\n return !!userAgent.match(edgeRe);\n };\n\n\n /**\n * Tries to detect whether is in the context of an HTML document.\n * @return {boolean} True if it looks like HTML document.\n * @private\n */\n goog.inHtmlDocument_ = function() {\n /** @type {!Document} */\n var doc = goog.global.document;\n return doc != null && 'write' in doc; // XULDocument misses write.\n };\n\n\n /**\n * We'd like to check for if the document readyState is 'loading'; however\n * there are bugs on IE 10 and below where the readyState being anything other\n * than 'complete' is not reliable.\n * @return {boolean}\n * @private\n */\n goog.isDocumentLoading_ = function() {\n // attachEvent is available on IE 6 thru 10 only, and thus can be used to\n // detect those browsers.\n /** @type {!HTMLDocument} */\n var doc = goog.global.document;\n return doc.attachEvent ? doc.readyState != 'complete' :\n doc.readyState == 'loading';\n };\n\n\n /**\n * Tries to detect the base path of base.js script that bootstraps Closure.\n * @private\n */\n goog.findBasePath_ = function() {\n if (goog.global.CLOSURE_BASE_PATH != undefined &&\n // Anti DOM-clobbering runtime check (b/37736576).\n typeof goog.global.CLOSURE_BASE_PATH === 'string') {\n goog.basePath = goog.global.CLOSURE_BASE_PATH;\n return;\n } else if (!goog.inHtmlDocument_()) {\n return;\n }\n /** @type {!Document} */\n var doc = goog.global.document;\n // If we have a currentScript available, use it exclusively.\n var currentScript = doc.currentScript;\n if (currentScript) {\n var scripts = [currentScript];\n } else {\n var scripts = doc.getElementsByTagName('SCRIPT');\n }\n // Search backwards since the current script is in almost all cases the one\n // that has base.js.\n for (var i = scripts.length - 1; i >= 0; --i) {\n var script = /** @type {!HTMLScriptElement} */ (scripts[i]);\n var src = script.src;\n var qmark = src.lastIndexOf('?');\n var l = qmark == -1 ? src.length : qmark;\n if (src.slice(l - 7, l) == 'base.js') {\n goog.basePath = src.slice(0, l - 7);\n return;\n }\n }\n };\n\n goog.findBasePath_();\n\n /**\n * Rewrites closing script tags in input to avoid ending an enclosing script\n * tag.\n *\n * @param {string} str\n * @return {string}\n * @private\n */\n goog.protectScriptTag_ = function(str) {\n return str.replace(/<\\/(SCRIPT)/ig, '\\\\x3c/$1');\n };\n\n\n /**\n * A debug loader is responsible for downloading and executing javascript\n * files in an unbundled, uncompiled environment.\n *\n * This can be custimized via the setDependencyFactory method, or by\n * CLOSURE_IMPORT_SCRIPT/CLOSURE_LOAD_FILE_SYNC.\n *\n * @struct @constructor @final @private\n */\n goog.DebugLoader_ = function() {\n /** @private @const {!Object<string, !goog.Dependency>} */\n this.dependencies_ = {};\n /** @private @const {!Object<string, string>} */\n this.idToPath_ = {};\n /** @private @const {!Object<string, boolean>} */\n this.written_ = {};\n /** @private @const {!Array<!goog.Dependency>} */\n this.loadingDeps_ = [];\n /** @private {!Array<!goog.Dependency>} */\n this.depsToLoad_ = [];\n /** @private {boolean} */\n this.paused_ = false;\n /** @private {!goog.DependencyFactory} */\n this.factory_ = new goog.DependencyFactory();\n /** @private @const {!Object<string, !Function>} */\n this.deferredCallbacks_ = {};\n /** @private @const {!Array<string>} */\n this.deferredQueue_ = [];\n };\n\n /**\n * @param {!Array<string>} namespaces\n * @param {function(): undefined} callback Function to call once all the\n * namespaces have loaded.\n */\n goog.DebugLoader_.prototype.bootstrap = function(namespaces, callback) {\n var cb = callback;\n function resolve() {\n if (cb) {\n goog.global.setTimeout(cb, 0);\n cb = null;\n }\n }\n\n if (!namespaces.length) {\n resolve();\n return;\n }\n\n var deps = [];\n for (var i = 0; i < namespaces.length; i++) {\n var path = this.getPathFromDeps_(namespaces[i]);\n if (!path) {\n throw new Error('Unregonized namespace: ' + namespaces[i]);\n }\n deps.push(this.dependencies_[path]);\n }\n\n var require = goog.require;\n var loaded = 0;\n for (var i = 0; i < namespaces.length; i++) {\n require(namespaces[i]);\n deps[i].onLoad(function() {\n if (++loaded == namespaces.length) {\n resolve();\n }\n });\n }\n };\n\n\n /**\n * Loads the Closure Dependency file.\n *\n * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n * loaded, setDependencyFactory called, and then this called. i.e. allows\n * custom loading of the deps file.\n */\n goog.DebugLoader_.prototype.loadClosureDeps = function() {\n // Circumvent addDependency, which would try to transpile deps.js if\n // transpile is set to always.\n var relPath = 'deps.js';\n this.depsToLoad_.push(this.factory_.createDependency(\n goog.normalizePath_(goog.basePath + relPath), relPath, [], [], {}));\n this.loadDeps_();\n };\n\n\n /**\n * Notifies the debug loader when a dependency has been requested.\n *\n * @param {string} absPathOrId Path of the dependency or goog id.\n * @param {boolean=} opt_force\n */\n goog.DebugLoader_.prototype.requested = function(absPathOrId, opt_force) {\n var path = this.getPathFromDeps_(absPathOrId);\n if (path &&\n (opt_force || this.areDepsLoaded_(this.dependencies_[path].requires))) {\n var callback = this.deferredCallbacks_[path];\n if (callback) {\n delete this.deferredCallbacks_[path];\n callback();\n }\n }\n };\n\n\n /**\n * Sets the dependency factory, which can be used to create custom\n * goog.Dependency implementations to control how dependencies are loaded.\n *\n * @param {!goog.DependencyFactory} factory\n */\n goog.DebugLoader_.prototype.setDependencyFactory = function(factory) {\n this.factory_ = factory;\n };\n\n\n /**\n * Travserses the dependency graph and queues the given dependency, and all of\n * its transitive dependencies, for loading and then starts loading if not\n * paused.\n *\n * @param {string} namespace\n * @private\n */\n goog.DebugLoader_.prototype.load_ = function(namespace) {\n if (!this.getPathFromDeps_(namespace)) {\n var errorMessage = 'goog.require could not find: ' + namespace;\n goog.logToConsole_(errorMessage);\n } else {\n var loader = this;\n\n var deps = [];\n\n /** @param {string} namespace */\n var visit = function(namespace) {\n var path = loader.getPathFromDeps_(namespace);\n\n if (!path) {\n throw new Error('Bad dependency path or symbol: ' + namespace);\n }\n\n if (loader.written_[path]) {\n return;\n }\n\n loader.written_[path] = true;\n\n var dep = loader.dependencies_[path];\n for (var i = 0; i < dep.requires.length; i++) {\n if (!goog.isProvided_(dep.requires[i])) {\n visit(dep.requires[i]);\n }\n }\n\n deps.push(dep);\n };\n\n visit(namespace);\n\n var wasLoading = !!this.depsToLoad_.length;\n this.depsToLoad_ = this.depsToLoad_.concat(deps);\n\n if (!this.paused_ && !wasLoading) {\n this.loadDeps_();\n }\n }\n };\n\n\n /**\n * Loads any queued dependencies until they are all loaded or paused.\n *\n * @private\n */\n goog.DebugLoader_.prototype.loadDeps_ = function() {\n var loader = this;\n var paused = this.paused_;\n\n while (this.depsToLoad_.length && !paused) {\n (function() {\n var loadCallDone = false;\n var dep = loader.depsToLoad_.shift();\n\n var loaded = false;\n loader.loading_(dep);\n\n var controller = {\n pause: function() {\n if (loadCallDone) {\n throw new Error('Cannot call pause after the call to load.');\n } else {\n paused = true;\n }\n },\n resume: function() {\n if (loadCallDone) {\n loader.resume_();\n } else {\n // Some dep called pause and then resume in the same load call.\n // Just keep running this same loop.\n paused = false;\n }\n },\n loaded: function() {\n if (loaded) {\n throw new Error('Double call to loaded.');\n }\n\n loaded = true;\n loader.loaded_(dep);\n },\n pending: function() {\n // Defensive copy.\n var pending = [];\n for (var i = 0; i < loader.loadingDeps_.length; i++) {\n pending.push(loader.loadingDeps_[i]);\n }\n return pending;\n },\n /**\n * @param {goog.ModuleType} type\n */\n setModuleState: function(type) {\n goog.moduleLoaderState_ = {\n type: type,\n moduleName: '',\n declareLegacyNamespace: false\n };\n },\n /** @type {function(string, string, string=)} */\n registerEs6ModuleExports: function(\n path, exports, opt_closureNamespace) {\n if (opt_closureNamespace) {\n goog.loadedModules_[opt_closureNamespace] = {\n exports: exports,\n type: goog.ModuleType.ES6,\n moduleId: opt_closureNamespace || ''\n };\n }\n },\n /** @type {function(string, ?)} */\n registerGoogModuleExports: function(moduleId, exports) {\n goog.loadedModules_[moduleId] = {\n exports: exports,\n type: goog.ModuleType.GOOG,\n moduleId: moduleId\n };\n },\n clearModuleState: function() {\n goog.moduleLoaderState_ = null;\n },\n defer: function(callback) {\n if (loadCallDone) {\n throw new Error(\n 'Cannot register with defer after the call to load.');\n }\n loader.defer_(dep, callback);\n },\n areDepsLoaded: function() {\n return loader.areDepsLoaded_(dep.requires);\n }\n };\n\n try {\n dep.load(controller);\n } finally {\n loadCallDone = true;\n }\n })();\n }\n\n if (paused) {\n this.pause_();\n }\n };\n\n\n /** @private */\n goog.DebugLoader_.prototype.pause_ = function() {\n this.paused_ = true;\n };\n\n\n /** @private */\n goog.DebugLoader_.prototype.resume_ = function() {\n if (this.paused_) {\n this.paused_ = false;\n this.loadDeps_();\n }\n };\n\n\n /**\n * Marks the given dependency as loading (load has been called but it has not\n * yet marked itself as finished). Useful for dependencies that want to know\n * what else is loading. Example: goog.modules cannot eval if there are\n * loading dependencies.\n *\n * @param {!goog.Dependency} dep\n * @private\n */\n goog.DebugLoader_.prototype.loading_ = function(dep) {\n this.loadingDeps_.push(dep);\n };\n\n\n /**\n * Marks the given dependency as having finished loading and being available\n * for require.\n *\n * @param {!goog.Dependency} dep\n * @private\n */\n goog.DebugLoader_.prototype.loaded_ = function(dep) {\n for (var i = 0; i < this.loadingDeps_.length; i++) {\n if (this.loadingDeps_[i] == dep) {\n this.loadingDeps_.splice(i, 1);\n break;\n }\n }\n\n for (var i = 0; i < this.deferredQueue_.length; i++) {\n if (this.deferredQueue_[i] == dep.path) {\n this.deferredQueue_.splice(i, 1);\n break;\n }\n }\n\n if (this.loadingDeps_.length == this.deferredQueue_.length &&\n !this.depsToLoad_.length) {\n // Something has asked to load these, but they may not be directly\n // required again later, so load them now that we know we're done loading\n // everything else. e.g. a goog module entry point.\n while (this.deferredQueue_.length) {\n this.requested(this.deferredQueue_.shift(), true);\n }\n }\n\n dep.loaded();\n };\n\n\n /**\n * @param {!Array<string>} pathsOrIds\n * @return {boolean}\n * @private\n */\n goog.DebugLoader_.prototype.areDepsLoaded_ = function(pathsOrIds) {\n for (var i = 0; i < pathsOrIds.length; i++) {\n var path = this.getPathFromDeps_(pathsOrIds[i]);\n if (!path ||\n (!(path in this.deferredCallbacks_) &&\n !goog.isProvided_(pathsOrIds[i]))) {\n return false;\n }\n }\n\n return true;\n };\n\n\n /**\n * @param {string} absPathOrId\n * @return {?string}\n * @private\n */\n goog.DebugLoader_.prototype.getPathFromDeps_ = function(absPathOrId) {\n if (absPathOrId in this.idToPath_) {\n return this.idToPath_[absPathOrId];\n } else if (absPathOrId in this.dependencies_) {\n return absPathOrId;\n } else {\n return null;\n }\n };\n\n\n /**\n * @param {!goog.Dependency} dependency\n * @param {!Function} callback\n * @private\n */\n goog.DebugLoader_.prototype.defer_ = function(dependency, callback) {\n this.deferredCallbacks_[dependency.path] = callback;\n this.deferredQueue_.push(dependency.path);\n };\n\n\n /**\n * Interface for goog.Dependency implementations to have some control over\n * loading of dependencies.\n *\n * @record\n */\n goog.LoadController = function() {};\n\n\n /**\n * Tells the controller to halt loading of more dependencies.\n */\n goog.LoadController.prototype.pause = function() {};\n\n\n /**\n * Tells the controller to resume loading of more dependencies if paused.\n */\n goog.LoadController.prototype.resume = function() {};\n\n\n /**\n * Tells the controller that this dependency has finished loading.\n *\n * This causes this to be removed from pending() and any load callbacks to\n * fire.\n */\n goog.LoadController.prototype.loaded = function() {};\n\n\n /**\n * List of dependencies on which load has been called but which have not\n * called loaded on their controller. This includes the current dependency.\n *\n * @return {!Array<!goog.Dependency>}\n */\n goog.LoadController.prototype.pending = function() {};\n\n\n /**\n * Registers an object as an ES6 module's exports so that goog.modules may\n * require it by path.\n *\n * @param {string} path Full path of the module.\n * @param {?} exports\n * @param {string=} opt_closureNamespace Closure namespace to associate with\n * this module.\n */\n goog.LoadController.prototype.registerEs6ModuleExports = function(\n path, exports, opt_closureNamespace) {};\n\n\n /**\n * Sets the current module state.\n *\n * @param {goog.ModuleType} type Type of module.\n */\n goog.LoadController.prototype.setModuleState = function(type) {};\n\n\n /**\n * Clears the current module state.\n */\n goog.LoadController.prototype.clearModuleState = function() {};\n\n\n /**\n * Registers a callback to call once the dependency is actually requested\n * via goog.require + all of the immediate dependencies have been loaded or\n * all other files have been loaded. Allows for lazy loading until\n * require'd without pausing dependency loading, which is needed on old IE.\n *\n * @param {!Function} callback\n */\n goog.LoadController.prototype.defer = function(callback) {};\n\n\n /**\n * @return {boolean}\n */\n goog.LoadController.prototype.areDepsLoaded = function() {};\n\n\n /**\n * Basic super class for all dependencies Closure Library can load.\n *\n * This default implementation is designed to load untranspiled, non-module\n * scripts in a web broswer.\n *\n * For goog.modules see {@see goog.GoogModuleDependency}.\n * For untranspiled ES6 modules {@see goog.Es6ModuleDependency}.\n *\n * @param {string} path Absolute path of this script.\n * @param {string} relativePath Path of this script relative to goog.basePath.\n * @param {!Array<string>} provides goog.provided or goog.module symbols\n * in this file.\n * @param {!Array<string>} requires goog symbols or relative paths to Closure\n * this depends on.\n * @param {!Object<string, string>} loadFlags\n * @struct @constructor\n */\n goog.Dependency = function(\n path, relativePath, provides, requires, loadFlags) {\n /** @const */\n this.path = path;\n /** @const */\n this.relativePath = relativePath;\n /** @const */\n this.provides = provides;\n /** @const */\n this.requires = requires;\n /** @const */\n this.loadFlags = loadFlags;\n /** @private {boolean} */\n this.loaded_ = false;\n /** @private {!Array<function()>} */\n this.loadCallbacks_ = [];\n };\n\n\n /**\n * @return {string} The pathname part of this dependency's path if it is a\n * URI.\n */\n goog.Dependency.prototype.getPathName = function() {\n var pathName = this.path;\n var protocolIndex = pathName.indexOf('://');\n if (protocolIndex >= 0) {\n pathName = pathName.substring(protocolIndex + 3);\n var slashIndex = pathName.indexOf('/');\n if (slashIndex >= 0) {\n pathName = pathName.substring(slashIndex + 1);\n }\n }\n return pathName;\n };\n\n\n /**\n * @param {function()} callback Callback to fire as soon as this has loaded.\n * @final\n */\n goog.Dependency.prototype.onLoad = function(callback) {\n if (this.loaded_) {\n callback();\n } else {\n this.loadCallbacks_.push(callback);\n }\n };\n\n\n /**\n * Marks this dependency as loaded and fires any callbacks registered with\n * onLoad.\n * @final\n */\n goog.Dependency.prototype.loaded = function() {\n this.loaded_ = true;\n var callbacks = this.loadCallbacks_;\n this.loadCallbacks_ = [];\n for (var i = 0; i < callbacks.length; i++) {\n callbacks[i]();\n }\n };\n\n\n /**\n * Whether or not document.written / appended script tags should be deferred.\n *\n * @private {boolean}\n */\n goog.Dependency.defer_ = false;\n\n\n /**\n * Map of script ready / state change callbacks. Old IE cannot handle putting\n * these properties on goog.global.\n *\n * @private @const {!Object<string, function(?):undefined>}\n */\n goog.Dependency.callbackMap_ = {};\n\n\n /**\n * @param {function(...?):?} callback\n * @return {string}\n * @private\n */\n goog.Dependency.registerCallback_ = function(callback) {\n var key = Math.random().toString(32);\n goog.Dependency.callbackMap_[key] = callback;\n return key;\n };\n\n\n /**\n * @param {string} key\n * @private\n */\n goog.Dependency.unregisterCallback_ = function(key) {\n delete goog.Dependency.callbackMap_[key];\n };\n\n\n /**\n * @param {string} key\n * @param {...?} var_args\n * @private\n * @suppress {unusedPrivateMembers}\n */\n goog.Dependency.callback_ = function(key, var_args) {\n if (key in goog.Dependency.callbackMap_) {\n var callback = goog.Dependency.callbackMap_[key];\n var args = [];\n for (var i = 1; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n callback.apply(undefined, args);\n } else {\n var errorMessage = 'Callback key ' + key +\n ' does not exist (was base.js loaded more than once?).';\n throw Error(errorMessage);\n }\n };\n\n\n /**\n * Starts loading this dependency. This dependency can pause loading if it\n * needs to and resume it later via the controller interface.\n *\n * When this is loaded it should call controller.loaded(). Note that this will\n * end up calling the loaded method of this dependency; there is no need to\n * call it explicitly.\n *\n * @param {!goog.LoadController} controller\n */\n goog.Dependency.prototype.load = function(controller) {\n if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n controller.loaded();\n } else {\n controller.pause();\n }\n return;\n }\n\n if (!goog.inHtmlDocument_()) {\n goog.logToConsole_(\n 'Cannot use default debug loader outside of HTML documents.');\n if (this.relativePath == 'deps.js') {\n // Some old code is relying on base.js auto loading deps.js failing with\n // no error before later setting CLOSURE_IMPORT_SCRIPT.\n // CLOSURE_IMPORT_SCRIPT should be set *before* base.js is loaded, or\n // CLOSURE_NO_DEPS set to true.\n goog.logToConsole_(\n 'Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, ' +\n 'or setting CLOSURE_NO_DEPS to true.');\n controller.loaded();\n } else {\n controller.pause();\n }\n return;\n }\n\n /** @type {!HTMLDocument} */\n var doc = goog.global.document;\n\n // If the user tries to require a new symbol after document load,\n // something has gone terribly wrong. Doing a document.write would\n // wipe out the page. This does not apply to the CSP-compliant method\n // of writing script tags.\n if (doc.readyState == 'complete' &&\n !goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {\n // Certain test frameworks load base.js multiple times, which tries\n // to write deps.js each time. If that happens, just fail silently.\n // These frameworks wipe the page between each load of base.js, so this\n // is OK.\n var isDeps = /\\bdeps.js$/.test(this.path);\n if (isDeps) {\n controller.loaded();\n return;\n } else {\n throw Error('Cannot write \"' + this.path + '\" after document load');\n }\n }\n\n var nonce = goog.getScriptNonce_();\n if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&\n goog.isDocumentLoading_()) {\n var key;\n var callback = function(script) {\n if (script.readyState && script.readyState != 'complete') {\n script.onload = callback;\n return;\n }\n goog.Dependency.unregisterCallback_(key);\n controller.loaded();\n };\n key = goog.Dependency.registerCallback_(callback);\n\n var defer = goog.Dependency.defer_ ? ' defer' : '';\n var nonceAttr = nonce ? ' nonce=\"' + nonce + '\"' : '';\n var script = '<script src=\"' + this.path + '\"' + nonceAttr + defer +\n ' id=\"script-' + key + '\"><\\/script>';\n\n script += '<script' + nonceAttr + '>';\n\n if (goog.Dependency.defer_) {\n script += 'document.getElementById(\\'script-' + key +\n '\\').onload = function() {\\n' +\n ' goog.Dependency.callback_(\\'' + key + '\\', this);\\n' +\n '};\\n';\n } else {\n script += 'goog.Dependency.callback_(\\'' + key +\n '\\', document.getElementById(\\'script-' + key + '\\'));';\n }\n\n script += '<\\/script>';\n\n doc.write(\n goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n script);\n } else {\n var scriptEl =\n /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n scriptEl.defer = goog.Dependency.defer_;\n scriptEl.async = false;\n\n // If CSP nonces are used, propagate them to dynamically created scripts.\n // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n if (nonce) {\n scriptEl.nonce = nonce;\n }\n\n scriptEl.onload = function() {\n scriptEl.onload = null;\n controller.loaded();\n };\n\n scriptEl.src = goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createScriptURL(this.path) :\n this.path;\n doc.head.appendChild(scriptEl);\n }\n };\n\n\n /**\n * @param {string} path Absolute path of this script.\n * @param {string} relativePath Path of this script relative to goog.basePath.\n * @param {!Array<string>} provides Should be an empty array.\n * TODO(johnplaisted) add support for adding closure namespaces to ES6\n * modules for interop purposes.\n * @param {!Array<string>} requires goog symbols or relative paths to Closure\n * this depends on.\n * @param {!Object<string, string>} loadFlags\n * @struct @constructor\n * @extends {goog.Dependency}\n */\n goog.Es6ModuleDependency = function(\n path, relativePath, provides, requires, loadFlags) {\n goog.Es6ModuleDependency.base(\n this, 'constructor', path, relativePath, provides, requires, loadFlags);\n };\n goog.inherits(goog.Es6ModuleDependency, goog.Dependency);\n\n\n /**\n * @override\n * @param {!goog.LoadController} controller\n */\n goog.Es6ModuleDependency.prototype.load = function(controller) {\n if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n controller.loaded();\n } else {\n controller.pause();\n }\n return;\n }\n\n if (!goog.inHtmlDocument_()) {\n goog.logToConsole_(\n 'Cannot use default debug loader outside of HTML documents.');\n controller.pause();\n return;\n }\n\n /** @type {!HTMLDocument} */\n var doc = goog.global.document;\n\n var dep = this;\n\n // TODO(johnplaisted): Does document.writing really speed up anything? Any\n // difference between this and just waiting for interactive mode and then\n // appending?\n function write(src, contents) {\n var nonceAttr = '';\n var nonce = goog.getScriptNonce_();\n if (nonce) {\n nonceAttr = ' nonce=\"' + nonce + '\"';\n }\n\n if (contents) {\n var script = '<script type=\"module\" crossorigin' + nonceAttr + '>' +\n contents + '</' +\n 'script>';\n doc.write(\n goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n script);\n } else {\n var script = '<script type=\"module\" crossorigin src=\"' + src + '\"' +\n nonceAttr + '></' +\n 'script>';\n doc.write(\n goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n script);\n }\n }\n\n function append(src, contents) {\n var scriptEl =\n /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n scriptEl.defer = true;\n scriptEl.async = false;\n scriptEl.type = 'module';\n scriptEl.setAttribute('crossorigin', true);\n\n // If CSP nonces are used, propagate them to dynamically created scripts.\n // This is necessary to allow nonce-based CSPs without 'strict-dynamic'.\n var nonce = goog.getScriptNonce_();\n if (nonce) {\n scriptEl.nonce = nonce;\n }\n\n if (contents) {\n scriptEl.text = goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createScript(contents) :\n contents;\n } else {\n scriptEl.src = goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createScriptURL(src) :\n src;\n }\n\n doc.head.appendChild(scriptEl);\n }\n\n var create;\n\n if (goog.isDocumentLoading_()) {\n create = write;\n // We can ONLY call document.write if we are guaranteed that any\n // non-module script tags document.written after this are deferred.\n // Small optimization, in theory document.writing is faster.\n goog.Dependency.defer_ = true;\n } else {\n create = append;\n }\n\n // Write 4 separate tags here:\n // 1) Sets the module state at the correct time (just before execution).\n // 2) A src node for this, which just hopefully lets the browser load it a\n // little early (no need to parse #3).\n // 3) Import the module and register it.\n // 4) Clear the module state at the correct time. Guaranteed to run even\n // if there is an error in the module (#3 will not run if there is an\n // error in the module).\n var beforeKey = goog.Dependency.registerCallback_(function() {\n goog.Dependency.unregisterCallback_(beforeKey);\n controller.setModuleState(goog.ModuleType.ES6);\n });\n create(undefined, 'goog.Dependency.callback_(\"' + beforeKey + '\")');\n\n // TODO(johnplaisted): Does this really speed up anything?\n create(this.path, undefined);\n\n var registerKey = goog.Dependency.registerCallback_(function(exports) {\n goog.Dependency.unregisterCallback_(registerKey);\n controller.registerEs6ModuleExports(\n dep.path, exports, goog.moduleLoaderState_.moduleName);\n });\n create(\n undefined,\n 'import * as m from \"' + this.path + '\"; goog.Dependency.callback_(\"' +\n registerKey + '\", m)');\n\n var afterKey = goog.Dependency.registerCallback_(function() {\n goog.Dependency.unregisterCallback_(afterKey);\n controller.clearModuleState();\n controller.loaded();\n });\n create(undefined, 'goog.Dependency.callback_(\"' + afterKey + '\")');\n };\n\n\n /**\n * Superclass of any dependency that needs to be loaded into memory,\n * transformed, and then eval'd (goog.modules and transpiled files).\n *\n * @param {string} path Absolute path of this script.\n * @param {string} relativePath Path of this script relative to goog.basePath.\n * @param {!Array<string>} provides goog.provided or goog.module symbols\n * in this file.\n * @param {!Array<string>} requires goog symbols or relative paths to Closure\n * this depends on.\n * @param {!Object<string, string>} loadFlags\n * @struct @constructor @abstract\n * @extends {goog.Dependency}\n */\n goog.TransformedDependency = function(\n path, relativePath, provides, requires, loadFlags) {\n goog.TransformedDependency.base(\n this, 'constructor', path, relativePath, provides, requires, loadFlags);\n /** @private {?string} */\n this.contents_ = null;\n\n /**\n * Whether to lazily make the synchronous XHR (when goog.require'd) or make\n * the synchronous XHR when initially loading. On FireFox 61 there is a bug\n * where an ES6 module cannot make a synchronous XHR (rather, it can, but if\n * it does then no other ES6 modules will load after).\n *\n * tl;dr we lazy load due to bugs on older browsers and eager load due to\n * bugs on newer ones.\n *\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1477090\n *\n * @private @const {boolean}\n */\n this.lazyFetch_ = !goog.inHtmlDocument_() ||\n !('noModule' in goog.global.document.createElement('script'));\n };\n goog.inherits(goog.TransformedDependency, goog.Dependency);\n\n\n /**\n * @override\n * @param {!goog.LoadController} controller\n */\n goog.TransformedDependency.prototype.load = function(controller) {\n var dep = this;\n\n function fetch() {\n dep.contents_ = goog.loadFileSync_(dep.path);\n\n if (dep.contents_) {\n dep.contents_ = dep.transform(dep.contents_);\n if (dep.contents_) {\n dep.contents_ += '\\n//# sourceURL=' + dep.path;\n }\n }\n }\n\n if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n fetch();\n if (this.contents_ &&\n goog.global.CLOSURE_IMPORT_SCRIPT('', this.contents_)) {\n this.contents_ = null;\n controller.loaded();\n } else {\n controller.pause();\n }\n return;\n }\n\n\n var isEs6 = this.loadFlags['module'] == goog.ModuleType.ES6;\n\n if (!this.lazyFetch_) {\n fetch();\n }\n\n function load() {\n if (dep.lazyFetch_) {\n fetch();\n }\n\n if (!dep.contents_) {\n // loadFileSync_ or transform are responsible. Assume they logged an\n // error.\n return;\n }\n\n if (isEs6) {\n controller.setModuleState(goog.ModuleType.ES6);\n }\n\n var namespace;\n\n try {\n var contents = dep.contents_;\n dep.contents_ = null;\n goog.globalEval(goog.CLOSURE_EVAL_PREFILTER_.createScript(contents));\n if (isEs6) {\n namespace = goog.moduleLoaderState_.moduleName;\n }\n } finally {\n if (isEs6) {\n controller.clearModuleState();\n }\n }\n\n if (isEs6) {\n // Due to circular dependencies this may not be available for require\n // right now.\n goog.global['$jscomp']['require']['ensure'](\n [dep.getPathName()], function() {\n controller.registerEs6ModuleExports(\n dep.path,\n goog.global['$jscomp']['require'](dep.getPathName()),\n namespace);\n });\n }\n\n controller.loaded();\n }\n\n // Do not fetch now; in FireFox 47 the synchronous XHR doesn't block all\n // events. If we fetched now and then document.write'd the contents the\n // document.write would be an eval and would execute too soon! Instead write\n // a script tag to fetch and eval synchronously at the correct time.\n function fetchInOwnScriptThenLoad() {\n /** @type {!HTMLDocument} */\n var doc = goog.global.document;\n\n var key = goog.Dependency.registerCallback_(function() {\n goog.Dependency.unregisterCallback_(key);\n load();\n });\n\n var nonce = goog.getScriptNonce_();\n var nonceAttr = nonce ? ' nonce=\"' + nonce + '\"' : '';\n var script = '<script' + nonceAttr + '>' +\n goog.protectScriptTag_('goog.Dependency.callback_(\"' + key + '\");') +\n '</' +\n 'script>';\n doc.write(\n goog.TRUSTED_TYPES_POLICY_ ?\n goog.TRUSTED_TYPES_POLICY_.createHTML(script) :\n script);\n }\n\n // If one thing is pending it is this.\n var anythingElsePending = controller.pending().length > 1;\n\n // Additionally if we are meant to defer scripts but the page is still\n // loading (e.g. an ES6 module is loading) then also defer. Or if we are\n // meant to defer and anything else is pending then defer (those may be\n // scripts that did not need transformation and are just script tags with\n // defer set to true, and we need to evaluate after that deferred script).\n var needsAsyncLoading = goog.Dependency.defer_ &&\n (anythingElsePending || goog.isDocumentLoading_());\n\n if (needsAsyncLoading) {\n // Note that we only defer when we have to rather than 100% of the time.\n // Always defering would work, but then in theory the order of\n // goog.require calls would then matter. We want to enforce that most of\n // the time the order of the require calls does not matter.\n controller.defer(function() {\n load();\n });\n return;\n }\n // TODO(johnplaisted): Externs are missing onreadystatechange for\n // HTMLDocument.\n /** @type {?} */\n var doc = goog.global.document;\n\n var isInternetExplorerOrEdge = goog.inHtmlDocument_() &&\n ('ActiveXObject' in goog.global || goog.isEdge_());\n\n // Don't delay in any version of IE or pre-Chromium Edge. There's a bug\n // around this that will cause out of order script execution. This means\n // that on older IE ES6 modules will load too early (while the document is\n // still loading + the dom is not available). The other option is to load\n // too late (when the document is complete and the onload even will never\n // fire). This seems to be the lesser of two evils as scripts already act\n // like the former.\n if (isEs6 && goog.inHtmlDocument_() && goog.isDocumentLoading_() &&\n !isInternetExplorerOrEdge) {\n goog.Dependency.defer_ = true;\n // Transpiled ES6 modules still need to load like regular ES6 modules,\n // aka only after the document is interactive.\n controller.pause();\n var oldCallback = doc.onreadystatechange;\n doc.onreadystatechange = function() {\n if (doc.readyState == 'interactive') {\n doc.onreadystatechange = oldCallback;\n load();\n controller.resume();\n }\n if (typeof oldCallback === 'function') {\n oldCallback.apply(undefined, arguments);\n }\n };\n } else {\n // Always eval on old IE.\n if (!goog.inHtmlDocument_() || !goog.isDocumentLoading_()) {\n load();\n } else {\n fetchInOwnScriptThenLoad();\n }\n }\n };\n\n\n /**\n * @param {string} contents\n * @return {string}\n * @abstract\n */\n goog.TransformedDependency.prototype.transform = function(contents) {};\n\n\n /**\n * An ES6 module dependency that was transpiled to a jscomp module outside\n * of the debug loader, e.g. server side.\n *\n * @param {string} path Absolute path of this script.\n * @param {string} relativePath Path of this script relative to goog.basePath.\n * @param {!Array<string>} provides goog.provided or goog.module symbols\n * in this file.\n * @param {!Array<string>} requires goog symbols or relative paths to Closure\n * this depends on.\n * @param {!Object<string, string>} loadFlags\n * @struct @constructor\n * @extends {goog.TransformedDependency}\n */\n goog.PreTranspiledEs6ModuleDependency = function(\n path, relativePath, provides, requires, loadFlags) {\n goog.PreTranspiledEs6ModuleDependency.base(\n this, 'constructor', path, relativePath, provides, requires, loadFlags);\n };\n goog.inherits(\n goog.PreTranspiledEs6ModuleDependency, goog.TransformedDependency);\n\n\n /**\n * @override\n * @param {string} contents\n * @return {string}\n */\n goog.PreTranspiledEs6ModuleDependency.prototype.transform = function(\n contents) {\n return contents;\n };\n\n\n /**\n * A goog.module, transpiled or not. Will always perform some minimal\n * transformation even when not transpiled to wrap in a goog.loadModule\n * statement.\n *\n * @param {string} path Absolute path of this script.\n * @param {string} relativePath Path of this script relative to goog.basePath.\n * @param {!Array<string>} provides goog.provided or goog.module symbols\n * in this file.\n * @param {!Array<string>} requires goog symbols or relative paths to Closure\n * this depends on.\n * @param {!Object<string, string>} loadFlags\n * @struct @constructor\n * @extends {goog.TransformedDependency}\n */\n goog.GoogModuleDependency = function(\n path, relativePath, provides, requires, loadFlags) {\n goog.GoogModuleDependency.base(\n this, 'constructor', path, relativePath, provides, requires, loadFlags);\n };\n goog.inherits(goog.GoogModuleDependency, goog.TransformedDependency);\n\n\n /**\n * @override\n * @param {string} contents\n * @return {string}\n */\n goog.GoogModuleDependency.prototype.transform = function(contents) {\n if (!goog.LOAD_MODULE_USING_EVAL || goog.global.JSON === undefined) {\n return '' +\n 'goog.loadModule(function(exports) {' +\n '\"use strict\";' + contents +\n '\\n' + // terminate any trailing single line comment.\n ';return exports' +\n '});' +\n '\\n//# sourceURL=' + this.path + '\\n';\n } else {\n return '' +\n 'goog.loadModule(' +\n goog.global.JSON.stringify(\n contents + '\\n//# sourceURL=' + this.path + '\\n') +\n ');';\n }\n };\n\n\n /**\n * @param {string} relPath\n * @param {!Array<string>|undefined} provides\n * @param {!Array<string>} requires\n * @param {boolean|!Object<string>=} opt_loadFlags\n * @see goog.addDependency\n */\n goog.DebugLoader_.prototype.addDependency = function(\n relPath, provides, requires, opt_loadFlags) {\n provides = provides || [];\n relPath = relPath.replace(/\\\\/g, '/');\n var path = goog.normalizePath_(goog.basePath + relPath);\n if (!opt_loadFlags || typeof opt_loadFlags === 'boolean') {\n opt_loadFlags = opt_loadFlags ? {'module': goog.ModuleType.GOOG} : {};\n }\n var dep = this.factory_.createDependency(\n path, relPath, provides, requires, opt_loadFlags);\n this.dependencies_[path] = dep;\n for (var i = 0; i < provides.length; i++) {\n this.idToPath_[provides[i]] = path;\n }\n this.idToPath_[relPath] = path;\n };\n\n\n /**\n * Creates goog.Dependency instances for the debug loader to load.\n *\n * Should be overridden to have the debug loader use custom subclasses of\n * goog.Dependency.\n *\n * @struct @constructor\n */\n goog.DependencyFactory = function() {};\n\n\n /**\n * @param {string} path Absolute path of the file.\n * @param {string} relativePath Path relative to closure’s base.js.\n * @param {!Array<string>} provides Array of provided goog.provide/module ids.\n * @param {!Array<string>} requires Array of required goog.provide/module /\n * relative ES6 module paths.\n * @param {!Object<string, string>} loadFlags\n * @return {!goog.Dependency}\n */\n goog.DependencyFactory.prototype.createDependency = function(\n path, relativePath, provides, requires, loadFlags) {\n\n if (loadFlags['module'] == goog.ModuleType.GOOG) {\n return new goog.GoogModuleDependency(\n path, relativePath, provides, requires, loadFlags);\n } else {\n if (loadFlags['module'] == goog.ModuleType.ES6) {\n if (goog.ASSUME_ES_MODULES_TRANSPILED) {\n return new goog.PreTranspiledEs6ModuleDependency(\n path, relativePath, provides, requires, loadFlags);\n } else {\n return new goog.Es6ModuleDependency(\n path, relativePath, provides, requires, loadFlags);\n }\n } else {\n return new goog.Dependency(\n path, relativePath, provides, requires, loadFlags);\n }\n }\n };\n\n\n /** @private @const */\n goog.debugLoader_ = new goog.DebugLoader_();\n\n\n /**\n * Loads the Closure Dependency file.\n *\n * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n * loaded, setDependencyFactory called, and then this called. i.e. allows\n * custom loading of the deps file.\n */\n goog.loadClosureDeps = function() {\n goog.debugLoader_.loadClosureDeps();\n };\n\n\n /**\n * Sets the dependency factory, which can be used to create custom\n * goog.Dependency implementations to control how dependencies are loaded.\n *\n * Note: if you wish to call this function and provide your own implemnetation\n * it is a wise idea to set CLOSURE_NO_DEPS to true, otherwise the dependency\n * file and all of its goog.addDependency calls will use the default factory.\n * You can call goog.loadClosureDeps to load the Closure dependency file\n * later, after your factory is injected.\n *\n * @param {!goog.DependencyFactory} factory\n */\n goog.setDependencyFactory = function(factory) {\n goog.debugLoader_.setDependencyFactory(factory);\n };\n\n\n /**\n * Trusted Types policy for the debug loader.\n * @private @const {?TrustedTypePolicy}\n */\n goog.TRUSTED_TYPES_POLICY_ = goog.TRUSTED_TYPES_POLICY_NAME ?\n goog.createTrustedTypesPolicy(goog.TRUSTED_TYPES_POLICY_NAME + '#base') :\n null;\n\n if (!goog.global.CLOSURE_NO_DEPS) {\n goog.debugLoader_.loadClosureDeps();\n }\n\n\n /**\n * Bootstraps the given namespaces and calls the callback once they are\n * available either via goog.require. This is a replacement for using\n * `goog.require` to bootstrap Closure JavaScript. Previously a `goog.require`\n * in an HTML file would guarantee that the require'd namespace was available\n * in the next immediate script tag. With ES6 modules this no longer a\n * guarantee.\n *\n * @param {!Array<string>} namespaces\n * @param {function(): ?} callback Function to call once all the namespaces\n * have loaded. Always called asynchronously.\n */\n goog.bootstrap = function(namespaces, callback) {\n goog.debugLoader_.bootstrap(namespaces, callback);\n };\n}\n\n\nif (!COMPILED) {\n var isChrome87 = false;\n // Cannot run check for Chrome <87 bug in case of strict CSP environments.\n // TODO(user): Remove once Chrome <87 bug is no longer a problem.\n try {\n isChrome87 = eval(goog.global.trustedTypes.emptyScript) !==\n goog.global.trustedTypes.emptyScript;\n } catch (err) {\n }\n\n /**\n * Trusted Types for running dev servers.\n *\n * @private @const\n */\n goog.CLOSURE_EVAL_PREFILTER_ =\n // Detect Chrome <87 bug with TT and eval.\n goog.global.trustedTypes && isChrome87 &&\n goog.createTrustedTypesPolicy('goog#base#devonly#eval') ||\n {createScript: goog.identity_};\n}\n",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements the disposable interface.\n */\n\ngoog.provide('goog.Disposable');\n\ngoog.require('goog.disposable.IDisposable');\ngoog.require('goog.dispose');\n/**\n * TODO(user): Remove this require.\n * @suppress {extraRequire}\n */\ngoog.require('goog.disposeAll');\n\n/**\n * Class that provides the basic implementation for disposable objects. If your\n * class holds references or resources that can't be collected by standard GC,\n * it should extend this class or implement the disposable interface (defined\n * in goog.disposable.IDisposable). See description of\n * goog.disposable.IDisposable for examples of cleanup.\n * @constructor\n * @implements {goog.disposable.IDisposable}\n */\ngoog.Disposable = function() {\n 'use strict';\n /**\n * If monitoring the goog.Disposable instances is enabled, stores the creation\n * stack trace of the Disposable instance.\n * @type {string|undefined}\n */\n this.creationStack;\n\n if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {\n if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {\n this.creationStack = new Error().stack;\n }\n goog.Disposable.instances_[goog.getUid(this)] = this;\n }\n // Support sealing\n this.disposed_ = this.disposed_;\n this.onDisposeCallbacks_ = this.onDisposeCallbacks_;\n};\n\n\n/**\n * @enum {number} Different monitoring modes for Disposable.\n */\ngoog.Disposable.MonitoringMode = {\n /**\n * No monitoring.\n */\n OFF: 0,\n /**\n * Creating and disposing the goog.Disposable instances is monitored. All\n * disposable objects need to call the `goog.Disposable` base\n * constructor. The PERMANENT mode must be switched on before creating any\n * goog.Disposable instances.\n */\n PERMANENT: 1,\n /**\n * INTERACTIVE mode can be switched on and off on the fly without producing\n * errors. It also doesn't warn if the disposable objects don't call the\n * `goog.Disposable` base constructor.\n */\n INTERACTIVE: 2\n};\n\n\n/**\n * @define {number} The monitoring mode of the goog.Disposable\n * instances. Default is OFF. Switching on the monitoring is only\n * recommended for debugging because it has a significant impact on\n * performance and memory usage. If switched off, the monitoring code\n * compiles down to 0 bytes.\n */\ngoog.Disposable.MONITORING_MODE =\n goog.define('goog.Disposable.MONITORING_MODE', 0);\n\n\n/**\n * @define {boolean} Whether to attach creation stack to each created disposable\n * instance; This is only relevant for when MonitoringMode != OFF.\n */\ngoog.Disposable.INCLUDE_STACK_ON_CREATION =\n goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);\n\n\n/**\n * Maps the unique ID of every undisposed `goog.Disposable` object to\n * the object itself.\n * @type {!Object<number, !goog.Disposable>}\n * @private\n */\ngoog.Disposable.instances_ = {};\n\n\n/**\n * @return {!Array<!goog.Disposable>} All `goog.Disposable` objects that\n * haven't been disposed of.\n */\ngoog.Disposable.getUndisposedObjects = function() {\n 'use strict';\n var ret = [];\n for (var id in goog.Disposable.instances_) {\n if (goog.Disposable.instances_.hasOwnProperty(id)) {\n ret.push(goog.Disposable.instances_[Number(id)]);\n }\n }\n return ret;\n};\n\n\n/**\n * Clears the registry of undisposed objects but doesn't dispose of them.\n */\ngoog.Disposable.clearUndisposedObjects = function() {\n 'use strict';\n goog.Disposable.instances_ = {};\n};\n\n\n/**\n * Whether the object has been disposed of.\n * @type {boolean}\n * @private\n */\ngoog.Disposable.prototype.disposed_ = false;\n\n\n/**\n * Callbacks to invoke when this object is disposed.\n * @type {Array<!Function>}\n * @private\n */\ngoog.Disposable.prototype.onDisposeCallbacks_;\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n * @override\n */\ngoog.Disposable.prototype.isDisposed = function() {\n 'use strict';\n return this.disposed_;\n};\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n * @deprecated Use {@link #isDisposed} instead.\n */\ngoog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;\n\n\n/**\n * Disposes of the object. If the object hasn't already been disposed of, calls\n * {@link #disposeInternal}. Classes that extend `goog.Disposable` should\n * override {@link #disposeInternal} in order to cleanup references, resources\n * and other disposable objects. Reentrant.\n *\n * @return {void} Nothing.\n * @override\n */\ngoog.Disposable.prototype.dispose = function() {\n 'use strict';\n if (!this.disposed_) {\n // Set disposed_ to true first, in case during the chain of disposal this\n // gets disposed recursively.\n this.disposed_ = true;\n this.disposeInternal();\n if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {\n var uid = goog.getUid(this);\n if (goog.Disposable.MONITORING_MODE ==\n goog.Disposable.MonitoringMode.PERMANENT &&\n !goog.Disposable.instances_.hasOwnProperty(uid)) {\n throw new Error(\n this + ' did not call the goog.Disposable base ' +\n 'constructor or was disposed of after a clearUndisposedObjects ' +\n 'call');\n }\n if (goog.Disposable.MONITORING_MODE !=\n goog.Disposable.MonitoringMode.OFF &&\n this.onDisposeCallbacks_ && this.onDisposeCallbacks_.length > 0) {\n throw new Error(\n this + ' did not empty its onDisposeCallbacks queue. This ' +\n 'probably means it overrode dispose() or disposeInternal() ' +\n 'without calling the superclass\\' method.');\n }\n delete goog.Disposable.instances_[uid];\n }\n }\n};\n\n\n/**\n * Associates a disposable object with this object so that they will be disposed\n * together.\n * @param {goog.disposable.IDisposable} disposable that will be disposed when\n * this object is disposed.\n */\ngoog.Disposable.prototype.registerDisposable = function(disposable) {\n 'use strict';\n this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));\n};\n\n\n/**\n * Invokes a callback function when this object is disposed. Callbacks are\n * invoked in the order in which they were added. If a callback is added to\n * an already disposed Disposable, it will be called immediately.\n * @param {function(this:T):?} callback The callback function.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @template T\n */\ngoog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {\n 'use strict';\n if (this.disposed_) {\n opt_scope !== undefined ? callback.call(opt_scope) : callback();\n return;\n }\n if (!this.onDisposeCallbacks_) {\n this.onDisposeCallbacks_ = [];\n }\n\n this.onDisposeCallbacks_.push(\n opt_scope !== undefined ? goog.bind(callback, opt_scope) : callback);\n};\n\n\n/**\n * Performs appropriate cleanup. See description of goog.disposable.IDisposable\n * for examples. Classes that extend `goog.Disposable` should override this\n * method. Not reentrant. To avoid calling it twice, it must only be called from\n * the subclass' `disposeInternal` method. Everywhere else the public `dispose`\n * method must be used. For example:\n *\n * <pre>\n * mypackage.MyClass = function() {\n * mypackage.MyClass.base(this, 'constructor');\n * // Constructor logic specific to MyClass.\n * ...\n * };\n * goog.inherits(mypackage.MyClass, goog.Disposable);\n *\n * mypackage.MyClass.prototype.disposeInternal = function() {\n * // Dispose logic specific to MyClass.\n * ...\n * // Call superclass's disposeInternal at the end of the subclass's, like\n * // in C++, to avoid hard-to-catch issues.\n * mypackage.MyClass.base(this, 'disposeInternal');\n * };\n * </pre>\n *\n * @protected\n */\ngoog.Disposable.prototype.disposeInternal = function() {\n 'use strict';\n if (this.onDisposeCallbacks_) {\n while (this.onDisposeCallbacks_.length) {\n this.onDisposeCallbacks_.shift()();\n }\n }\n};\n\n\n/**\n * Returns True if we can verify the object is disposed.\n * Calls `isDisposed` on the argument if it supports it. If obj\n * is not an object with an isDisposed() method, return false.\n * @param {*} obj The object to investigate.\n * @return {boolean} True if we can verify the object is disposed.\n */\ngoog.Disposable.isDisposed = function(obj) {\n 'use strict';\n if (obj && typeof obj.isDisposed == 'function') {\n return obj.isDisposed();\n }\n return false;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating arrays.\n */\n\n\ngoog.module('goog.array');\ngoog.module.declareLegacyNamespace();\n\nconst asserts = goog.require('goog.asserts');\n\n\n/**\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\n * rely on Array.prototype functions, if available.\n *\n * The Array.prototype functions can be defined by external libraries like\n * Prototype and setting this flag to false forces closure to use its own\n * goog.array implementation.\n *\n * If your javascript can be loaded by a third party site and you are wary about\n * relying on the prototype functions, specify\n * \"--define goog.NATIVE_ARRAY_PROTOTYPES=false\" to the JSCompiler.\n *\n * Setting goog.TRUSTED_SITE to false will automatically set\n * NATIVE_ARRAY_PROTOTYPES to false.\n */\ngoog.NATIVE_ARRAY_PROTOTYPES =\n goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\n\n\n/**\n * @define {boolean} If true, JSCompiler will use the native implementation of\n * array functions where appropriate (e.g., `Array#filter`) and remove the\n * unused pure JS implementation.\n */\nconst ASSUME_NATIVE_FUNCTIONS = goog.define(\n 'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\nexports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as {@link goog.array.last}.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\nfunction peek(array) {\n return array[array.length - 1];\n}\nexports.peek = peek;\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as {@link goog.array.peek}.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\nexports.last = peek;\n\n// NOTE(arv): Since most of the array functions are generic it allows you to\n// pass an array-like object. Strings have a length and are considered array-\n// like. However, the 'in' operator does not work on strings so we cannot just\n// use the array path even if the browser supports indexing into strings. We\n// therefore end up splitting the string.\n\n\n/**\n * Returns the index of the first element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\n *\n * @param {IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {number=} opt_fromIndex The index at which to start the search. If\n * omitted the search starts at index 0.\n * @return {number} The index of the first matching array element.\n * @template T\n */\nconst indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\n function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n const fromIndex = opt_fromIndex == null ?\n 0 :\n (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\n opt_fromIndex);\n\n if (typeof arr === 'string') {\n // Array.prototype.indexOf uses === so only strings should be found.\n if (typeof obj !== 'string' || obj.length != 1) {\n return -1;\n }\n return arr.indexOf(obj, fromIndex);\n }\n\n for (let i = fromIndex; i < arr.length; i++) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\nexports.indexOf = indexOf;\n\n\n/**\n * Returns the index of the last element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\n *\n * @param {!IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {?number=} opt_fromIndex The index at which to start the search. If\n * omitted the search starts at the end of the array.\n * @return {number} The index of the last matching array element.\n * @template T\n */\nconst lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\n function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n\n // Firefox treats undefined and null as 0 in the fromIndex argument which\n // leads it to always return -1\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n\n if (fromIndex < 0) {\n fromIndex = Math.max(0, arr.length + fromIndex);\n }\n\n if (typeof arr === 'string') {\n // Array.prototype.lastIndexOf uses === so only strings should be found.\n if (typeof obj !== 'string' || obj.length != 1) {\n return -1;\n }\n return arr.lastIndexOf(obj, fromIndex);\n }\n\n for (let i = fromIndex; i >= 0; i--) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\nexports.lastIndexOf = lastIndexOf;\n\n\n/**\n * Calls a function for each element in an array. Skips holes in the array.\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\n *\n * @param {IArrayLike<T>|string} arr Array or array like object over\n * which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n * element. This function takes 3 arguments (the element, the index and the\n * array). The return value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @template T,S\n */\nconst forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n Array.prototype.forEach.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n };\nexports.forEach = forEach;\n\n\n/**\n * Calls a function for each element in an array, starting from the last\n * element rather than the first.\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n * element. This function\n * takes 3 arguments (the element, the index and the array). The return\n * value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @template T,S\n */\nfunction forEachRight(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = l - 1; i >= 0; --i) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n}\nexports.forEachRight = forEachRight;\n\n\n/**\n * Calls a function for each element in an array, and if the function returns\n * true adds the element to a new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\n * every element. This function\n * takes 3 arguments (the element, the index and the array) and must\n * return a Boolean. If the return value is true the element is added to the\n * result array. If it is false the element is not included.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {!Array<T>} a new array in which only elements that passed the test\n * are present.\n * @template T,S\n */\nconst filter = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.filter.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const res = [];\n let resLength = 0;\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n const val = arr2[i]; // in case f mutates arr2\n if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\n res[resLength++] = val;\n }\n }\n }\n return res;\n };\nexports.filter = filter;\n\n\n/**\n * Calls a function for each element in an array and inserts the result into a\n * new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\n *\n * @param {IArrayLike<VALUE>|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\n * for every element. This function takes 3 arguments (the element,\n * the index and the array) and should return something. The result will be\n * inserted into a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the results from f.\n * @template THIS, VALUE, RESULT\n */\nconst map = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.map.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const res = new Array(l);\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n return res;\n };\nexports.map = map;\n\n\n/**\n * Passes every element of an array into a function and accumulates the result.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\n * Note that this implementation differs from the native Array.prototype.reduce\n * in that the initial value is assumed to be defined (the MDN docs linked above\n * recommend not omitting this parameter, although it is technically optional).\n *\n * For example:\n * var a = [1, 2, 3, 4];\n * reduce(a, function(r, v, i, arr) {return r + v;}, 0);\n * returns 10\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\n * every element. This function\n * takes 4 arguments (the function's previous result or the initial value,\n * the value of the current array element, the current array index, and the\n * array itself)\n * function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {R} Result of evaluating f repeatedly across the values of the array.\n * @template T,S,R\n */\nconst reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\n function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduce.call(arr, f, val);\n } :\n function(arr, f, val, opt_obj) {\n let rval = val;\n forEach(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\nexports.reduce = reduce;\n\n\n/**\n * Passes every element of an array into a function and accumulates the result,\n * starting from the last element and working towards the first.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\n *\n * For example:\n * var a = ['a', 'b', 'c'];\n * reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\n * returns 'cba'\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\n * every element. This function\n * takes 4 arguments (the function's previous result or the initial value,\n * the value of the current array element, the current array index, and the\n * array itself)\n * function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {R} Object returned as a result of evaluating f repeatedly across the\n * values of the array.\n * @template T,S,R\n */\nconst reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\n function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n asserts.assert(f != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduceRight.call(arr, f, val);\n } :\n function(arr, f, val, opt_obj) {\n let rval = val;\n forEachRight(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\nexports.reduceRight = reduceRight;\n\n\n/**\n * Calls f for each element of an array. If any call returns true, some()\n * returns true (without checking the remaining elements). If all calls\n * return false, some() returns false.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {boolean} true if any element passes the test.\n * @template T,S\n */\nconst some = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.some.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return true;\n }\n }\n return false;\n };\nexports.some = some;\n\n\n/**\n * Call f for each element of an array. If all calls return true, every()\n * returns true. If any call returns false, every() returns false and\n * does not continue to check the remaining elements.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {boolean} false if any element fails the test.\n * @template T,S\n */\nconst every = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.every.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return false;\n }\n }\n return true;\n };\nexports.every = every;\n\n\n/**\n * Counts the array elements that fulfill the predicate, i.e. for which the\n * callback function returns true. Skips holes in the array.\n *\n * @param {!IArrayLike<T>|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\n * every element. Takes 3 arguments (the element, the index and the array).\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @return {number} The number of the matching elements.\n * @template T,S\n */\nfunction count(arr, f, opt_obj) {\n let count = 0;\n forEach(arr, function(element, index, arr) {\n if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\n ++count;\n }\n }, opt_obj);\n return count;\n}\nexports.count = count;\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The first array element that passes the test, or null if no\n * element is found.\n * @template T,S\n */\nfunction find(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n}\nexports.find = find;\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the first array element that passes the test,\n * or -1 if no element is found.\n * @template T,S\n */\nfunction findIndex(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n}\nexports.findIndex = findIndex;\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The last array element that passes the test, or null if no\n * element is found.\n * @template T,S\n */\nfunction findRight(arr, f, opt_obj) {\n const i = findIndexRight(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n}\nexports.findRight = findRight;\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the last array element that passes the test,\n * or -1 if no element is found.\n * @template T,S\n */\nfunction findIndexRight(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = l - 1; i >= 0; i--) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n}\nexports.findIndexRight = findIndexRight;\n\n\n/**\n * Whether the array contains the given object.\n * @param {IArrayLike<?>|string} arr The array to test for the presence of the\n * element.\n * @param {*} obj The object for which to test.\n * @return {boolean} true if obj is present.\n */\nfunction contains(arr, obj) {\n return indexOf(arr, obj) >= 0;\n}\nexports.contains = contains;\n\n\n/**\n * Whether the array is empty.\n * @param {IArrayLike<?>|string} arr The array to test.\n * @return {boolean} true if empty.\n */\nfunction isEmpty(arr) {\n return arr.length == 0;\n}\nexports.isEmpty = isEmpty;\n\n\n/**\n * Clears the array.\n * @param {IArrayLike<?>} arr Array or array like object to clear.\n */\nfunction clear(arr) {\n // For non real arrays we don't have the magic length so we delete the\n // indices.\n if (!Array.isArray(arr)) {\n for (let i = arr.length - 1; i >= 0; i--) {\n delete arr[i];\n }\n }\n arr.length = 0;\n}\nexports.clear = clear;\n\n\n/**\n * Pushes an item into an array, if it's not already in the array.\n * @param {Array<T>} arr Array into which to insert the item.\n * @param {T} obj Value to add.\n * @template T\n */\nfunction insert(arr, obj) {\n if (!contains(arr, obj)) {\n arr.push(obj);\n }\n}\nexports.insert = insert;\n\n\n/**\n * Inserts an object at the given index of the array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {*} obj The object to insert.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n * treated as 0. A negative index is counted from the end of the array.\n */\nfunction insertAt(arr, obj, opt_i) {\n splice(arr, opt_i, 0, obj);\n}\nexports.insertAt = insertAt;\n\n\n/**\n * Inserts at the given index of the array, all elements of another array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {IArrayLike<?>} elementsToAdd The array of elements to add.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n * treated as 0. A negative index is counted from the end of the array.\n */\nfunction insertArrayAt(arr, elementsToAdd, opt_i) {\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\n}\nexports.insertArrayAt = insertArrayAt;\n\n\n/**\n * Inserts an object into an array before a specified object.\n * @param {Array<T>} arr The array to modify.\n * @param {T} obj The object to insert.\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\n * is omitted or not found, obj is inserted at the end of the array.\n * @template T\n */\nfunction insertBefore(arr, obj, opt_obj2) {\n let i;\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\n arr.push(obj);\n } else {\n insertAt(arr, obj, i);\n }\n}\nexports.insertBefore = insertBefore;\n\n\n/**\n * Removes the first occurrence of a particular value from an array.\n * @param {IArrayLike<T>} arr Array from which to remove\n * value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\nfunction remove(arr, obj) {\n const i = indexOf(arr, obj);\n let rv;\n if ((rv = i >= 0)) {\n removeAt(arr, i);\n }\n return rv;\n}\nexports.remove = remove;\n\n\n/**\n * Removes the last occurrence of a particular value from an array.\n * @param {!IArrayLike<T>} arr Array from which to remove value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\nfunction removeLast(arr, obj) {\n const i = lastIndexOf(arr, obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n}\nexports.removeLast = removeLast;\n\n\n/**\n * Removes from an array the element at index i\n * @param {IArrayLike<?>} arr Array or array like object from which to\n * remove value.\n * @param {number} i The index to remove.\n * @return {boolean} True if an element was removed.\n */\nfunction removeAt(arr, i) {\n asserts.assert(arr.length != null);\n\n // use generic form of splice\n // splice returns the removed items and if successful the length of that\n // will be 1\n return Array.prototype.splice.call(arr, i, 1).length == 1;\n}\nexports.removeAt = removeAt;\n\n\n/**\n * Removes the first value that satisfies the given condition.\n * @param {IArrayLike<T>} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {boolean} True if an element was removed.\n * @template T,S\n */\nfunction removeIf(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n}\nexports.removeIf = removeIf;\n\n\n/**\n * Removes all values that satisfy the given condition.\n * @param {IArrayLike<T>} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The number of items removed\n * @template T,S\n */\nfunction removeAllIf(arr, f, opt_obj) {\n let removedCount = 0;\n forEachRight(arr, function(val, index) {\n if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\n if (removeAt(arr, index)) {\n removedCount++;\n }\n }\n });\n return removedCount;\n}\nexports.removeAllIf = removeAllIf;\n\n\n/**\n * Returns a new array that is the result of joining the arguments. If arrays\n * are passed then their items are added, however, if non-arrays are passed they\n * will be added to the return array as is.\n *\n * Note that ArrayLike objects will be added as is, rather than having their\n * items added.\n *\n * concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\n * concat(0, [1, 2]) -> [0, 1, 2]\n * concat([1, 2], null) -> [1, 2, null]\n *\n * @param {...*} var_args Items to concatenate. Arrays will have each item\n * added, while primitives and objects will be added as is.\n * @return {!Array<?>} The new resultant array.\n */\nfunction concat(var_args) {\n return Array.prototype.concat.apply([], arguments);\n}\nexports.concat = concat;\n\n\n/**\n * Returns a new array that contains the contents of all the arrays passed.\n * @param {...!Array<T>} var_args\n * @return {!Array<T>}\n * @template T\n */\nfunction join(var_args) {\n return Array.prototype.concat.apply([], arguments);\n}\nexports.join = join;\n\n\n/**\n * Converts an object to an array.\n * @param {IArrayLike<T>|string} object The object to convert to an\n * array.\n * @return {!Array<T>} The object converted into an array. If object has a\n * length property, every property indexed with a non-negative number\n * less than length will be included in the result. If object does not\n * have a length property, an empty array will be returned.\n * @template T\n */\nfunction toArray(object) {\n const length = object.length;\n\n // If length is not a number the following is false. This case is kept for\n // backwards compatibility since there are callers that pass objects that are\n // not array like.\n if (length > 0) {\n const rv = new Array(length);\n for (let i = 0; i < length; i++) {\n rv[i] = object[i];\n }\n return rv;\n }\n return [];\n}\nexports.toArray = toArray;\n\n\n/**\n * Does a shallow copy of an array.\n * @param {IArrayLike<T>|string} arr Array or array-like object to\n * clone.\n * @return {!Array<T>} Clone of the input array.\n * @template T\n */\nconst clone = toArray;\nexports.clone = clone;\n\n\n/**\n * Extends an array with another array, element, or \"array like\" object.\n * This function operates 'in-place', it does not create a new Array.\n *\n * Example:\n * var a = [];\n * extend(a, [0, 1]);\n * a; // [0, 1]\n * extend(a, 2);\n * a; // [0, 1, 2]\n *\n * @param {Array<VALUE>} arr1 The array to modify.\n * @param {...(IArrayLike<VALUE>|VALUE)} var_args The elements or arrays of\n * elements to add to arr1.\n * @template VALUE\n */\nfunction extend(arr1, var_args) {\n for (let i = 1; i < arguments.length; i++) {\n const arr2 = arguments[i];\n if (goog.isArrayLike(arr2)) {\n const len1 = arr1.length || 0;\n const len2 = arr2.length || 0;\n arr1.length = len1 + len2;\n for (let j = 0; j < len2; j++) {\n arr1[len1 + j] = arr2[j];\n }\n } else {\n arr1.push(arr2);\n }\n }\n}\nexports.extend = extend;\n\n\n/**\n * Adds or removes elements from an array. This is a generic version of Array\n * splice. This means that it might work on other objects similar to arrays,\n * such as the arguments object.\n *\n * @param {IArrayLike<T>} arr The array to modify.\n * @param {number|undefined} index The index at which to start changing the\n * array. If not defined, treated as 0.\n * @param {number} howMany How many elements to remove (0 means no removal. A\n * value below 0 is treated as zero and so is any other non number. Numbers\n * are floored).\n * @param {...T} var_args Optional, additional elements to insert into the\n * array.\n * @return {!Array<T>} the removed elements.\n * @template T\n */\nfunction splice(arr, index, howMany, var_args) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\n}\nexports.splice = splice;\n\n\n/**\n * Returns a new array from a segment of an array. This is a generic version of\n * Array slice. This means that it might work on other objects similar to\n * arrays, such as the arguments object.\n *\n * @param {IArrayLike<T>|string} arr The array from\n * which to copy a segment.\n * @param {number} start The index of the first element to copy.\n * @param {number=} opt_end The index after the last element to copy.\n * @return {!Array<T>} A new array containing the specified segment of the\n * original array.\n * @template T\n */\nfunction slice(arr, start, opt_end) {\n asserts.assert(arr.length != null);\n\n // passing 1 arg to slice is not the same as passing 2 where the second is\n // null or undefined (in that case the second argument is treated as 0).\n // we could use slice on the arguments object and then use apply instead of\n // testing the length\n if (arguments.length <= 2) {\n return Array.prototype.slice.call(arr, start);\n } else {\n return Array.prototype.slice.call(arr, start, opt_end);\n }\n}\nexports.slice = slice;\n\n\n/**\n * Removes all duplicates from an array (retaining only the first\n * occurrence of each array element). This function modifies the\n * array in place and doesn't change the order of the non-duplicate items.\n *\n * For objects, duplicates are identified as having the same unique ID as\n * defined by {@link goog.getUid}.\n *\n * Alternatively you can specify a custom hash function that returns a unique\n * value for each item in the array it should consider unique.\n *\n * Runtime: N,\n * Worstcase space: 2N (no dupes)\n *\n * @param {IArrayLike<T>} arr The array from which to remove\n * duplicates.\n * @param {Array=} opt_rv An optional array in which to return the results,\n * instead of performing the removal inplace. If specified, the original\n * array will remain unchanged.\n * @param {function(T):string=} opt_hashFn An optional function to use to\n * apply to every item in the array. This function should return a unique\n * value for each item in the array it should consider unique.\n * @template T\n */\nfunction removeDuplicates(arr, opt_rv, opt_hashFn) {\n const returnArray = opt_rv || arr;\n const defaultHashFn = function(item) {\n // Prefix each type with a single character representing the type to\n // prevent conflicting keys (e.g. true and 'true').\n return goog.isObject(item) ? 'o' + goog.getUid(item) :\n (typeof item).charAt(0) + item;\n };\n const hashFn = opt_hashFn || defaultHashFn;\n\n let cursorInsert = 0;\n let cursorRead = 0;\n const seen = {};\n\n while (cursorRead < arr.length) {\n const current = arr[cursorRead++];\n const key = hashFn(current);\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n seen[key] = true;\n returnArray[cursorInsert++] = current;\n }\n }\n returnArray.length = cursorInsert;\n}\nexports.removeDuplicates = removeDuplicates;\n\n\n/**\n * Searches the specified array for the specified target using the binary\n * search algorithm. If no opt_compareFn is specified, elements are compared\n * using <code>defaultCompare</code>, which compares the elements\n * using the built in < and > operators. This will produce the expected\n * behavior for homogeneous arrays of String(s) and Number(s). The array\n * specified <b>must</b> be sorted in ascending order (as defined by the\n * comparison function). If the array is not sorted, results are undefined.\n * If the array contains multiple instances of the specified target value, the\n * left-most instance will be found.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {TARGET} target The sought value.\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, the target value and an element from your array, and return a\n * negative number, zero, or a positive number depending on whether the\n * first argument is less than, equal to, or greater than the second.\n * @return {number} Lowest index of the target value if found, otherwise\n * (-(insertion point) - 1). The insertion point is where the value should\n * be inserted into arr to preserve the sorted property. Return value >= 0\n * iff target is found.\n * @template TARGET, VALUE\n */\nfunction binarySearch(arr, target, opt_compareFn) {\n return binarySearch_(\n arr, opt_compareFn || defaultCompare, false /* isEvaluator */, target);\n}\nexports.binarySearch = binarySearch;\n\n\n/**\n * Selects an index in the specified array using the binary search algorithm.\n * The evaluator receives an element and determines whether the desired index\n * is before, at, or after it. The evaluator must be consistent (formally,\n * map(map(arr, evaluator, opt_obj), goog.math.sign)\n * must be monotonically non-increasing).\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\n * Evaluator function that receives 3 arguments (the element, the index and\n * the array). Should return a negative number, zero, or a positive number\n * depending on whether the desired index is before, at, or after the\n * element passed to it.\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\n * within evaluator.\n * @return {number} Index of the leftmost element matched by the evaluator, if\n * such exists; otherwise (-(insertion point) - 1). The insertion point is\n * the index of the first element for which the evaluator returns negative,\n * or arr.length if no such element exists. The return value is non-negative\n * iff a match is found.\n * @template THIS, VALUE\n */\nfunction binarySelect(arr, evaluator, opt_obj) {\n return binarySearch_(\n arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\n opt_obj);\n}\nexports.binarySelect = binarySelect;\n\n\n/**\n * Implementation of a binary search algorithm which knows how to use both\n * comparison functions and evaluators. If an evaluator is provided, will call\n * the evaluator with the given optional data object, conforming to the\n * interface defined in binarySelect. Otherwise, if a comparison function is\n * provided, will call the comparison function against the given data object.\n *\n * This implementation purposefully does not use goog.bind or goog.partial for\n * performance reasons.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<?>} arr The array to be searched.\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\n * Either an evaluator or a comparison function, as defined by binarySearch\n * and binarySelect above.\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\n * comparison function.\n * @param {?=} opt_target If the function is a comparison function, then\n * this is the target to binary search for.\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\n * optional this object for the evaluator.\n * @return {number} Lowest index of the target value if found, otherwise\n * (-(insertion point) - 1). The insertion point is where the value should\n * be inserted into arr to preserve the sorted property. Return value >= 0\n * iff target is found.\n * @private\n */\nfunction binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n let left = 0; // inclusive\n let right = arr.length; // exclusive\n let found;\n while (left < right) {\n const middle = left + ((right - left) >>> 1);\n let compareResult;\n if (isEvaluator) {\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n } else {\n // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\n // for the type of binarySearch_, which the type system can't express yet.\n compareResult = /** @type {function(?, ?): number} */ (compareFn)(\n opt_target, arr[middle]);\n }\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n // We are looking for the lowest index so we can't return immediately.\n found = !compareResult;\n }\n }\n // left is the index if found, or the insertion point otherwise.\n // Avoiding bitwise not operator, as that causes a loss in precision for array\n // indexes outside the bounds of a 32-bit signed integer. Array indexes have\n // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\n return found ? left : -left - 1;\n}\n\n\n/**\n * Sorts the specified array into ascending order. If no opt_compareFn is\n * specified, elements are compared using\n * <code>defaultCompare</code>, which compares the elements using\n * the built in < and > operators. This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\n * but will give unpredictable results for heterogeneous lists of strings and\n * numbers with different numbers of digits.\n *\n * This sort is not guaranteed to be stable.\n *\n * Runtime: Same as `Array.prototype.sort`\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\n * function by which the\n * array is to be ordered. Should take 2 arguments to compare, and return a\n * negative number, zero, or a positive number depending on whether the\n * first argument is less than, equal to, or greater than the second.\n * @template T\n */\nfunction sort(arr, opt_compareFn) {\n // TODO(arv): Update type annotation since null is not accepted.\n arr.sort(opt_compareFn || defaultCompare);\n}\nexports.sort = sort;\n\n\n/**\n * Sorts the specified array into ascending order in a stable way. If no\n * opt_compareFn is specified, elements are compared using\n * <code>defaultCompare</code>, which compares the elements using\n * the built in < and > operators. This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s).\n *\n * Runtime: Same as `Array.prototype.sort`, plus an additional\n * O(n) overhead of copying the array twice.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\n * by which the array is to be ordered. Should take 2 arguments to compare,\n * and return a negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template T\n */\nfunction stableSort(arr, opt_compareFn) {\n const compArr = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n compArr[i] = {index: i, value: arr[i]};\n }\n const valueCompareFn = opt_compareFn || defaultCompare;\n function stableCompareFn(obj1, obj2) {\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n }\n sort(compArr, stableCompareFn);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = compArr[i].value;\n }\n}\nexports.stableSort = stableSort;\n\n\n/**\n * Sort the specified array into ascending order based on item keys\n * returned by the specified key function.\n * If no opt_compareFn is specified, the keys are compared in ascending order\n * using <code>defaultCompare</code>.\n *\n * Runtime: O(S(f(n)), where S is runtime of <code>sort</code>\n * and f(n) is runtime of the key function.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {function(T): K} keyFn Function taking array element and returning\n * a key used for sorting this element.\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\n * by which the keys are to be ordered. Should take 2 arguments to compare,\n * and return a negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template T,K\n */\nfunction sortByKey(arr, keyFn, opt_compareFn) {\n const keyCompareFn = opt_compareFn || defaultCompare;\n sort(arr, function(a, b) {\n return keyCompareFn(keyFn(a), keyFn(b));\n });\n}\nexports.sortByKey = sortByKey;\n\n\n/**\n * Sorts an array of objects by the specified object key and compare\n * function. If no compare function is provided, the key values are\n * compared in ascending order using <code>defaultCompare</code>.\n * This won't work for keys that get renamed by the compiler. So use\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\n * @param {Array<Object>} arr An array of objects to sort.\n * @param {string} key The object key to sort by.\n * @param {Function=} opt_compareFn The function to use to compare key\n * values.\n */\nfunction sortObjectsByKey(arr, key, opt_compareFn) {\n sortByKey(arr, function(obj) {\n return obj[key];\n }, opt_compareFn);\n}\nexports.sortObjectsByKey = sortObjectsByKey;\n\n\n/**\n * Tells if the array is sorted.\n * @param {!IArrayLike<T>} arr The array.\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\n * array elements.\n * Should take 2 arguments to compare, and return a negative number, zero,\n * or a positive number depending on whether the first argument is less\n * than, equal to, or greater than the second.\n * @param {boolean=} opt_strict If true no equal elements are allowed.\n * @return {boolean} Whether the array is sorted.\n * @template T\n */\nfunction isSorted(arr, opt_compareFn, opt_strict) {\n const compare = opt_compareFn || defaultCompare;\n for (let i = 1; i < arr.length; i++) {\n const compareResult = compare(arr[i - 1], arr[i]);\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\n return false;\n }\n }\n return true;\n}\nexports.isSorted = isSorted;\n\n\n/**\n * Compares two arrays for equality. Two arrays are considered equal if they\n * have the same length and their corresponding elements are equal according to\n * the comparison function.\n *\n * @param {IArrayLike<A>} arr1 The first array to compare.\n * @param {IArrayLike<B>} arr2 The second array to compare.\n * @param {?function(A,B):boolean=} opt_equalsFn Optional comparison function.\n * Should take 2 arguments to compare, and return true if the arguments\n * are equal. Defaults to {@link goog.array.defaultCompareEquality} which\n * compares the elements using the built-in '===' operator.\n * @return {boolean} Whether the two arrays are equal.\n * @template A\n * @template B\n */\nfunction equals(arr1, arr2, opt_equalsFn) {\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\n arr1.length != arr2.length) {\n return false;\n }\n const l = arr1.length;\n const equalsFn = opt_equalsFn || defaultCompareEquality;\n for (let i = 0; i < l; i++) {\n if (!equalsFn(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n}\nexports.equals = equals;\n\n\n/**\n * 3-way array compare function.\n * @param {!IArrayLike<VALUE>} arr1 The first array to\n * compare.\n * @param {!IArrayLike<VALUE>} arr2 The second array to\n * compare.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is to be ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {number} Negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template VALUE\n */\nfunction compare3(arr1, arr2, opt_compareFn) {\n const compare = opt_compareFn || defaultCompare;\n const l = Math.min(arr1.length, arr2.length);\n for (let i = 0; i < l; i++) {\n const result = compare(arr1[i], arr2[i]);\n if (result != 0) {\n return result;\n }\n }\n return defaultCompare(arr1.length, arr2.length);\n}\nexports.compare3 = compare3;\n\n\n/**\n * Compares its two arguments for order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second,\n * respectively.\n * @template VALUE\n */\nfunction defaultCompare(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\nexports.defaultCompare = defaultCompare;\n\n\n/**\n * Compares its two arguments for inverse order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is greater than, equal to, or less than the second,\n * respectively.\n * @template VALUE\n */\nfunction inverseDefaultCompare(a, b) {\n return -defaultCompare(a, b);\n}\nexports.inverseDefaultCompare = inverseDefaultCompare;\n\n\n/**\n * Compares its two arguments for equality, using the built in === operator.\n * @param {*} a The first object to compare.\n * @param {*} b The second object to compare.\n * @return {boolean} True if the two arguments are equal, false otherwise.\n */\nfunction defaultCompareEquality(a, b) {\n return a === b;\n}\nexports.defaultCompareEquality = defaultCompareEquality;\n\n\n/**\n * Inserts a value into a sorted array. The array is not modified if the\n * value is already present.\n * @param {IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to insert.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {boolean} True if an element was inserted.\n * @template VALUE\n */\nfunction binaryInsert(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n if (index < 0) {\n insertAt(array, value, -(index + 1));\n return true;\n }\n return false;\n}\nexports.binaryInsert = binaryInsert;\n\n\n/**\n * Removes a value from a sorted array.\n * @param {!IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to remove.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {boolean} True if an element was removed.\n * @template VALUE\n */\nfunction binaryRemove(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n return (index >= 0) ? removeAt(array, index) : false;\n}\nexports.binaryRemove = binaryRemove;\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {IArrayLike<T>} array The array.\n * @param {function(this:S, T, number, !IArrayLike<T>):?} sorter Function to\n * call for every element. This takes 3 arguments (the element, the index\n * and the array) and must return a valid object key (a string, number,\n * etc), or undefined, if that object should not be placed in a bucket.\n * @param {S=} opt_obj The object to be used as the value of 'this' within\n * sorter.\n * @return {!Object<!Array<T>>} An object, with keys being all of the unique\n * return values of sorter, and values being arrays containing the items for\n * which the splitter returned that key.\n * @template T,S\n */\nfunction bucket(array, sorter, opt_obj) {\n const buckets = {};\n\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\n if (key !== undefined) {\n // Push the value to the right bucket, creating it if necessary.\n const bucket = buckets[key] || (buckets[key] = []);\n bucket.push(value);\n }\n }\n\n return buckets;\n}\nexports.bucket = bucket;\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {!IArrayLike<V>} array The array.\n * @param {function(V, number, !IArrayLike<V>):(K|undefined)} sorter Function to\n * call for every element. This takes 3 arguments (the element, the index,\n * and the array) and must return a value to use as a key, or undefined, if\n * that object should not be placed in a bucket.\n * @return {!Map<K, !Array<V>>} A map, with keys being all of the unique\n * return values of sorter, and values being arrays containing the items for\n * which the splitter returned that key.\n * @template K,V\n */\nfunction bucketToMap(array, sorter) {\n const /** !Map<K, !Array<V>> */ buckets = new Map();\n\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter(value, i, array);\n if (key !== undefined) {\n // Push the value to the right bucket, creating it if necessary.\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = [];\n buckets.set(key, bucket);\n }\n bucket.push(value);\n }\n }\n\n return buckets;\n}\nexports.bucketToMap = bucketToMap;\n\n\n/**\n * Creates a new object built from the provided array and the key-generation\n * function.\n * @param {IArrayLike<T>} arr Array or array like object over\n * which to iterate whose elements will be the values in the new object.\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\n * call for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a string that will be used as the\n * key for the element in the new object. If the function returns the same\n * key for more than one element, the value for that key is\n * implementation-defined.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within keyFunc.\n * @return {!Object<T>} The new object.\n * @template T,S\n */\nfunction toObject(arr, keyFunc, opt_obj) {\n const ret = {};\n forEach(arr, function(element, index) {\n ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\n element;\n });\n return ret;\n}\nexports.toObject = toObject;\n\n\n/**\n * Creates a new ES6 Map built from the provided array and the key-generation\n * function.\n * @param {!IArrayLike<V>} arr Array or array like object over which to iterate\n * whose elements will be the values in the new object.\n * @param {?function(V, number, ?) : K} keyFunc The function to call for every\n * element. This function takes 3 arguments (the element, the index, and the\n * array) and should return a value that will be used as the key for the\n * element in the new object. If the function returns the same key for more\n * than one element, the value for that key is implementation-defined.\n * @return {!Map<K, V>} The new map.\n * @template K,V\n */\nfunction toMap(arr, keyFunc) {\n const /** !Map<K, V> */ map = new Map();\n\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i];\n map.set(keyFunc(element, i, arr), element);\n }\n\n return map;\n}\nexports.toMap = toMap;\n\n\n/**\n * Creates a range of numbers in an arithmetic progression.\n *\n * Range takes 1, 2, or 3 arguments:\n * <pre>\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\n * range(-2, -5, -1) produces [-2, -3, -4]\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\n * </pre>\n *\n * @param {number} startOrEnd The starting value of the range if an end argument\n * is provided. Otherwise, the start value is 0, and this is the end value.\n * @param {number=} opt_end The optional end value of the range.\n * @param {number=} opt_step The step size between range values. Defaults to 1\n * if opt_step is undefined or 0.\n * @return {!Array<number>} An array of numbers for the requested range. May be\n * an empty array if adding the step would not converge toward the end\n * value.\n */\nfunction range(startOrEnd, opt_end, opt_step) {\n const array = [];\n let start = 0;\n let end = startOrEnd;\n const step = opt_step || 1;\n if (opt_end !== undefined) {\n start = startOrEnd;\n end = opt_end;\n }\n\n if (step * (end - start) < 0) {\n // Sign mismatch: start + step will never reach the end value.\n return [];\n }\n\n if (step > 0) {\n for (let i = start; i < end; i += step) {\n array.push(i);\n }\n } else {\n for (let i = start; i > end; i += step) {\n array.push(i);\n }\n }\n return array;\n}\nexports.range = range;\n\n\n/**\n * Returns an array consisting of the given value repeated N times.\n *\n * @param {VALUE} value The value to repeat.\n * @param {number} n The repeat count.\n * @return {!Array<VALUE>} An array with the repeated value.\n * @template VALUE\n */\nfunction repeat(value, n) {\n const array = [];\n for (let i = 0; i < n; i++) {\n array[i] = value;\n }\n return array;\n}\nexports.repeat = repeat;\n\n\n/**\n * Returns an array consisting of every argument with all arrays\n * expanded in-place recursively.\n *\n * @param {...*} var_args The values to flatten.\n * @return {!Array<?>} An array containing the flattened values.\n */\nfunction flatten(var_args) {\n const CHUNK_SIZE = 8192;\n\n const result = [];\n for (let i = 0; i < arguments.length; i++) {\n const element = arguments[i];\n if (Array.isArray(element)) {\n for (let c = 0; c < element.length; c += CHUNK_SIZE) {\n const chunk = slice(element, c, c + CHUNK_SIZE);\n const recurseResult = flatten.apply(null, chunk);\n for (let r = 0; r < recurseResult.length; r++) {\n result.push(recurseResult[r]);\n }\n }\n } else {\n result.push(element);\n }\n }\n return result;\n}\nexports.flatten = flatten;\n\n\n/**\n * Rotates an array in-place. After calling this method, the element at\n * index i will be the element previously at index (i - n) %\n * array.length, for all values of i between 0 and array.length - 1,\n * inclusive.\n *\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\n *\n * @param {!Array<T>} array The array to rotate.\n * @param {number} n The amount to rotate.\n * @return {!Array<T>} The array.\n * @template T\n */\nfunction rotate(array, n) {\n asserts.assert(array.length != null);\n\n if (array.length) {\n n %= array.length;\n if (n > 0) {\n Array.prototype.unshift.apply(array, array.splice(-n, n));\n } else if (n < 0) {\n Array.prototype.push.apply(array, array.splice(0, -n));\n }\n }\n return array;\n}\nexports.rotate = rotate;\n\n\n/**\n * Moves one item of an array to a new position keeping the order of the rest\n * of the items. Example use case: keeping a list of JavaScript objects\n * synchronized with the corresponding list of DOM elements after one of the\n * elements has been dragged to a new position.\n * @param {!IArrayLike<?>} arr The array to modify.\n * @param {number} fromIndex Index of the item to move between 0 and\n * `arr.length - 1`.\n * @param {number} toIndex Target index between 0 and `arr.length - 1`.\n */\nfunction moveItem(arr, fromIndex, toIndex) {\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\n // Remove 1 item at fromIndex.\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n // Insert the removed item at toIndex.\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n // We don't use goog.array.insertAt and goog.array.removeAt, because they're\n // significantly slower than splice.\n}\nexports.moveItem = moveItem;\n\n\n/**\n * Creates a new array for which the element at position i is an array of the\n * ith element of the provided arrays. The returned array will only be as long\n * as the shortest array provided; additional values are ignored. For example,\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\n *\n * This is similar to the zip() function in Python. See {@link\n * http://docs.python.org/library/functions.html#zip}\n *\n * @param {...!IArrayLike<?>} var_args Arrays to be combined.\n * @return {!Array<!Array<?>>} A new array of arrays created from\n * provided arrays.\n */\nfunction zip(var_args) {\n if (!arguments.length) {\n return [];\n }\n const result = [];\n let minLen = arguments[0].length;\n for (let i = 1; i < arguments.length; i++) {\n if (arguments[i].length < minLen) {\n minLen = arguments[i].length;\n }\n }\n for (let i = 0; i < minLen; i++) {\n const value = [];\n for (let j = 0; j < arguments.length; j++) {\n value.push(arguments[j][i]);\n }\n result.push(value);\n }\n return result;\n}\nexports.zip = zip;\n\n\n/**\n * Shuffles the values in the specified array using the Fisher-Yates in-place\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\n * and so resets the state of that random number generator. Similarly, may reset\n * the state of any other specified random number generator.\n *\n * Runtime: O(n)\n *\n * @param {!Array<?>} arr The array to be shuffled.\n * @param {function():number=} opt_randFn Optional random function to use for\n * shuffling.\n * Takes no arguments, and returns a random number on the interval [0, 1).\n * Defaults to Math.random() using JavaScript's built-in Math library.\n */\nfunction shuffle(arr, opt_randFn) {\n const randFn = opt_randFn || Math.random;\n\n for (let i = arr.length - 1; i > 0; i--) {\n // Choose a random array index in [0, i] (inclusive with i).\n const j = Math.floor(randFn() * (i + 1));\n\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n }\n}\nexports.shuffle = shuffle;\n\n\n/**\n * Returns a new array of elements from arr, based on the indexes of elements\n * provided by index_arr. For example, the result of index copying\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\n *\n * @param {!IArrayLike<T>} arr The array to get a indexed copy from.\n * @param {!IArrayLike<number>} index_arr An array of indexes to get from arr.\n * @return {!Array<T>} A new array of elements from arr in index_arr order.\n * @template T\n */\nfunction copyByIndex(arr, index_arr) {\n const result = [];\n forEach(index_arr, function(index) {\n result.push(arr[index]);\n });\n return result;\n}\nexports.copyByIndex = copyByIndex;\n\n\n/**\n * Maps each element of the input array into zero or more elements of the output\n * array.\n *\n * @param {!IArrayLike<VALUE>|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): !Array<RESULT>} f The function\n * to call for every element. This function takes 3 arguments (the element,\n * the index and the array) and should return an array. The result will be\n * used to extend a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the concatenation of all arrays\n * returned from f.\n * @template THIS, VALUE, RESULT\n */\nfunction concatMap(arr, f, opt_obj) {\n return concat.apply([], map(arr, f, opt_obj));\n}\nexports.concatMap = concatMap;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A base class for event objects.\n */\n\n\ngoog.provide('goog.events.Event');\n\n/**\n * goog.events.Event no longer depends on goog.Disposable. Keep requiring\n * goog.Disposable here to not break projects which assume this dependency.\n * @suppress {extraRequire}\n */\ngoog.require('goog.Disposable');\ngoog.require('goog.events.EventId');\n\n\n/**\n * A base class for event objects, so that they can support preventDefault and\n * stopPropagation.\n *\n * @param {string|!goog.events.EventId} type Event Type.\n * @param {Object=} opt_target Reference to the object that is the target of\n * this event. It has to implement the `EventTarget` interface\n * declared at {@link http://developer.mozilla.org/en/DOM/EventTarget}.\n * @constructor\n */\ngoog.events.Event = function(type, opt_target) {\n 'use strict';\n /**\n * Event type.\n * @type {string}\n */\n this.type = type instanceof goog.events.EventId ? String(type) : type;\n\n /**\n * TODO(tbreisacher): The type should probably be\n * EventTarget|goog.events.EventTarget.\n *\n * Target of the event.\n * @type {Object|undefined}\n */\n this.target = opt_target;\n\n /**\n * Object that had the listener attached.\n * @type {Object|undefined}\n */\n this.currentTarget = this.target;\n\n /**\n * Whether to cancel the event in internal capture/bubble processing for IE.\n * @type {boolean}\n * @private\n */\n this.propagationStopped_ = false;\n\n /**\n * Whether the default action has been prevented.\n * This is a property to match the W3C specification at\n * {@link http://www.w3.org/TR/DOM-Level-3-Events/\n * #events-event-type-defaultPrevented}.\n * Must be treated as read-only outside the class.\n * @type {boolean}\n */\n this.defaultPrevented = false;\n};\n\n/**\n * @return {boolean} true iff internal propagation has been stopped.\n */\ngoog.events.Event.prototype.hasPropagationStopped = function() {\n 'use strict';\n return this.propagationStopped_;\n};\n\n/**\n * Stops event propagation.\n * @return {void}\n */\ngoog.events.Event.prototype.stopPropagation = function() {\n 'use strict';\n this.propagationStopped_ = true;\n};\n\n\n/**\n * Prevents the default action, for example a link redirecting to a url.\n * @return {void}\n */\ngoog.events.Event.prototype.preventDefault = function() {\n 'use strict';\n this.defaultPrevented = true;\n};\n\n\n/**\n * Stops the propagation of the event. It is equivalent to\n * `e.stopPropagation()`, but can be used as the callback argument of\n * {@link goog.events.listen} without declaring another function.\n * @param {!goog.events.Event} e An event.\n * @return {void}\n */\ngoog.events.Event.stopPropagation = function(e) {\n 'use strict';\n e.stopPropagation();\n};\n\n\n/**\n * Prevents the default action. It is equivalent to\n * `e.preventDefault()`, but can be used as the callback argument of\n * {@link goog.events.listen} without declaring another function.\n * @param {!goog.events.Event} e An event.\n * @return {void}\n */\ngoog.events.Event.preventDefault = function(e) {\n 'use strict';\n e.preventDefault();\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Browser capability checks for the events package.\n */\n\ngoog.module('goog.events.BrowserFeature');\ngoog.module.declareLegacyNamespace();\n\n\n/**\n * Tricks Closure Compiler into believing that a function is pure. The compiler\n * assumes that any `valueOf` function is pure, without analyzing its contents.\n *\n * @param {function(): T} fn\n * @return {T}\n * @template T\n */\nconst purify = (fn) => {\n return ({valueOf: fn}).valueOf();\n};\n\n\n/**\n * Enum of browser capabilities.\n * @enum {boolean}\n */\nexports = {\n /**\n * Whether touch is enabled in the browser.\n */\n TOUCH_ENABLED:\n ('ontouchstart' in goog.global ||\n !!(goog.global['document'] && document.documentElement &&\n 'ontouchstart' in document.documentElement) ||\n // IE10 uses non-standard touch events, so it has a different check.\n !!(goog.global['navigator'] &&\n (goog.global['navigator']['maxTouchPoints'] ||\n goog.global['navigator']['msMaxTouchPoints']))),\n\n /**\n * Whether addEventListener supports W3C standard pointer events.\n * http://www.w3.org/TR/pointerevents/\n */\n POINTER_EVENTS: ('PointerEvent' in goog.global),\n\n /**\n * Whether addEventListener supports MSPointer events (only used in IE10).\n * http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx\n * http://msdn.microsoft.com/library/hh673557(v=vs.85).aspx\n */\n MSPOINTER_EVENTS: false,\n\n /**\n * Whether addEventListener supports {passive: true}.\n * https://developers.google.com/web/updates/2016/06/passive-event-listeners\n */\n PASSIVE_EVENTS: purify(function() {\n // If we're in a web worker or other custom environment, we can't tell.\n if (!goog.global.addEventListener || !Object.defineProperty) { // IE 8\n return false;\n }\n\n var passive = false;\n var options = Object.defineProperty({}, 'passive', {\n get: function() {\n passive = true;\n }\n });\n try {\n const nullFunction = () => {};\n goog.global.addEventListener('test', nullFunction, options);\n goog.global.removeEventListener('test', nullFunction, options);\n } catch (e) {\n }\n\n return passive;\n })\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview String functions called from Closure packages that couldn't\n * depend on each other. Outside Closure, use goog.string function which\n * delegate to these.\n */\n\n\ngoog.provide('goog.string.internal');\n\n\n/**\n * Fast prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the start of `str`.\n * @return {boolean} True if `str` begins with `prefix`.\n * @see goog.string.startsWith\n */\ngoog.string.internal.startsWith = function(str, prefix) {\n 'use strict';\n return str.lastIndexOf(prefix, 0) == 0;\n};\n\n\n/**\n * Fast suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix`.\n * @see goog.string.endsWith\n */\ngoog.string.internal.endsWith = function(str, suffix) {\n 'use strict';\n const l = str.length - suffix.length;\n return l >= 0 && str.indexOf(suffix, l) == l;\n};\n\n\n/**\n * Case-insensitive prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the end of `str`.\n * @return {boolean} True if `str` begins with `prefix` (ignoring\n * case).\n * @see goog.string.caseInsensitiveStartsWith\n */\ngoog.string.internal.caseInsensitiveStartsWith = function(str, prefix) {\n 'use strict';\n return (\n goog.string.internal.caseInsensitiveCompare(\n prefix, str.slice(0, prefix.length)) == 0);\n};\n\n\n/**\n * Case-insensitive suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix` (ignoring\n * case).\n * @see goog.string.caseInsensitiveEndsWith\n */\ngoog.string.internal.caseInsensitiveEndsWith = function(str, suffix) {\n 'use strict';\n return (\n goog.string.internal.caseInsensitiveCompare(\n suffix, str.slice(str.length - suffix.length)) == 0);\n};\n\n\n/**\n * Case-insensitive equality checker.\n * @param {string} str1 First string to check.\n * @param {string} str2 Second string to check.\n * @return {boolean} True if `str1` and `str2` are the same string,\n * ignoring case.\n * @see goog.string.caseInsensitiveEquals\n */\ngoog.string.internal.caseInsensitiveEquals = function(str1, str2) {\n 'use strict';\n return str1.toLowerCase() == str2.toLowerCase();\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n * @see goog.string.isEmptyOrWhitespace\n */\ngoog.string.internal.isEmptyOrWhitespace = function(str) {\n 'use strict';\n // testing length == 0 first is actually slower in all browsers (about the\n // same in Opera).\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return /^[\\s\\xa0]*$/.test(str);\n};\n\n\n/**\n * Trims white spaces to the left and right of a string.\n * @param {string} str The string to trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.internal.trim =\n (goog.TRUSTED_SITE && String.prototype.trim) ? function(str) {\n 'use strict';\n return str.trim();\n } : function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s\n // character class (as required by section 7.2 of the ECMAScript spec),\n // we explicitly include it in the regexp to enforce consistent\n // cross-browser behavior.\n // NOTE: We don't use String#replace because it might have side effects\n // causing this function to not compile to 0 bytes.\n return /^[\\s\\xa0]*([\\s\\S]*?)[\\s\\xa0]*$/.exec(str)[1];\n };\n\n\n/**\n * A string comparator that ignores case.\n * -1 = str1 less than str2\n * 0 = str1 equals str2\n * 1 = str1 greater than str2\n *\n * @param {string} str1 The string to compare.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} The comparator result, as described above.\n * @see goog.string.caseInsensitiveCompare\n */\ngoog.string.internal.caseInsensitiveCompare = function(str1, str2) {\n 'use strict';\n const test1 = String(str1).toLowerCase();\n const test2 = String(str2).toLowerCase();\n\n if (test1 < test2) {\n return -1;\n } else if (test1 == test2) {\n return 0;\n } else {\n return 1;\n }\n};\n\n\n/**\n * Converts \\n to <br>s or <br />s.\n * @param {string} str The string in which to convert newlines.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} A copy of `str` with converted newlines.\n * @see goog.string.newLineToBr\n */\ngoog.string.internal.newLineToBr = function(str, opt_xml) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)/g, opt_xml ? '<br />' : '<br>');\n};\n\n\n/**\n * Escapes double quote '\"' and single quote '\\'' characters in addition to\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\n * value within double or single quotes.\n * @param {string} str string to be escaped.\n * @param {boolean=} opt_isLikelyToContainHtmlChars\n * @return {string} An escaped copy of `str`.\n * @see goog.string.htmlEscape\n */\ngoog.string.internal.htmlEscape = function(\n str, opt_isLikelyToContainHtmlChars) {\n 'use strict';\n if (opt_isLikelyToContainHtmlChars) {\n str = str.replace(goog.string.internal.AMP_RE_, '&')\n .replace(goog.string.internal.LT_RE_, '<')\n .replace(goog.string.internal.GT_RE_, '>')\n .replace(goog.string.internal.QUOT_RE_, '"')\n .replace(goog.string.internal.SINGLE_QUOTE_RE_, ''')\n .replace(goog.string.internal.NULL_RE_, '�');\n return str;\n\n } else {\n // quick test helps in the case when there are no chars to replace, in\n // worst case this makes barely a difference to the time taken\n if (!goog.string.internal.ALL_RE_.test(str)) return str;\n\n // str.indexOf is faster than regex.test in this case\n if (str.indexOf('&') != -1) {\n str = str.replace(goog.string.internal.AMP_RE_, '&');\n }\n if (str.indexOf('<') != -1) {\n str = str.replace(goog.string.internal.LT_RE_, '<');\n }\n if (str.indexOf('>') != -1) {\n str = str.replace(goog.string.internal.GT_RE_, '>');\n }\n if (str.indexOf('\"') != -1) {\n str = str.replace(goog.string.internal.QUOT_RE_, '"');\n }\n if (str.indexOf('\\'') != -1) {\n str = str.replace(goog.string.internal.SINGLE_QUOTE_RE_, ''');\n }\n if (str.indexOf('\\x00') != -1) {\n str = str.replace(goog.string.internal.NULL_RE_, '�');\n }\n return str;\n }\n};\n\n\n/**\n * Regular expression that matches an ampersand, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.AMP_RE_ = /&/g;\n\n\n/**\n * Regular expression that matches a less than sign, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.LT_RE_ = /</g;\n\n\n/**\n * Regular expression that matches a greater than sign, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.GT_RE_ = />/g;\n\n\n/**\n * Regular expression that matches a double quote, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.QUOT_RE_ = /\"/g;\n\n\n/**\n * Regular expression that matches a single quote, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.SINGLE_QUOTE_RE_ = /'/g;\n\n\n/**\n * Regular expression that matches null character, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.NULL_RE_ = /\\x00/g;\n\n\n/**\n * Regular expression that matches any character that needs to be escaped.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.ALL_RE_ = /[\\x00&<>\"']/;\n\n\n/**\n * Do escaping of whitespace to preserve spatial formatting. We use character\n * entity #160 to make it safer for xml.\n * @param {string} str The string in which to escape whitespace.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} An escaped copy of `str`.\n * @see goog.string.whitespaceEscape\n */\ngoog.string.internal.whitespaceEscape = function(str, opt_xml) {\n 'use strict';\n // This doesn't use goog.string.preserveSpaces for backwards compatibility.\n return goog.string.internal.newLineToBr(\n str.replace(/ /g, '  '), opt_xml);\n};\n\n\n/**\n * Determines whether a string contains a substring.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n * @see goog.string.contains\n */\ngoog.string.internal.contains = function(str, subString) {\n 'use strict';\n return str.indexOf(subString) != -1;\n};\n\n\n/**\n * Determines whether a string contains a substring, ignoring case.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n * @see goog.string.caseInsensitiveContains\n */\ngoog.string.internal.caseInsensitiveContains = function(str, subString) {\n 'use strict';\n return goog.string.internal.contains(\n str.toLowerCase(), subString.toLowerCase());\n};\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string|number} version1 Version of first item.\n * @param {string|number} version2 Version of second item.\n *\n * @return {number} 1 if `version1` is higher.\n * 0 if arguments are equal.\n * -1 if `version2` is higher.\n * @see goog.string.compareVersions\n */\ngoog.string.internal.compareVersions = function(version1, version2) {\n 'use strict';\n let order = 0;\n // Trim leading and trailing whitespace and split the versions into\n // subversions.\n const v1Subs = goog.string.internal.trim(String(version1)).split('.');\n const v2Subs = goog.string.internal.trim(String(version2)).split('.');\n const subCount = Math.max(v1Subs.length, v2Subs.length);\n\n // Iterate over the subversions, as long as they appear to be equivalent.\n for (let subIdx = 0; order == 0 && subIdx < subCount; subIdx++) {\n let v1Sub = v1Subs[subIdx] || '';\n let v2Sub = v2Subs[subIdx] || '';\n\n do {\n // Split the subversions into pairs of numbers and qualifiers (like 'b').\n // Two different RegExp objects are use to make it clear the code\n // is side-effect free\n const v1Comp = /(\\d*)(\\D*)(.*)/.exec(v1Sub) || ['', '', '', ''];\n const v2Comp = /(\\d*)(\\D*)(.*)/.exec(v2Sub) || ['', '', '', ''];\n // Break if there are no more matches.\n if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {\n break;\n }\n\n // Parse the numeric part of the subversion. A missing number is\n // equivalent to 0.\n const v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);\n const v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);\n\n // Compare the subversion components. The number has the highest\n // precedence. Next, if the numbers are equal, a subversion without any\n // qualifier is always higher than a subversion with any qualifier. Next,\n // the qualifiers are compared as strings.\n order = goog.string.internal.compareElements_(v1CompNum, v2CompNum) ||\n goog.string.internal.compareElements_(\n v1Comp[2].length == 0, v2Comp[2].length == 0) ||\n goog.string.internal.compareElements_(v1Comp[2], v2Comp[2]);\n // Stop as soon as an inequality is discovered.\n\n v1Sub = v1Comp[3];\n v2Sub = v2Comp[3];\n } while (order == 0);\n }\n\n return order;\n};\n\n\n/**\n * Compares elements of a version number.\n *\n * @param {string|number|boolean} left An element from a version number.\n * @param {string|number|boolean} right An element from a version number.\n *\n * @return {number} 1 if `left` is higher.\n * 0 if arguments are equal.\n * -1 if `right` is higher.\n * @private\n */\ngoog.string.internal.compareElements_ = function(left, right) {\n 'use strict';\n if (left < right) {\n return -1;\n } else if (left > right) {\n return 1;\n }\n return 0;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities used by goog.labs.userAgent tools. These functions\n * should not be used outside of goog.labs.userAgent.*.\n *\n */\n\ngoog.module('goog.labs.userAgent.util');\ngoog.module.declareLegacyNamespace();\n\nconst {caseInsensitiveContains, contains} = goog.require('goog.string.internal');\nconst {useClientHints} = goog.require('goog.labs.userAgent');\n\n/**\n * @const {boolean} If true, use navigator.userAgentData without check.\n * TODO(user): FEATURESET_YEAR >= 2024 if it supports mobile and all the\n * brands we need. See https://caniuse.com/mdn-api_navigator_useragentdata.\n */\nconst ASSUME_CLIENT_HINTS_SUPPORT = false;\n\n/**\n * Gets the native userAgent string from navigator if it exists.\n * If navigator or navigator.userAgent string is missing, returns an empty\n * string.\n * @return {string}\n */\nfunction getNativeUserAgentString() {\n const navigator = getNavigator();\n if (navigator) {\n const userAgent = navigator.userAgent;\n if (userAgent) {\n return userAgent;\n }\n }\n return '';\n}\n\n/**\n * Gets the native userAgentData object from navigator if it exists.\n * If navigator.userAgentData object is missing returns null.\n * @return {?NavigatorUAData}\n */\nfunction getNativeUserAgentData() {\n const navigator = getNavigator();\n // TODO(user): Use navigator?.userAgent ?? null once it's supported.\n if (navigator) {\n return navigator.userAgentData || null;\n }\n return null;\n}\n\n/**\n * Getter for the native navigator.\n * @return {!Navigator}\n */\nfunction getNavigator() {\n return goog.global.navigator;\n}\n\n/**\n * A possible override for applications which wish to not check\n * navigator.userAgent but use a specified value for detection instead.\n * @type {?string}\n */\nlet userAgentInternal = null;\n\n/**\n * A possible override for applications which wish to not check\n * navigator.userAgentData but use a specified value for detection instead.\n * @type {?NavigatorUAData}\n */\nlet userAgentDataInternal = getNativeUserAgentData();\n\n/**\n * Override the user agent string with the given value.\n * This should only be used for testing within the goog.labs.userAgent\n * namespace.\n * Pass `null` to use the native browser object instead.\n * @param {?string=} userAgent The userAgent override.\n * @return {void}\n */\nfunction setUserAgent(userAgent = undefined) {\n userAgentInternal =\n typeof userAgent === 'string' ? userAgent : getNativeUserAgentString();\n}\n\n/** @return {string} The user agent string. */\nfunction getUserAgent() {\n return userAgentInternal == null ? getNativeUserAgentString() :\n userAgentInternal;\n}\n\n/**\n * Override the user agent data object with the given value.\n * This should only be used for testing within the goog.labs.userAgent\n * namespace.\n * Pass `null` to specify the absence of userAgentData. Note that this behavior\n * is different from setUserAgent.\n * @param {?NavigatorUAData} userAgentData The userAgentData override.\n */\nfunction setUserAgentData(userAgentData) {\n userAgentDataInternal = userAgentData;\n}\n\n/**\n * If the user agent data object was overridden using setUserAgentData,\n * reset it so that it uses the native browser object instead, if it exists.\n */\nfunction resetUserAgentData() {\n userAgentDataInternal = getNativeUserAgentData();\n}\n\n/** @return {?NavigatorUAData} Navigator.userAgentData if exist */\nfunction getUserAgentData() {\n return userAgentDataInternal;\n}\n\n/**\n * Checks if any string in userAgentData.brands matches str.\n * Returns false if userAgentData is not supported.\n * @param {string} str\n * @return {boolean} Whether any brand string from userAgentData contains the\n * given string.\n */\nfunction matchUserAgentDataBrand(str) {\n if (!useClientHints()) return false;\n const data = getUserAgentData();\n if (!data) return false;\n return data.brands.some(({brand}) => brand && contains(brand, str));\n}\n\n/**\n * @param {string} str\n * @return {boolean} Whether the user agent contains the given string.\n */\nfunction matchUserAgent(str) {\n const userAgent = getUserAgent();\n return contains(userAgent, str);\n}\n\n/**\n * @param {string} str\n * @return {boolean} Whether the user agent contains the given string, ignoring\n * case.\n */\nfunction matchUserAgentIgnoreCase(str) {\n const userAgent = getUserAgent();\n return caseInsensitiveContains(userAgent, str);\n}\n\n/**\n * Parses the user agent into tuples for each section.\n * @param {string} userAgent\n * @return {!Array<!Array<string>>} Tuples of key, version, and the contents of\n * the parenthetical.\n */\nfunction extractVersionTuples(userAgent) {\n // Matches each section of a user agent string.\n // Example UA:\n // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)\n // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405\n // This has three version tuples: Mozilla, AppleWebKit, and Mobile.\n\n const versionRegExp = new RegExp(\n // Key. Note that a key may have a space.\n // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')\n '([A-Z][\\\\w ]+)' +\n\n '/' + // slash\n '([^\\\\s]+)' + // version (i.e. '5.0b')\n '\\\\s*' + // whitespace\n '(?:\\\\((.*?)\\\\))?', // parenthetical info. parentheses not matched.\n 'g');\n\n const data = [];\n let match;\n\n // Iterate and collect the version tuples. Each iteration will be the\n // next regex match.\n while (match = versionRegExp.exec(userAgent)) {\n data.push([\n match[1], // key\n match[2], // value\n // || undefined as this is not undefined in IE7 and IE8\n match[3] || undefined // info\n ]);\n }\n\n return data;\n}\n\nexports = {\n ASSUME_CLIENT_HINTS_SUPPORT,\n extractVersionTuples,\n getNativeUserAgentString,\n getUserAgent,\n getUserAgentData,\n matchUserAgent,\n matchUserAgentDataBrand,\n matchUserAgentIgnoreCase,\n resetUserAgentData,\n setUserAgent,\n setUserAgentData,\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Useful compiler idioms.\n */\n\ngoog.provide('goog.reflect');\n\n\n/**\n * Syntax for object literal casts.\n * @see http://go/jscompiler-renaming\n * @see https://goo.gl/CRs09P\n *\n * Use this if you have an object literal whose keys need to have the same names\n * as the properties of some class even after they are renamed by the compiler.\n *\n * @param {!Function} type Type to cast to.\n * @param {Object} object Object literal to cast.\n * @return {Object} The object literal.\n */\ngoog.reflect.object = function(type, object) {\n 'use strict';\n return object;\n};\n\n/**\n * Syntax for renaming property strings.\n * @see http://go/jscompiler-renaming\n * @see https://goo.gl/CRs09P\n *\n * Use this if you have an need to access a property as a string, but want\n * to also have the property renamed by the compiler. In contrast to\n * goog.reflect.object, this method takes an instance of an object.\n *\n * Properties must be simple names (not qualified names).\n *\n * @param {string} prop Name of the property\n * @param {!Object} object Instance of the object whose type will be used\n * for renaming\n * @return {string} The renamed property.\n */\ngoog.reflect.objectProperty = function(prop, object) {\n 'use strict';\n return prop;\n};\n\n/**\n * To assert to the compiler that an operation is needed when it would\n * otherwise be stripped. For example:\n * <code>\n * // Force a layout\n * goog.reflect.sinkValue(dialog.offsetHeight);\n * </code>\n * @param {T} x\n * @return {T}\n * @template T\n */\ngoog.reflect.sinkValue = function(x) {\n 'use strict';\n goog.reflect.sinkValue[' '](x);\n return x;\n};\n\n\n/**\n * The compiler should optimize this function away iff no one ever uses\n * goog.reflect.sinkValue.\n */\ngoog.reflect.sinkValue[' '] = function() {};\n\n\n/**\n * Check if a property can be accessed without throwing an exception.\n * @param {Object} obj The owner of the property.\n * @param {string} prop The property name.\n * @return {boolean} Whether the property is accessible. Will also return true\n * if obj is null.\n */\ngoog.reflect.canAccessProperty = function(obj, prop) {\n 'use strict';\n try {\n goog.reflect.sinkValue(obj[prop]);\n return true;\n } catch (e) {\n }\n return false;\n};\n\n\n/**\n * Retrieves a value from a cache given a key. The compiler provides special\n * consideration for this call such that it is generally considered side-effect\n * free. However, if the `opt_keyFn` or `valueFn` have side-effects\n * then the entire call is considered to have side-effects.\n *\n * Conventionally storing the value on the cache would be considered a\n * side-effect and preclude unused calls from being pruned, ie. even if\n * the value was never used, it would still always be stored in the cache.\n *\n * Providing a side-effect free `valueFn` and `opt_keyFn`\n * allows unused calls to `goog.reflect.cache` to be pruned.\n *\n * @param {!Object<K, V>} cacheObj The object that contains the cached values.\n * @param {?} key The key to lookup in the cache. If it is not string or number\n * then a `opt_keyFn` should be provided. The key is also used as the\n * parameter to the `valueFn`.\n * @param {function(?):V} valueFn The value provider to use to calculate the\n * value to store in the cache. This function should be side-effect free\n * to take advantage of the optimization.\n * @param {function(?):K=} opt_keyFn The key provider to determine the cache\n * map key. This should be used if the given key is not a string or number.\n * If not provided then the given key is used. This function should be\n * side-effect free to take advantage of the optimization.\n * @return {V} The cached or calculated value.\n * @template K\n * @template V\n */\ngoog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {\n 'use strict';\n const storedKey = opt_keyFn ? opt_keyFn(key) : key;\n\n if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {\n return cacheObj[storedKey];\n }\n\n return (cacheObj[storedKey] = valueFn(key));\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Defines an Integer class for representing (potentially)\n * infinite length two's-complement integer values.\n *\n * For the specific case of 64-bit integers, use goog.math.Long, which is more\n * efficient.\n */\n\ngoog.provide('goog.math.Integer');\n\ngoog.require('goog.reflect');\n\n/**\n * Constructs a two's-complement integer an array containing bits of the\n * integer in 32-bit (signed) pieces, given in little-endian order (i.e.,\n * lowest-order bits in the first piece), and the sign of -1 or 0.\n *\n * See the from* functions below for other convenient ways of constructing\n * Integers.\n *\n * The internal representation of an integer is an array of 32-bit signed\n * pieces, along with a sign (0 or -1) that indicates the contents of all the\n * other 32-bit pieces out to infinity. We use 32-bit pieces because these are\n * the size of integers on which JavaScript performs bit-operations. For\n * operations like addition and multiplication, we split each number into 16-bit\n * pieces, which can easily be multiplied within JavaScript's floating-point\n * representation without overflow or change in sign.\n *\n * @struct\n * @constructor\n * @param {Array<number>} bits Array containing the bits of the number.\n * @param {number} sign The sign of the number: -1 for negative and 0 positive.\n * @final\n */\ngoog.math.Integer = function(bits, sign) {\n 'use strict';\n /**\n * @type {number}\n * @private\n */\n this.sign_ = sign;\n\n // Note: using a local variable while initializing the array helps the\n // compiler understand that assigning to the array is local side-effect and\n // that enables the entire constructor to be seen as side-effect free.\n var localBits = [];\n\n // Copy the 32-bit signed integer values passed in. We prune out those at the\n // top that equal the sign since they are redundant.\n var top = true;\n\n for (var i = bits.length - 1; i >= 0; i--) {\n var val = bits[i] | 0;\n if (!top || val != sign) {\n localBits[i] = val;\n top = false;\n }\n }\n\n /**\n * @type {!Array<number>}\n * @private\n * @const\n */\n this.bits_ = localBits;\n};\n\n\n// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the\n// from* methods on which they depend.\n\n\n/**\n * A cache of the Integer representations of small integer values.\n * @type {!Object<number, !goog.math.Integer>}\n * @private\n */\ngoog.math.Integer.IntCache_ = {};\n\n\n/**\n * Returns an Integer representing the given (32-bit) integer value.\n * @param {number} value A 32-bit integer value.\n * @return {!goog.math.Integer} The corresponding Integer value.\n */\ngoog.math.Integer.fromInt = function(value) {\n 'use strict';\n if (-128 <= value && value < 128) {\n return goog.reflect.cache(\n goog.math.Integer.IntCache_, value, function(val) {\n 'use strict';\n return new goog.math.Integer([val | 0], val < 0 ? -1 : 0);\n });\n }\n return new goog.math.Integer([value | 0], value < 0 ? -1 : 0);\n};\n\n\n/**\n * Returns an Integer representing the given value, provided that it is a finite\n * number. Otherwise, zero is returned.\n * @param {number} value The value in question.\n * @return {!goog.math.Integer} The corresponding Integer value.\n */\ngoog.math.Integer.fromNumber = function(value) {\n 'use strict';\n if (isNaN(value) || !isFinite(value)) {\n return goog.math.Integer.ZERO;\n } else if (value < 0) {\n return goog.math.Integer.fromNumber(-value).negate();\n } else {\n var bits = [];\n var pow = 1;\n for (var i = 0; value >= pow; i++) {\n bits[i] = (value / pow) | 0;\n pow *= goog.math.Integer.TWO_PWR_32_DBL_;\n }\n return new goog.math.Integer(bits, 0);\n }\n};\n\n\n/**\n * Returns a Integer representing the value that comes by concatenating the\n * given entries, each is assumed to be 32 signed bits, given in little-endian\n * order (lowest order bits in the lowest index), and sign-extending the highest\n * order 32-bit value.\n * @param {Array<number>} bits The bits of the number, in 32-bit signed pieces,\n * in little-endian order.\n * @return {!goog.math.Integer} The corresponding Integer value.\n */\ngoog.math.Integer.fromBits = function(bits) {\n 'use strict';\n var high = bits[bits.length - 1];\n return new goog.math.Integer(bits, high & (1 << 31) ? -1 : 0);\n};\n\n\n/**\n * Returns an Integer representation of the given string, written using the\n * given radix.\n * @param {string} str The textual representation of the Integer.\n * @param {number=} opt_radix The radix in which the text is written.\n * @return {!goog.math.Integer} The corresponding Integer value.\n */\ngoog.math.Integer.fromString = function(str, opt_radix) {\n 'use strict';\n if (str.length == 0) {\n throw new Error('number format error: empty string');\n }\n\n var radix = opt_radix || 10;\n if (radix < 2 || 36 < radix) {\n throw new Error('radix out of range: ' + radix);\n }\n\n if (str.charAt(0) == '-') {\n return goog.math.Integer.fromString(str.substring(1), radix).negate();\n } else if (str.indexOf('-') >= 0) {\n throw new Error('number format error: interior \"-\" character');\n }\n\n // Do several (8) digits each time through the loop, so as to\n // minimize the calls to the very expensive emulated div.\n var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 8));\n\n var result = goog.math.Integer.ZERO;\n for (var i = 0; i < str.length; i += 8) {\n var size = Math.min(8, str.length - i);\n var value = parseInt(str.substring(i, i + size), radix);\n if (size < 8) {\n var power = goog.math.Integer.fromNumber(Math.pow(radix, size));\n result = result.multiply(power).add(goog.math.Integer.fromNumber(value));\n } else {\n result = result.multiply(radixToPower);\n result = result.add(goog.math.Integer.fromNumber(value));\n }\n }\n return result;\n};\n\n\n/**\n * A number used repeatedly in calculations. This must appear before the first\n * call to the from* functions below.\n * @type {number}\n * @private\n */\ngoog.math.Integer.TWO_PWR_32_DBL_ = (1 << 16) * (1 << 16);\n\n\n/** @type {!goog.math.Integer} */\ngoog.math.Integer.ZERO = goog.math.Integer.fromInt(0);\n\n/** @type {!goog.math.Integer} */\ngoog.math.Integer.ONE = goog.math.Integer.fromInt(1);\n\n\n/**\n * @const\n * @type {!goog.math.Integer}\n * @private\n */\ngoog.math.Integer.TWO_PWR_24_ = goog.math.Integer.fromInt(1 << 24);\n\n/**\n * Returns the value, assuming it is a 32-bit integer.\n * @return {number} The corresponding int value.\n */\ngoog.math.Integer.prototype.toInt = function() {\n 'use strict';\n return this.bits_.length > 0 ? this.bits_[0] : this.sign_;\n};\n\n\n/** @return {number} The closest floating-point representation to this value. */\ngoog.math.Integer.prototype.toNumber = function() {\n 'use strict';\n if (this.isNegative()) {\n return -this.negate().toNumber();\n } else {\n var val = 0;\n var pow = 1;\n for (var i = 0; i < this.bits_.length; i++) {\n val += this.getBitsUnsigned(i) * pow;\n pow *= goog.math.Integer.TWO_PWR_32_DBL_;\n }\n return val;\n }\n};\n\n\n/**\n * @param {number=} opt_radix The radix in which the text should be written.\n * @return {string} The textual representation of this value.\n * @override\n */\ngoog.math.Integer.prototype.toString = function(opt_radix) {\n 'use strict';\n var radix = opt_radix || 10;\n if (radix < 2 || 36 < radix) {\n throw new Error('radix out of range: ' + radix);\n }\n\n if (this.isZero()) {\n return '0';\n } else if (this.isNegative()) {\n return '-' + this.negate().toString(radix);\n }\n\n // Do several (6) digits each time through the loop, so as to\n // minimize the calls to the very expensive emulated div.\n var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 6));\n\n var rem = this;\n var result = '';\n while (true) {\n var remDiv = rem.divide(radixToPower);\n // The right shifting fixes negative values in the case when\n // intval >= 2^31; for more details see\n // https://github.com/google/closure-library/pull/498\n var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0;\n var digits = intval.toString(radix);\n\n rem = remDiv;\n if (rem.isZero()) {\n return digits + result;\n } else {\n while (digits.length < 6) {\n digits = '0' + digits;\n }\n result = '' + digits + result;\n }\n }\n};\n\n\n/**\n * Returns the index-th 32-bit (signed) piece of the Integer according to\n * little-endian order (i.e., index 0 contains the smallest bits).\n * @param {number} index The index in question.\n * @return {number} The requested 32-bits as a signed number.\n */\ngoog.math.Integer.prototype.getBits = function(index) {\n 'use strict';\n if (index < 0) {\n return 0; // Allowing this simplifies bit shifting operations below...\n } else if (index < this.bits_.length) {\n return this.bits_[index];\n } else {\n return this.sign_;\n }\n};\n\n\n/**\n * Returns the index-th 32-bit piece as an unsigned number.\n * @param {number} index The index in question.\n * @return {number} The requested 32-bits as an unsigned number.\n */\ngoog.math.Integer.prototype.getBitsUnsigned = function(index) {\n 'use strict';\n var val = this.getBits(index);\n return val >= 0 ? val : goog.math.Integer.TWO_PWR_32_DBL_ + val;\n};\n\n\n/** @return {number} The sign bit of this number, -1 or 0. */\ngoog.math.Integer.prototype.getSign = function() {\n 'use strict';\n return this.sign_;\n};\n\n\n/** @return {boolean} Whether this value is zero. */\ngoog.math.Integer.prototype.isZero = function() {\n 'use strict';\n if (this.sign_ != 0) {\n return false;\n }\n for (var i = 0; i < this.bits_.length; i++) {\n if (this.bits_[i] != 0) {\n return false;\n }\n }\n return true;\n};\n\n\n/** @return {boolean} Whether this value is negative. */\ngoog.math.Integer.prototype.isNegative = function() {\n 'use strict';\n return this.sign_ == -1;\n};\n\n\n/** @return {boolean} Whether this value is odd. */\ngoog.math.Integer.prototype.isOdd = function() {\n 'use strict';\n return (this.bits_.length == 0) && (this.sign_ == -1) ||\n (this.bits_.length > 0) && ((this.bits_[0] & 1) != 0);\n};\n\n\n/**\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {boolean} Whether this Integer equals the other.\n */\ngoog.math.Integer.prototype.equals = function(other) {\n 'use strict';\n if (this.sign_ != other.sign_) {\n return false;\n }\n var len = Math.max(this.bits_.length, other.bits_.length);\n for (var i = 0; i < len; i++) {\n if (this.getBits(i) != other.getBits(i)) {\n return false;\n }\n }\n return true;\n};\n\n\n/**\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {boolean} Whether this Integer does not equal the other.\n */\ngoog.math.Integer.prototype.notEquals = function(other) {\n 'use strict';\n return !this.equals(other);\n};\n\n\n/**\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {boolean} Whether this Integer is greater than the other.\n */\ngoog.math.Integer.prototype.greaterThan = function(other) {\n 'use strict';\n return this.compare(other) > 0;\n};\n\n\n/**\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {boolean} Whether this Integer is greater than or equal to the other.\n */\ngoog.math.Integer.prototype.greaterThanOrEqual = function(other) {\n 'use strict';\n return this.compare(other) >= 0;\n};\n\n\n/**\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {boolean} Whether this Integer is less than the other.\n */\ngoog.math.Integer.prototype.lessThan = function(other) {\n 'use strict';\n return this.compare(other) < 0;\n};\n\n\n/**\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {boolean} Whether this Integer is less than or equal to the other.\n */\ngoog.math.Integer.prototype.lessThanOrEqual = function(other) {\n 'use strict';\n return this.compare(other) <= 0;\n};\n\n\n/**\n * Compares this Integer with the given one.\n * @param {goog.math.Integer} other Integer to compare against.\n * @return {number} 0 if they are the same, 1 if the this is greater, and -1\n * if the given one is greater.\n */\ngoog.math.Integer.prototype.compare = function(other) {\n 'use strict';\n var diff = this.subtract(other);\n if (diff.isNegative()) {\n return -1;\n } else if (diff.isZero()) {\n return 0;\n } else {\n return +1;\n }\n};\n\n\n/**\n * Returns an integer with only the first numBits bits of this value, sign\n * extended from the final bit.\n * @param {number} numBits The number of bits by which to shift.\n * @return {!goog.math.Integer} The shorted integer value.\n */\ngoog.math.Integer.prototype.shorten = function(numBits) {\n 'use strict';\n var arr_index = (numBits - 1) >> 5;\n var bit_index = (numBits - 1) % 32;\n var bits = [];\n for (var i = 0; i < arr_index; i++) {\n bits[i] = this.getBits(i);\n }\n var sigBits = bit_index == 31 ? 0xFFFFFFFF : (1 << (bit_index + 1)) - 1;\n var val = this.getBits(arr_index) & sigBits;\n if (val & (1 << bit_index)) {\n val |= 0xFFFFFFFF - sigBits;\n bits[arr_index] = val;\n return new goog.math.Integer(bits, -1);\n } else {\n bits[arr_index] = val;\n return new goog.math.Integer(bits, 0);\n }\n};\n\n\n/** @return {!goog.math.Integer} The negation of this value. */\ngoog.math.Integer.prototype.negate = function() {\n 'use strict';\n return this.not().add(goog.math.Integer.ONE);\n};\n\n\n/** @return {!goog.math.Integer} The absolute value of this value. */\ngoog.math.Integer.prototype.abs = function() {\n 'use strict';\n return this.isNegative() ? this.negate() : this;\n};\n\n\n/**\n * Returns the sum of this and the given Integer.\n * @param {goog.math.Integer} other The Integer to add to this.\n * @return {!goog.math.Integer} The Integer result.\n */\ngoog.math.Integer.prototype.add = function(other) {\n 'use strict';\n var len = Math.max(this.bits_.length, other.bits_.length);\n var arr = [];\n var carry = 0;\n\n for (var i = 0; i <= len; i++) {\n var a1 = this.getBits(i) >>> 16;\n var a0 = this.getBits(i) & 0xFFFF;\n\n var b1 = other.getBits(i) >>> 16;\n var b0 = other.getBits(i) & 0xFFFF;\n\n var c0 = carry + a0 + b0;\n var c1 = (c0 >>> 16) + a1 + b1;\n carry = c1 >>> 16;\n c0 &= 0xFFFF;\n c1 &= 0xFFFF;\n arr[i] = (c1 << 16) | c0;\n }\n return goog.math.Integer.fromBits(arr);\n};\n\n\n/**\n * Returns the difference of this and the given Integer.\n * @param {goog.math.Integer} other The Integer to subtract from this.\n * @return {!goog.math.Integer} The Integer result.\n */\ngoog.math.Integer.prototype.subtract = function(other) {\n 'use strict';\n return this.add(other.negate());\n};\n\n\n/**\n * Returns the product of this and the given Integer.\n * @param {goog.math.Integer} other The Integer to multiply against this.\n * @return {!goog.math.Integer} The product of this and the other.\n */\ngoog.math.Integer.prototype.multiply = function(other) {\n 'use strict';\n if (this.isZero()) {\n return goog.math.Integer.ZERO;\n } else if (other.isZero()) {\n return goog.math.Integer.ZERO;\n }\n\n if (this.isNegative()) {\n if (other.isNegative()) {\n return this.negate().multiply(other.negate());\n } else {\n return this.negate().multiply(other).negate();\n }\n } else if (other.isNegative()) {\n return this.multiply(other.negate()).negate();\n }\n\n // If both numbers are small, use float multiplication\n if (this.lessThan(goog.math.Integer.TWO_PWR_24_) &&\n other.lessThan(goog.math.Integer.TWO_PWR_24_)) {\n return goog.math.Integer.fromNumber(this.toNumber() * other.toNumber());\n }\n\n // Fill in an array of 16-bit products.\n var len = this.bits_.length + other.bits_.length;\n var arr = [];\n for (var i = 0; i < 2 * len; i++) {\n arr[i] = 0;\n }\n for (var i = 0; i < this.bits_.length; i++) {\n for (var j = 0; j < other.bits_.length; j++) {\n var a1 = this.getBits(i) >>> 16;\n var a0 = this.getBits(i) & 0xFFFF;\n\n var b1 = other.getBits(j) >>> 16;\n var b0 = other.getBits(j) & 0xFFFF;\n\n arr[2 * i + 2 * j] += a0 * b0;\n goog.math.Integer.carry16_(arr, 2 * i + 2 * j);\n arr[2 * i + 2 * j + 1] += a1 * b0;\n goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);\n arr[2 * i + 2 * j + 1] += a0 * b1;\n goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);\n arr[2 * i + 2 * j + 2] += a1 * b1;\n goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 2);\n }\n }\n\n // Combine the 16-bit values into 32-bit values.\n for (var i = 0; i < len; i++) {\n arr[i] = (arr[2 * i + 1] << 16) | arr[2 * i];\n }\n for (var i = len; i < 2 * len; i++) {\n arr[i] = 0;\n }\n return new goog.math.Integer(arr, 0);\n};\n\n\n/**\n * Carries any overflow from the given index into later entries.\n * @param {Array<number>} bits Array of 16-bit values in little-endian order.\n * @param {number} index The index in question.\n * @private\n */\ngoog.math.Integer.carry16_ = function(bits, index) {\n 'use strict';\n while ((bits[index] & 0xFFFF) != bits[index]) {\n bits[index + 1] += bits[index] >>> 16;\n bits[index] &= 0xFFFF;\n index++;\n }\n};\n\n\n/**\n * Returns \"this\" Integer divided by the given one. Both \"this\" and the given\n * Integer MUST be positive.\n *\n * This method is only needed for very large numbers (>10^308),\n * for which the original division algorithm gets into an infinite\n * loop (see https://github.com/google/closure-library/issues/500).\n *\n * The algorithm has some possible performance enhancements (or\n * could be rewritten entirely), it's just an initial solution for\n * the issue linked above.\n *\n * @param {!goog.math.Integer} other The Integer to divide \"this\" by.\n * @return {!goog.math.Integer.DivisionResult}\n * @private\n */\ngoog.math.Integer.prototype.slowDivide_ = function(other) {\n 'use strict';\n if (this.isNegative() || other.isNegative()) {\n throw new Error('slowDivide_ only works with positive integers.');\n }\n\n var twoPower = goog.math.Integer.ONE;\n var multiple = other;\n\n // First we have to figure out what the highest bit of the result\n // is, so we increase \"twoPower\" and \"multiple\" until \"multiple\"\n // exceeds \"this\".\n while (multiple.lessThanOrEqual(this)) {\n twoPower = twoPower.shiftLeft(1);\n multiple = multiple.shiftLeft(1);\n }\n\n // Rewind by one power of two, giving us the highest bit of the\n // result.\n var res = twoPower.shiftRight(1);\n var total = multiple.shiftRight(1);\n\n // Now we starting decreasing \"multiple\" and \"twoPower\" to find the\n // rest of the bits of the result.\n var total2;\n multiple = multiple.shiftRight(2);\n twoPower = twoPower.shiftRight(2);\n while (!multiple.isZero()) {\n // whenever we can add \"multiple\" to the total and not exceed\n // \"this\", that means we've found a 1 bit. Else we've found a 0\n // and don't need to add to the result.\n total2 = total.add(multiple);\n if (total2.lessThanOrEqual(this)) {\n res = res.add(twoPower);\n total = total2;\n }\n multiple = multiple.shiftRight(1);\n twoPower = twoPower.shiftRight(1);\n }\n\n\n // TODO(user): Calculate this more efficiently during the division.\n // This is kind of a waste since it isn't always needed, but it keeps the\n // API smooth. Since this is already a slow path it probably isn't a big deal.\n var remainder = this.subtract(res.multiply(other));\n return new goog.math.Integer.DivisionResult(res, remainder);\n};\n\n\n/**\n * Returns this Integer divided by the given one.\n * @param {!goog.math.Integer} other The Integer to divide this by.\n * @return {!goog.math.Integer} This value divided by the given one.\n */\ngoog.math.Integer.prototype.divide = function(other) {\n 'use strict';\n return this.divideAndRemainder(other).quotient;\n};\n\n\n/**\n * A struct for holding the quotient and remainder of a division.\n *\n * @constructor\n * @final\n * @struct\n *\n * @param {!goog.math.Integer} quotient\n * @param {!goog.math.Integer} remainder\n */\ngoog.math.Integer.DivisionResult = function(quotient, remainder) {\n 'use strict';\n /** @const */\n this.quotient = quotient;\n\n /** @const */\n this.remainder = remainder;\n};\n\n\n/**\n * Returns this Integer divided by the given one, as well as the remainder of\n * that division.\n *\n * @param {!goog.math.Integer} other The Integer to divide this by.\n * @return {!goog.math.Integer.DivisionResult}\n */\ngoog.math.Integer.prototype.divideAndRemainder = function(other) {\n 'use strict';\n if (other.isZero()) {\n throw new Error('division by zero');\n } else if (this.isZero()) {\n return new goog.math.Integer.DivisionResult(\n goog.math.Integer.ZERO, goog.math.Integer.ZERO);\n }\n\n if (this.isNegative()) {\n // Do the division on the negative of the numerator...\n var result = this.negate().divideAndRemainder(other);\n return new goog.math.Integer.DivisionResult(\n // ...and flip the sign back after.\n result.quotient.negate(),\n // The remainder must always have the same sign as the numerator.\n result.remainder.negate());\n } else if (other.isNegative()) {\n // Do the division on the negative of the denominator...\n var result = this.divideAndRemainder(other.negate());\n return new goog.math.Integer.DivisionResult(\n // ...and flip the sign back after.\n result.quotient.negate(),\n // The remainder must always have the same sign as the numerator.\n result.remainder);\n }\n\n // Have to degrade to slowDivide for Very Large Numbers, because\n // they're out of range for the floating-point approximation\n // technique used below.\n if (this.bits_.length > 30) {\n return this.slowDivide_(other);\n }\n\n // Repeat the following until the remainder is less than other: find a\n // floating-point that approximates remainder / other *from below*, add this\n // into the result, and subtract it from the remainder. It is critical that\n // the approximate value is less than or equal to the real value so that the\n // remainder never becomes negative.\n var res = goog.math.Integer.ZERO;\n var rem = this;\n while (rem.greaterThanOrEqual(other)) {\n // Approximate the result of division. This may be a little greater or\n // smaller than the actual value.\n var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));\n\n // We will tweak the approximate result by changing it in the 48-th digit or\n // the smallest non-fractional digit, whichever is larger.\n var log2 = Math.ceil(Math.log(approx) / Math.LN2);\n var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);\n\n // Decrease the approximation until it is smaller than the remainder. Note\n // that if it is too large, the product overflows and is negative.\n var approxRes = goog.math.Integer.fromNumber(approx);\n var approxRem = approxRes.multiply(other);\n while (approxRem.isNegative() || approxRem.greaterThan(rem)) {\n approx -= delta;\n approxRes = goog.math.Integer.fromNumber(approx);\n approxRem = approxRes.multiply(other);\n }\n\n // We know the answer can't be zero... and actually, zero would cause\n // infinite recursion since we would make no progress.\n if (approxRes.isZero()) {\n approxRes = goog.math.Integer.ONE;\n }\n\n res = res.add(approxRes);\n rem = rem.subtract(approxRem);\n }\n return new goog.math.Integer.DivisionResult(res, rem);\n};\n\n\n/**\n * Returns this Integer modulo the given one.\n * @param {!goog.math.Integer} other The Integer by which to mod.\n * @return {!goog.math.Integer} This value modulo the given one.\n */\ngoog.math.Integer.prototype.modulo = function(other) {\n 'use strict';\n return this.divideAndRemainder(other).remainder;\n};\n\n\n/** @return {!goog.math.Integer} The bitwise-NOT of this value. */\ngoog.math.Integer.prototype.not = function() {\n 'use strict';\n var len = this.bits_.length;\n var arr = [];\n for (var i = 0; i < len; i++) {\n arr[i] = ~this.bits_[i];\n }\n return new goog.math.Integer(arr, ~this.sign_);\n};\n\n\n/**\n * Returns the bitwise-AND of this Integer and the given one.\n * @param {goog.math.Integer} other The Integer to AND with this.\n * @return {!goog.math.Integer} The bitwise-AND of this and the other.\n */\ngoog.math.Integer.prototype.and = function(other) {\n 'use strict';\n var len = Math.max(this.bits_.length, other.bits_.length);\n var arr = [];\n for (var i = 0; i < len; i++) {\n arr[i] = this.getBits(i) & other.getBits(i);\n }\n return new goog.math.Integer(arr, this.sign_ & other.sign_);\n};\n\n\n/**\n * Returns the bitwise-OR of this Integer and the given one.\n * @param {goog.math.Integer} other The Integer to OR with this.\n * @return {!goog.math.Integer} The bitwise-OR of this and the other.\n */\ngoog.math.Integer.prototype.or = function(other) {\n 'use strict';\n var len = Math.max(this.bits_.length, other.bits_.length);\n var arr = [];\n for (var i = 0; i < len; i++) {\n arr[i] = this.getBits(i) | other.getBits(i);\n }\n return new goog.math.Integer(arr, this.sign_ | other.sign_);\n};\n\n\n/**\n * Returns the bitwise-XOR of this Integer and the given one.\n * @param {goog.math.Integer} other The Integer to XOR with this.\n * @return {!goog.math.Integer} The bitwise-XOR of this and the other.\n */\ngoog.math.Integer.prototype.xor = function(other) {\n 'use strict';\n var len = Math.max(this.bits_.length, other.bits_.length);\n var arr = [];\n for (var i = 0; i < len; i++) {\n arr[i] = this.getBits(i) ^ other.getBits(i);\n }\n return new goog.math.Integer(arr, this.sign_ ^ other.sign_);\n};\n\n\n/**\n * Returns this value with bits shifted to the left by the given amount.\n * @param {number} numBits The number of bits by which to shift.\n * @return {!goog.math.Integer} This shifted to the left by the given amount.\n */\ngoog.math.Integer.prototype.shiftLeft = function(numBits) {\n 'use strict';\n var arr_delta = numBits >> 5;\n var bit_delta = numBits % 32;\n var len = this.bits_.length + arr_delta + (bit_delta > 0 ? 1 : 0);\n var arr = [];\n for (var i = 0; i < len; i++) {\n if (bit_delta > 0) {\n arr[i] = (this.getBits(i - arr_delta) << bit_delta) |\n (this.getBits(i - arr_delta - 1) >>> (32 - bit_delta));\n } else {\n arr[i] = this.getBits(i - arr_delta);\n }\n }\n return new goog.math.Integer(arr, this.sign_);\n};\n\n\n/**\n * Returns this value with bits shifted to the right by the given amount.\n * @param {number} numBits The number of bits by which to shift.\n * @return {!goog.math.Integer} This shifted to the right by the given amount.\n */\ngoog.math.Integer.prototype.shiftRight = function(numBits) {\n 'use strict';\n var arr_delta = numBits >> 5;\n var bit_delta = numBits % 32;\n var len = this.bits_.length - arr_delta;\n var arr = [];\n for (var i = 0; i < len; i++) {\n if (bit_delta > 0) {\n arr[i] = (this.getBits(i + arr_delta) >>> bit_delta) |\n (this.getBits(i + arr_delta + 1) << (32 - bit_delta));\n } else {\n arr[i] = this.getBits(i + arr_delta);\n }\n }\n return new goog.math.Integer(arr, this.sign_);\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Rendering engine detection.\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>\n * For information on the browser brand (such as Safari versus Chrome), see\n * goog.userAgent.product.\n * @see ../demos/useragent.html\n */\n\ngoog.provide('goog.userAgent');\n\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.reflect');\ngoog.require('goog.string.internal');\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is IE.\n */\ngoog.userAgent.ASSUME_IE = goog.define('goog.userAgent.ASSUME_IE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is EDGE,\n * referring to EdgeHTML based Edge.\n */\ngoog.userAgent.ASSUME_EDGE = goog.define('goog.userAgent.ASSUME_EDGE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is GECKO.\n */\ngoog.userAgent.ASSUME_GECKO = goog.define('goog.userAgent.ASSUME_GECKO', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is WEBKIT.\n */\ngoog.userAgent.ASSUME_WEBKIT =\n goog.define('goog.userAgent.ASSUME_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is a\n * mobile device running WebKit e.g. iPhone or Android.\n */\ngoog.userAgent.ASSUME_MOBILE_WEBKIT =\n goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is OPERA,\n * referring to Presto-based Opera.\n */\ngoog.userAgent.ASSUME_OPERA = goog.define('goog.userAgent.ASSUME_OPERA', false);\n\n\n/**\n * @define {boolean} Whether the\n * `goog.userAgent.isVersionOrHigher`\n * function will return true for any version.\n */\ngoog.userAgent.ASSUME_ANY_VERSION =\n goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);\n\n\n/**\n * Whether we know the browser engine at compile-time.\n * @type {boolean}\n * @private\n */\ngoog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||\n goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||\n goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||\n goog.userAgent.ASSUME_OPERA;\n\n\n/**\n * Returns the userAgent string for the current browser.\n *\n * @return {string} The userAgent string.\n */\ngoog.userAgent.getUserAgentString = function() {\n 'use strict';\n return goog.labs.userAgent.util.getUserAgent();\n};\n\n\n/**\n * @return {?Navigator} The native navigator object.\n */\ngoog.userAgent.getNavigatorTyped = function() {\n 'use strict';\n // Need a local navigator reference instead of using the global one,\n // to avoid the rare case where they reference different objects.\n // (in a WorkerPool, for example).\n return goog.global['navigator'] || null;\n};\n\n\n/**\n * TODO(nnaze): Change type to \"Navigator\" and update compilation targets.\n * @return {?Object} The native navigator object.\n */\ngoog.userAgent.getNavigator = function() {\n 'use strict';\n return goog.userAgent.getNavigatorTyped();\n};\n\n\n/**\n * Whether the user agent is Presto-based Opera.\n * @type {boolean}\n */\ngoog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_OPERA :\n goog.labs.userAgent.browser.isOpera();\n\n\n/**\n * Whether the user agent is Internet Explorer.\n * @type {boolean}\n */\ngoog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_IE :\n goog.labs.userAgent.browser.isIE();\n\n\n/**\n * Whether the user agent is Microsoft Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_EDGE :\n goog.labs.userAgent.engine.isEdge();\n\n\n/**\n * Whether the user agent is MS Internet Explorer or MS Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;\n\n\n/**\n * Whether the user agent is Gecko. Gecko is the rendering engine used by\n * Mozilla, Firefox, and others.\n * @type {boolean}\n */\ngoog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_GECKO :\n goog.labs.userAgent.engine.isGecko();\n\n\n/**\n * Whether the user agent is WebKit. WebKit is the rendering engine that\n * Safari, Edge Chromium, Opera Chromium, Android and others use.\n * @type {boolean}\n */\ngoog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :\n goog.labs.userAgent.engine.isWebKit();\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * This is a separate function so that the logic can be tested.\n *\n * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().\n *\n * @return {boolean} Whether the user agent is running on a mobile device.\n * @private\n */\ngoog.userAgent.isMobile_ = function() {\n 'use strict';\n return goog.userAgent.WEBKIT &&\n goog.labs.userAgent.util.matchUserAgent('Mobile');\n};\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent\n * is promoted as the gecko/webkit logic is likely inaccurate.\n *\n * @type {boolean}\n */\ngoog.userAgent.MOBILE =\n goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();\n\n\n/**\n * Used while transitioning code to use WEBKIT instead.\n * @type {boolean}\n * @deprecated Use {@link goog.userAgent.product.SAFARI} instead.\n * TODO(nicksantos): Delete this from goog.userAgent.\n */\ngoog.userAgent.SAFARI = goog.userAgent.WEBKIT;\n\n\n/**\n * @return {string} the platform (operating system) the user agent is running\n * on. Default to empty string because navigator.platform may not be defined\n * (on Rhino, for example).\n * @private\n */\ngoog.userAgent.determinePlatform_ = function() {\n 'use strict';\n var navigator = goog.userAgent.getNavigatorTyped();\n return navigator && navigator.platform || '';\n};\n\n\n/**\n * The platform (operating system) the user agent is running on. Default to\n * empty string because navigator.platform may not be defined (on Rhino, for\n * example).\n * @type {string}\n */\ngoog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Macintosh operating\n * system.\n */\ngoog.userAgent.ASSUME_MAC = goog.define('goog.userAgent.ASSUME_MAC', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Windows operating\n * system.\n */\ngoog.userAgent.ASSUME_WINDOWS =\n goog.define('goog.userAgent.ASSUME_WINDOWS', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Linux operating\n * system.\n */\ngoog.userAgent.ASSUME_LINUX = goog.define('goog.userAgent.ASSUME_LINUX', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on Android.\n */\ngoog.userAgent.ASSUME_ANDROID =\n goog.define('goog.userAgent.ASSUME_ANDROID', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPhone.\n */\ngoog.userAgent.ASSUME_IPHONE =\n goog.define('goog.userAgent.ASSUME_IPHONE', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPad.\n */\ngoog.userAgent.ASSUME_IPAD = goog.define('goog.userAgent.ASSUME_IPAD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPod.\n */\ngoog.userAgent.ASSUME_IPOD = goog.define('goog.userAgent.ASSUME_IPOD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on KaiOS.\n */\ngoog.userAgent.ASSUME_KAIOS = goog.define('goog.userAgent.ASSUME_KAIOS', false);\n\n\n/**\n * @type {boolean}\n * @private\n */\ngoog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||\n goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||\n goog.userAgent.ASSUME_ANDROID || goog.userAgent.ASSUME_IPHONE ||\n goog.userAgent.ASSUME_IPAD || goog.userAgent.ASSUME_IPOD;\n\n\n/**\n * Whether the user agent is running on a Macintosh operating system.\n * @type {boolean}\n */\ngoog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_MAC :\n goog.labs.userAgent.platform.isMacintosh();\n\n\n/**\n * Whether the user agent is running on a Windows operating system.\n * @type {boolean}\n */\ngoog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_WINDOWS :\n goog.labs.userAgent.platform.isWindows();\n\n\n/**\n * Whether the user agent is Linux per the legacy behavior of\n * goog.userAgent.LINUX, which considered ChromeOS to also be\n * Linux.\n * @return {boolean}\n * @private\n */\ngoog.userAgent.isLegacyLinux_ = function() {\n 'use strict';\n return goog.labs.userAgent.platform.isLinux() ||\n goog.labs.userAgent.platform.isChromeOS();\n};\n\n\n/**\n * Whether the user agent is running on a Linux operating system.\n *\n * Note that goog.userAgent.LINUX considers ChromeOS to be Linux,\n * while goog.labs.userAgent.platform considers ChromeOS and\n * Linux to be different OSes.\n *\n * @type {boolean}\n */\ngoog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_LINUX :\n goog.userAgent.isLegacyLinux_();\n\n\n/**\n * Whether the user agent is running on Android.\n * @type {boolean}\n */\ngoog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_ANDROID :\n goog.labs.userAgent.platform.isAndroid();\n\n\n/**\n * Whether the user agent is running on an iPhone.\n * @type {boolean}\n */\ngoog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_IPHONE :\n goog.labs.userAgent.platform.isIphone();\n\n\n/**\n * Whether the user agent is running on an iPad.\n * @type {boolean}\n */\ngoog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_IPAD :\n goog.labs.userAgent.platform.isIpad();\n\n\n/**\n * Whether the user agent is running on an iPod.\n * @type {boolean}\n */\ngoog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_IPOD :\n goog.labs.userAgent.platform.isIpod();\n\n\n/**\n * Whether the user agent is running on iOS.\n * @type {boolean}\n */\ngoog.userAgent.IOS = goog.userAgent.PLATFORM_KNOWN_ ?\n (goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n goog.userAgent.ASSUME_IPOD) :\n goog.labs.userAgent.platform.isIos();\n\n/**\n * Whether the user agent is running on KaiOS.\n * @type {boolean}\n */\ngoog.userAgent.KAIOS = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_KAIOS :\n goog.labs.userAgent.platform.isKaiOS();\n\n\n/**\n * @return {string} The string that describes the version number of the user\n * agent.\n * @private\n */\ngoog.userAgent.determineVersion_ = function() {\n 'use strict';\n // All browsers have different ways to detect the version and they all have\n // different naming schemes.\n // version is a string rather than a number because it may contain 'b', 'a',\n // and so on.\n var version = '';\n var arr = goog.userAgent.getVersionRegexResult_();\n if (arr) {\n version = arr ? arr[1] : '';\n }\n\n if (goog.userAgent.IE) {\n // IE9 can be in document mode 9 but be reporting an inconsistent user agent\n // version. If it is identifying as a version lower than 9 we take the\n // documentMode as the version instead. IE8 has similar behavior.\n // It is recommended to set the X-UA-Compatible header to ensure that IE9\n // uses documentMode 9.\n var docMode = goog.userAgent.getDocumentMode_();\n if (docMode != null && docMode > parseFloat(version)) {\n return String(docMode);\n }\n }\n\n return version;\n};\n\n\n/**\n * @return {?IArrayLike<string>|undefined} The version regex matches from\n * parsing the user\n * agent string. These regex statements must be executed inline so they can\n * be compiled out by the closure compiler with the rest of the useragent\n * detection logic when ASSUME_* is specified.\n * @private\n */\ngoog.userAgent.getVersionRegexResult_ = function() {\n 'use strict';\n var userAgent = goog.userAgent.getUserAgentString();\n if (goog.userAgent.GECKO) {\n return /rv\\:([^\\);]+)(\\)|;)/.exec(userAgent);\n }\n if (goog.userAgent.EDGE) {\n return /Edge\\/([\\d\\.]+)/.exec(userAgent);\n }\n if (goog.userAgent.IE) {\n return /\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(userAgent);\n }\n if (goog.userAgent.WEBKIT) {\n // WebKit/125.4\n return /WebKit\\/(\\S+)/.exec(userAgent);\n }\n if (goog.userAgent.OPERA) {\n // If none of the above browsers were detected but the browser is Opera, the\n // only string that is of interest is 'Version/<number>'.\n return /(?:Version)[ \\/]?(\\S+)/.exec(userAgent);\n }\n return undefined;\n};\n\n\n/**\n * @return {number|undefined} Returns the document mode (for testing).\n * @private\n */\ngoog.userAgent.getDocumentMode_ = function() {\n 'use strict';\n // NOTE(user): goog.userAgent may be used in context where there is no DOM.\n var doc = goog.global['document'];\n return doc ? doc['documentMode'] : undefined;\n};\n\n\n/**\n * The version of the user agent. This is a string because it might contain\n * 'b' (as in beta) as well as multiple dots.\n * @type {string}\n */\ngoog.userAgent.VERSION = goog.userAgent.determineVersion_();\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string} v1 Version of first item.\n * @param {string} v2 Version of second item.\n *\n * @return {number} 1 if first argument is higher\n * 0 if arguments are equal\n * -1 if second argument is higher.\n * @deprecated Use goog.string.compareVersions.\n */\ngoog.userAgent.compare = function(v1, v2) {\n 'use strict';\n return goog.string.internal.compareVersions(v1, v2);\n};\n\n\n/**\n * Cache for {@link goog.userAgent.isVersionOrHigher}.\n * Calls to compareVersions are surprisingly expensive and, as a browser's\n * version number is unlikely to change during a session, we cache the results.\n * @const\n * @private\n */\ngoog.userAgent.isVersionOrHigherCache_ = {};\n\n\n/**\n * Whether the user agent version is higher or the same as the given version.\n * NOTE: When checking the version numbers for Firefox and Safari, be sure to\n * use the engine's version, not the browser's version number. For example,\n * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.\n * Opera and Internet Explorer versions match the product release number.<br>\n * @see <a href=\"http://en.wikipedia.org/wiki/Safari_version_history\">\n * Webkit</a>\n * @see <a href=\"http://en.wikipedia.org/wiki/Gecko_engine\">Gecko</a>\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent version is higher or the same as\n * the given version.\n */\ngoog.userAgent.isVersionOrHigher = function(version) {\n 'use strict';\n return goog.userAgent.ASSUME_ANY_VERSION ||\n goog.reflect.cache(\n goog.userAgent.isVersionOrHigherCache_, version, function() {\n 'use strict';\n return goog.string.internal.compareVersions(\n goog.userAgent.VERSION, version) >= 0;\n });\n};\n\n\n/**\n * Whether the IE effective document mode is higher or the same as the given\n * document mode version.\n * NOTE: Only for IE, return false for another browser.\n *\n * @param {number} documentMode The document mode version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n * same as the given version.\n */\ngoog.userAgent.isDocumentModeOrHigher = function(documentMode) {\n 'use strict';\n return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isDocumentModeOrHigher`.\n * @param {number} version The version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n * same as the given version.\n * @deprecated Use goog.userAgent.isDocumentModeOrHigher().\n */\ngoog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;\n\n\n/**\n * For IE version < 7, documentMode is undefined, so attempt to use the\n * CSS1Compat property to see if we are in standards mode. If we are in\n * standards mode, treat the browser version as the document mode. Otherwise,\n * IE is emulating version 5.\n *\n * NOTE(user): Support for IE < 7 is long gone, so this is now simplified.\n * It returns document.documentMode for IE and undefined for everything else.\n *\n * @type {number|undefined}\n * @const\n */\ngoog.userAgent.DOCUMENT_MODE = (function() {\n 'use strict';\n var doc = goog.global['document'];\n if (!doc || !goog.userAgent.IE) return undefined;\n // This must be an IE user agent.\n var documentMode = goog.userAgent.getDocumentMode_();\n if (documentMode) return documentMode;\n // The user agent version string begins with the major version.\n // Parse the major version and truncate anything following.\n var ieVersion = parseInt(goog.userAgent.VERSION, 10);\n return ieVersion || undefined;\n})();\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Closure user agent detection (Browser).\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>\n * For more information on rendering engine, platform, or device see the other\n * sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform,\n * goog.labs.userAgent.device respectively.)\n */\n\ngoog.module('goog.labs.userAgent.browser');\ngoog.module.declareLegacyNamespace();\n\nconst util = goog.require('goog.labs.userAgent.util');\nconst {AsyncValue, Version} = goog.require('goog.labs.userAgent.highEntropy.highEntropyValue');\nconst {ChromiumRebrand} = goog.require('goog.labs.userAgent.chromiumRebrands');\nconst {assert, assertExists} = goog.require('goog.asserts');\nconst {compareVersions} = goog.require('goog.string.internal');\nconst {fullVersionList} = goog.require('goog.labs.userAgent.highEntropy.highEntropyData');\nconst {useClientHints} = goog.require('goog.labs.userAgent');\n\n// TODO(nnaze): Refactor to remove excessive exclusion logic in matching\n// functions.\n\n/**\n * A browser brand represents an opaque string that is used for making\n * brand-specific version checks in userAgentData.\n * @enum {string}\n */\nconst Brand = {\n /**\n * The browser brand for Android Browser.\n * Do not depend on the value of this string. Because Android Browser has not\n * implemented userAgentData yet, the value of this string is not guaranteed\n * to stay the same in future revisions.\n */\n ANDROID_BROWSER: 'Android Browser',\n /**\n * The browser brand for Chromium, including Chromium-based Edge and Opera.\n */\n CHROMIUM: 'Chromium',\n /**\n * The browser brand for Edge.\n * This brand can be used to get the version of both EdgeHTML and\n * Chromium-based Edge.\n */\n EDGE: 'Microsoft Edge',\n /**\n * The browser brand for Firefox.\n * Do not depend on the value of this string. Because Firefox has not\n * implemented userAgentData yet, the value of this string is not guaranteed\n * to stay the same in future revisions.\n */\n FIREFOX: 'Firefox',\n /**\n * The browser brand for Internet Explorer.\n * Do not depend on the value of this string. Because IE will never support\n * userAgentData, the value of this string should be treated as opaque (it's\n * used internally for legacy-userAgent fallback).\n */\n IE: 'Internet Explorer',\n /**\n * The browser brand for Opera.\n * This brand can be used to get the version of both Presto- and\n * Chromium-based Opera.\n */\n OPERA: 'Opera',\n /**\n * The browser brand for Safari.\n * Do not depend on the value of this string. Because Safari has not\n * implemented userAgentData yet, the value of this string is not guaranteed\n * to stay the same in future revisions.\n */\n SAFARI: 'Safari',\n /**\n * The browser brand for Silk.\n * See\n * https://docs.aws.amazon.com/silk/latest/developerguide/what-is-silk.html\n * Do not depend on the value of this string. Because Silk does not\n * identify itself in userAgentData yet, the value of this string is not\n * guaranteed to stay the same in future revisions.\n */\n SILK: 'Silk',\n};\nexports.Brand = Brand;\n\n/** @typedef {(!Brand|!ChromiumRebrand)} */\nlet AllBrandsInternal;\n\n/**\n * All possible valid values to pass to various UACH Brand-accepting functions.\n * @typedef {(!Brand|!ChromiumRebrand)}\n */\nexports.AllBrands;\n\n/**\n * @param {boolean=} ignoreClientHintsFlag Iff truthy, the `useClientHints`\n * function will not be called when evaluating if User-Agent Client Hints\n * Brand data can be used. For existing labs.userAgent API surfaces with\n * widespread use, this should be a falsy value so that usage of the Client\n * Hints APIs can be gated behind flags / experiment rollouts.\n * @return {boolean} Whether to use navigator.userAgentData to determine\n * browser's brand.\n */\nfunction useUserAgentDataBrand(ignoreClientHintsFlag = false) {\n if (util.ASSUME_CLIENT_HINTS_SUPPORT) return true;\n // High-entropy API surfaces should not be gated behind the useClientHints\n // check (as in production it is gated behind a define).\n if (!ignoreClientHintsFlag && !useClientHints()) return false;\n const userAgentData = util.getUserAgentData();\n return !!userAgentData && userAgentData.brands.length > 0;\n}\n\n/**\n * @return {boolean} Whether this browser is likely to have the fullVersionList\n * high-entropy Client Hint.\n */\nfunction hasFullVersionList() {\n // https://chromiumdash.appspot.com/commits?commit=1eb643c3057e64ff4d22468432ad16c4cab12879&platform=Linux\n // indicates that for all platforms Chromium 98 shipped this feature.\n // See also\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA-Full-Version-List#browser_compatibility\n return isAtLeast(Brand.CHROMIUM, 98);\n}\n\n/**\n * @return {boolean} Whether the user's browser is Opera. Note: Chromium based\n * Opera (Opera 15+) is detected as Chrome to avoid unnecessary special\n * casing.\n */\nfunction matchOpera() {\n if (useUserAgentDataBrand()) {\n // Pre-Chromium Edge doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Opera');\n}\n\n/** @return {boolean} Whether the user's browser is IE. */\nfunction matchIE() {\n if (useUserAgentDataBrand()) {\n // IE doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Trident') || util.matchUserAgent('MSIE');\n}\n\n/**\n * @return {boolean} Whether the user's browser is Edge. This refers to\n * EdgeHTML based Edge.\n */\nfunction matchEdgeHtml() {\n if (useUserAgentDataBrand()) {\n // Pre-Chromium Edge doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Edge');\n}\n\n/** @return {boolean} Whether the user's browser is Chromium based Edge. */\nfunction matchEdgeChromium() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.EDGE);\n }\n return util.matchUserAgent('Edg/');\n}\n\n/** @return {boolean} Whether the user's browser is Chromium based Opera. */\nfunction matchOperaChromium() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.OPERA);\n }\n return util.matchUserAgent('OPR');\n}\n\n/** @return {boolean} Whether the user's browser is Firefox. */\nfunction matchFirefox() {\n // Firefox doesn't support navigator.userAgentData yet, so use\n // navigator.userAgent.\n return util.matchUserAgent('Firefox') || util.matchUserAgent('FxiOS');\n}\n\n/** @return {boolean} Whether the user's browser is Safari. */\nfunction matchSafari() {\n // Apple-based browsers don't support navigator.userAgentData yet, so use\n // navigator.userAgent.\n return util.matchUserAgent('Safari') &&\n !(matchChrome() || matchCoast() || matchOpera() || matchEdgeHtml() ||\n matchEdgeChromium() || matchOperaChromium() || matchFirefox() ||\n isSilk() || util.matchUserAgent('Android'));\n}\n\n/**\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\n * iOS browser).\n */\nfunction matchCoast() {\n if (useUserAgentDataBrand()) {\n // Coast doesn't support navigator.userAgentData.\n return false;\n }\n return util.matchUserAgent('Coast');\n}\n\n/** @return {boolean} Whether the user's browser is iOS Webview. */\nfunction matchIosWebview() {\n // Apple-based browsers don't support navigator.userAgentData yet, so use\n // navigator.userAgent.\n // iOS Webview does not show up as Chrome or Safari.\n return (util.matchUserAgent('iPad') || util.matchUserAgent('iPhone')) &&\n !matchSafari() && !matchChrome() && !matchCoast() && !matchFirefox() &&\n util.matchUserAgent('AppleWebKit');\n}\n\n/**\n * @return {boolean} Whether the user's browser is any Chromium browser. This\n * returns true for Chrome, Opera 15+, and Edge Chromium.\n */\nfunction matchChrome() {\n if (useUserAgentDataBrand()) {\n return util.matchUserAgentDataBrand(Brand.CHROMIUM);\n }\n return ((util.matchUserAgent('Chrome') || util.matchUserAgent('CriOS')) &&\n !matchEdgeHtml()) ||\n isSilk();\n}\n\n/** @return {boolean} Whether the user's browser is the Android browser. */\nfunction matchAndroidBrowser() {\n // Android can appear in the user agent string for Chrome on Android.\n // This is not the Android standalone browser if it does.\n return util.matchUserAgent('Android') &&\n !(isChrome() || isFirefox() || isOpera() || isSilk());\n}\n\n/** @return {boolean} Whether the user's browser is Opera. */\nconst isOpera = matchOpera;\nexports.isOpera = isOpera;\n\n/** @return {boolean} Whether the user's browser is IE. */\nconst isIE = matchIE;\nexports.isIE = isIE;\n\n/** @return {boolean} Whether the user's browser is EdgeHTML based Edge. */\nconst isEdge = matchEdgeHtml;\nexports.isEdge = isEdge;\n\n/** @return {boolean} Whether the user's browser is Chromium based Edge. */\nconst isEdgeChromium = matchEdgeChromium;\nexports.isEdgeChromium = isEdgeChromium;\n\n/** @return {boolean} Whether the user's browser is Chromium based Opera. */\nconst isOperaChromium = matchOperaChromium;\nexports.isOperaChromium = isOperaChromium;\n\n/** @return {boolean} Whether the user's browser is Firefox. */\nconst isFirefox = matchFirefox;\nexports.isFirefox = isFirefox;\n\n/** @return {boolean} Whether the user's browser is Safari. */\nconst isSafari = matchSafari;\nexports.isSafari = isSafari;\n\n/**\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\n * iOS browser).\n */\nconst isCoast = matchCoast;\nexports.isCoast = isCoast;\n\n/** @return {boolean} Whether the user's browser is iOS Webview. */\nconst isIosWebview = matchIosWebview;\nexports.isIosWebview = isIosWebview;\n\n/**\n * @return {boolean} Whether the user's browser is any Chromium based browser (\n * Chrome, Blink-based Opera (15+) and Edge Chromium).\n */\nconst isChrome = matchChrome;\nexports.isChrome = isChrome;\n\n/** @return {boolean} Whether the user's browser is the Android browser. */\nconst isAndroidBrowser = matchAndroidBrowser;\nexports.isAndroidBrowser = isAndroidBrowser;\n\n/**\n * For more information, see:\n * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html\n * @return {boolean} Whether the user's browser is Silk.\n */\nfunction isSilk() {\n // As of Silk 93, Silk does not identify itself in userAgentData.brands.\n // When Silk changes this behavior, update this method to call\n // matchUserAgentDataBrand (akin to isChrome, etc.)\n return util.matchUserAgent('Silk');\n}\nexports.isSilk = isSilk;\n\n/**\n * A helper function that returns a function mapping a list of candidate\n * version tuple keys to the first version string present under a key.\n * Ex:\n * <code>\n * // Arg extracted from \"Foo/1.2.3 Bar/0.2021\"\n * const mapVersion = createVersionMap([[\"Foo\", \"1.2.3\"], [\"Bar\", \"0.2021\"]]);\n * mapVersion([\"Bar\", \"Foo\"]); // returns \"0.2021\"\n * mapVersion([\"Baz\", \"Foo\"]); // returns \"1.2.3\"\n * mapVersion([\"Baz\", \"???\"]); // returns \"\"\n * </code>\n * @param {!Array<!Array<string>>} versionTuples Version tuples pre-extracted\n * from a user agent string.\n * @return {function(!Array<string>): string} The version string, or empty\n * string if it doesn't exist under the given key.\n */\nfunction createVersionMap(versionTuples) {\n // Construct a map for easy lookup.\n const versionMap = {};\n versionTuples.forEach((tuple) => {\n // Note that the tuple is of length three, but we only care about the\n // first two.\n const key = tuple[0];\n const value = tuple[1];\n versionMap[key] = value;\n });\n\n // Gives the value with the first key it finds, otherwise empty string.\n return (keys) => versionMap[keys.find((key) => key in versionMap)] || '';\n}\n\n/**\n * Returns the browser version.\n *\n * Note that for browsers with multiple brands, this function assumes a primary\n * brand and returns the version for that brand.\n *\n * Additionally, this function is not userAgentData-aware and will return\n * incorrect values when the User Agent string is frozen. The current status of\n * User Agent string freezing is available here:\n * https://www.chromestatus.com/feature/5704553745874944\n *\n * To mitigate both of these potential issues, use\n * getVersionStringForLogging() or fullVersionOf() instead.\n *\n * @return {string} The browser version or empty string if version cannot be\n * determined. Note that for Internet Explorer, this returns the version of\n * the browser, not the version of the rendering engine. (IE 8 in\n * compatibility mode will return 8.0 rather than 7.0. To determine the\n * rendering engine version, look at document.documentMode instead. See\n * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more\n * details.)\n */\nfunction getVersion() {\n const userAgentString = util.getUserAgent();\n\n // Special case IE since IE's version is inside the parenthesis and\n // without the '/'.\n if (isIE()) {\n return getIEVersion(userAgentString);\n }\n\n const versionTuples = util.extractVersionTuples(userAgentString);\n const lookUpValueWithKeys = createVersionMap(versionTuples);\n\n // Check Opera before Chrome since Opera 15+ has \"Chrome\" in the string.\n // See\n // http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond\n if (isOpera()) {\n // Opera 10 has Version/10.0 but Opera/9.8, so look for \"Version\" first.\n // Opera uses 'OPR' for more recent UAs.\n return lookUpValueWithKeys(['Version', 'Opera']);\n }\n\n // Check Edge before Chrome since it has Chrome in the string.\n if (isEdge()) {\n return lookUpValueWithKeys(['Edge']);\n }\n\n // Check Chromium Edge before Chrome since it has Chrome in the string.\n if (isEdgeChromium()) {\n return lookUpValueWithKeys(['Edg']);\n }\n\n // Check Silk before Chrome since it may have Chrome in its string and be\n // treated as Chrome.\n if (isSilk()) {\n return lookUpValueWithKeys(['Silk']);\n }\n\n if (isChrome()) {\n return lookUpValueWithKeys(['Chrome', 'CriOS', 'HeadlessChrome']);\n }\n\n // Usually products browser versions are in the third tuple after \"Mozilla\"\n // and the engine.\n const tuple = versionTuples[2];\n return tuple && tuple[1] || '';\n}\nexports.getVersion = getVersion;\n\n/**\n * Returns whether the current browser's version is at least as high as the\n * given one.\n *\n * Note that for browsers with multiple brands, this function assumes a primary\n * brand and checks the version for that brand.\n *\n * Additionally, this function is not userAgentData-aware and will return\n * incorrect values when the User Agent string is frozen. The current status of\n * User Agent string freezing is available here:\n * https://www.chromestatus.com/feature/5704553745874944\n *\n * To mitigate both of these potential issues, use isAtLeast()/isAtMost() or\n * fullVersionOf() instead.\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the browser version is higher or the same as the\n * given version.\n * @deprecated Use isAtLeast()/isAtMost() instead.\n */\nfunction isVersionOrHigher(version) {\n return compareVersions(getVersion(), version) >= 0;\n}\nexports.isVersionOrHigher = isVersionOrHigher;\n\n/**\n * A helper function to determine IE version. More information:\n * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString\n * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx\n * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx\n * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx\n * @param {string} userAgent the User-Agent.\n * @return {string}\n */\nfunction getIEVersion(userAgent) {\n // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade\n // bug. Example UA:\n // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)\n // like Gecko.\n // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.\n const rv = /rv: *([\\d\\.]*)/.exec(userAgent);\n if (rv && rv[1]) {\n return rv[1];\n }\n\n let version = '';\n const msie = /MSIE +([\\d\\.]+)/.exec(userAgent);\n if (msie && msie[1]) {\n // IE in compatibility mode usually identifies itself as MSIE 7.0; in this\n // case, use the Trident version to determine the version of IE. For more\n // details, see the links above.\n const tridentVersion = /Trident\\/(\\d.\\d)/.exec(userAgent);\n if (msie[1] == '7.0') {\n if (tridentVersion && tridentVersion[1]) {\n switch (tridentVersion[1]) {\n case '4.0':\n version = '8.0';\n break;\n case '5.0':\n version = '9.0';\n break;\n case '6.0':\n version = '10.0';\n break;\n case '7.0':\n version = '11.0';\n break;\n }\n } else {\n version = '7.0';\n }\n } else {\n version = msie[1];\n }\n }\n return version;\n}\n\n/**\n * A helper function to return the navigator.userAgent-supplied full version\n * number of the current browser or an empty string, based on whether the\n * current browser is the one specified.\n * @param {string} browser The brand whose version should be returned.\n * @return {string}\n */\nfunction getFullVersionFromUserAgentString(browser) {\n const userAgentString = util.getUserAgent();\n // Special case IE since IE's version is inside the parenthesis and\n // without the '/'.\n if (browser === Brand.IE) {\n return isIE() ? getIEVersion(userAgentString) : '';\n }\n\n const versionTuples = util.extractVersionTuples(userAgentString);\n const lookUpValueWithKeys = createVersionMap(versionTuples);\n switch (browser) {\n case Brand.OPERA:\n // Opera 10 has Version/10.0 but Opera/9.8, so look for \"Version\"\n // first. Opera uses 'OPR' for more recent UAs.\n if (isOpera()) {\n return lookUpValueWithKeys(['Version', 'Opera']);\n } else if (isOperaChromium()) {\n return lookUpValueWithKeys(['OPR']);\n }\n break;\n case Brand.EDGE:\n if (isEdge()) {\n return lookUpValueWithKeys(['Edge']);\n } else if (isEdgeChromium()) {\n return lookUpValueWithKeys(['Edg']);\n }\n break;\n case Brand.CHROMIUM:\n if (isChrome()) {\n return lookUpValueWithKeys(['Chrome', 'CriOS', 'HeadlessChrome']);\n }\n break;\n }\n\n // For the following browsers, the browser version is in the third tuple after\n // \"Mozilla\" and the engine.\n if ((browser === Brand.FIREFOX && isFirefox()) ||\n (browser === Brand.SAFARI && isSafari()) ||\n (browser === Brand.ANDROID_BROWSER && isAndroidBrowser()) ||\n (browser === Brand.SILK && isSilk())) {\n const tuple = versionTuples[2];\n return tuple && tuple[1] || '';\n }\n\n return '';\n}\n\n/**\n * Returns the major version of the given browser brand, or NaN if the current\n * browser is not the given brand.\n * Note that the major version number may be different depending on which\n * browser is specified. The returned value can be used to make browser version\n * comparisons using comparison operators.\n * @private\n * @param {!AllBrandsInternal} browser The brand whose version should be\n * returned.\n * @return {number} The major version number associated with the current\n * browser under the given brand, or NaN if the current browser doesn't match\n * the given brand.\n */\nfunction versionOf_(browser) {\n let versionParts;\n // Silk currently does not identify itself in its userAgentData.brands array,\n // so if checking its version, always fall back to the user agent string.\n if (useUserAgentDataBrand() && browser !== Brand.SILK) {\n const data = util.getUserAgentData();\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\n if (!matchingBrand || !matchingBrand.version) {\n return NaN;\n }\n versionParts = matchingBrand.version.split('.');\n } else {\n const fullVersion = getFullVersionFromUserAgentString(browser);\n if (fullVersion === '') {\n return NaN;\n }\n versionParts = fullVersion.split('.');\n }\n if (versionParts.length === 0) {\n return NaN;\n }\n const majorVersion = versionParts[0];\n return Number(majorVersion); // Returns NaN if it is not parseable.\n}\n\n/**\n * Returns true if the current browser matches the given brand and is at least\n * the given major version. The major version must be a whole number (i.e.\n * decimals should not be used to represent a minor version).\n * @param {!AllBrandsInternal} brand The brand whose version should be returned.\n * @param {number} majorVersion The major version number to compare against.\n * This must be a whole number.\n * @return {boolean} Whether the current browser both matches the given brand\n * and is at least the given version.\n */\nfunction isAtLeast(brand, majorVersion) {\n assert(\n Math.floor(majorVersion) === majorVersion,\n 'Major version must be an integer');\n return versionOf_(brand) >= majorVersion;\n}\nexports.isAtLeast = isAtLeast;\n\n/**\n * Returns true if the current browser matches the given brand and is at most\n * the given version. The major version must be a whole number (i.e. decimals\n * should not be used to represent a minor version).\n * @param {!AllBrandsInternal} brand The brand whose version should be returned.\n * @param {number} majorVersion The major version number to compare against.\n * This must be a whole number.\n * @return {boolean} Whether the current browser both matches the given brand\n * and is at most the given version.\n */\nfunction isAtMost(brand, majorVersion) {\n assert(\n Math.floor(majorVersion) === majorVersion,\n 'Major version must be an integer');\n return versionOf_(brand) <= majorVersion;\n}\nexports.isAtMost = isAtMost;\n\n/**\n * Loads the high-entropy browser brand/version data and wraps the correct\n * version string in a Version object.\n * @implements {AsyncValue<!Version>}\n */\nclass HighEntropyBrandVersion {\n /**\n * @param {string} brand The brand whose version is retrieved in this\n * container.\n * @param {boolean} useUach Whether to attempt to use the User-Agent Client\n * Hints (UACH) API surface.\n * @param {string} fallbackVersion The fallback version derived from the\n * userAgent string.\n */\n constructor(brand, useUach, fallbackVersion) {\n /** @private @const {string} */\n this.brand_ = brand;\n\n /** @private @const {!Version} */\n this.version_ = new Version(fallbackVersion);\n\n /** @private @const {boolean} */\n this.useUach_ = useUach;\n }\n\n /**\n * @return {!Version|undefined}\n * @override\n */\n getIfLoaded() {\n if (this.useUach_) {\n const loadedVersionList = fullVersionList.getIfLoaded();\n if (loadedVersionList !== undefined) {\n const matchingBrand =\n loadedVersionList.find(({brand}) => this.brand_ === brand);\n // We assumed in fullVersionOf that if the fullVersionList is defined\n // the brands must match. Double-check this here.\n assertExists(matchingBrand);\n return new Version(matchingBrand.version);\n }\n // Fallthrough to fallback on Pre-UACH implementation\n }\n // We want to make sure the loading semantics of the Pre-UACH implementation\n // match those of the UACH implementation. Loading must happen before any\n // data can be retrieved from getIfLoaded.\n // For HighEntropyBrandVersion, loading can either be done by calling #load\n // or by calling the module-local loadFullVersions function.\n if (preUachHasLoaded) {\n return this.version_;\n }\n return;\n }\n\n /**\n * @return {!Promise<!Version>}\n * @override\n */\n async load() {\n if (this.useUach_) {\n const loadedVersionList = await fullVersionList.load();\n if (loadedVersionList !== undefined) {\n const matchingBrand =\n loadedVersionList.find(({brand}) => this.brand_ === brand);\n assertExists(matchingBrand);\n return new Version(matchingBrand.version);\n }\n // Fallthrough to fallback on Pre-UACH implementation\n } else {\n // Await something so that calling load with or without UACH API\n // availability results in waiting at least one macrotask before allowing\n // access to the cached version information.\n await 0;\n }\n // Regardless of whether we are using UACH APIs, we can now allow access to\n // the fallback case\n preUachHasLoaded = true;\n return this.version_;\n }\n}\n\n/**\n * Whether full version data should be considered available when using UACH\n * fallback implementations. This is flipped to true when either\n * loadFullVersions or HighEntropyBrandVersion.prototype.load are called,\n * matching the global singleton semantics of the UACH codepaths.\n */\nlet preUachHasLoaded = false;\n\n/**\n * Requests all full browser versions to be cached. When the returned promise\n * resolves, subsequent calls to `fullVersionOf(...).getIfLoaded()` will return\n * a value.\n *\n * This method should be avoided in favor of directly awaiting\n * `fullVersionOf(...).load()` where it is used.\n *\n * @return {!Promise<void>}\n */\nasync function loadFullVersions() {\n if (useUserAgentDataBrand(true)) {\n await fullVersionList.load();\n }\n preUachHasLoaded = true;\n}\nexports.loadFullVersions = loadFullVersions;\n\n/**\n * Resets module-local caches used by functionality in this module.\n * This is only for use by goog.labs.userAgent.testUtil.resetUserAgent (and\n * labs.userAgent tests).\n * @package\n */\nexports.resetForTesting = () => {\n preUachHasLoaded = false;\n fullVersionList.resetForTesting();\n};\n\n\n/**\n * Returns an object that provides access to the full version string of the\n * current browser -- or undefined, based on whether the current browser matches\n * the requested browser brand. Note that the full version string is a\n * high-entropy value, and must be asynchronously loaded before it can be\n * accessed synchronously.\n * @param {!AllBrandsInternal} browser The brand whose version should be\n * returned.\n * @return {!AsyncValue<!Version>|undefined} An object that can be used\n * to get or load the full version string as a high-entropy value, or\n * undefined if the current browser doesn't match the given brand.\n */\nfunction fullVersionOf(browser) {\n let fallbackVersionString = '';\n // If we are reasonably certain now that the browser we are on has the\n // fullVersionList high-entropy hint, then we can skip computing the fallback\n // value as we won't end up using it.\n if (!hasFullVersionList()) {\n fallbackVersionString = getFullVersionFromUserAgentString(browser);\n }\n // Silk has the UACH API surface, but currently does not identify itself in\n // the userAgentData.brands array. Fallback to using userAgent string version\n // for Silk.\n const useUach = browser !== Brand.SILK && useUserAgentDataBrand(true);\n if (useUach) {\n const data = util.getUserAgentData();\n // Operate under the assumption that the low-entropy and high-entropy lists\n // of brand/version pairs contain an identical set of brands. Therefore, if\n // the low-entropy list doesn't contain the given brand, return undefined.\n if (!data.brands.find(({brand}) => brand === browser)) {\n return undefined;\n }\n } else if (fallbackVersionString === '') {\n return undefined;\n }\n return new HighEntropyBrandVersion(browser, useUach, fallbackVersionString);\n}\nexports.fullVersionOf = fullVersionOf;\n\n\n/**\n * Returns a version string for the current browser or undefined, based on\n * whether the current browser is the one specified.\n * This value should ONLY be used for logging/debugging purposes. Do not use it\n * to branch code paths. For comparing versions, use isAtLeast()/isAtMost() or\n * fullVersionOf() instead.\n * @param {!AllBrandsInternal} browser The brand whose version should be\n * returned.\n * @return {string} The version as a string.\n */\nfunction getVersionStringForLogging(browser) {\n if (useUserAgentDataBrand(true)) {\n const fullVersionObj = fullVersionOf(browser);\n if (fullVersionObj) {\n const fullVersion = fullVersionObj.getIfLoaded();\n if (fullVersion) {\n return fullVersion.toVersionStringForLogging();\n }\n // No full version, return the major version instead.\n const data = util.getUserAgentData();\n const matchingBrand = data.brands.find(({brand}) => brand === browser);\n // Checking for the existence of matchingBrand is not necessary because\n // the existence of fullVersionObj implies that there is already a\n // matching brand.\n assertExists(matchingBrand);\n return matchingBrand.version;\n }\n // If fullVersionObj is undefined, this doesn't mean that the full version\n // is unavailable, but rather that the current browser doesn't match the\n // input `browser` argument.\n return '';\n } else {\n return getFullVersionFromUserAgentString(browser);\n }\n}\nexports.getVersionStringForLogging = getVersionStringForLogging;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Closure user agent detection.\n * @see http://en.wikipedia.org/wiki/User_agent\n * For more information on browser brand, platform, or device see the other\n * sub-namespaces in goog.labs.userAgent (browser, platform, and device).\n */\n\ngoog.module('goog.labs.userAgent.engine');\ngoog.module.declareLegacyNamespace();\n\nconst googArray = goog.require('goog.array');\nconst googString = goog.require('goog.string.internal');\nconst util = goog.require('goog.labs.userAgent.util');\n\n/**\n * @return {boolean} Whether the rendering engine is Presto.\n */\nfunction isPresto() {\n return util.matchUserAgent('Presto');\n}\n\n/**\n * @return {boolean} Whether the rendering engine is Trident.\n */\nfunction isTrident() {\n // IE only started including the Trident token in IE8.\n return util.matchUserAgent('Trident') || util.matchUserAgent('MSIE');\n}\n\n/**\n * @return {boolean} Whether the rendering engine is EdgeHTML.\n */\nfunction isEdge() {\n return util.matchUserAgent('Edge');\n}\n\n/**\n * @return {boolean} Whether the rendering engine is WebKit. This will return\n * true for Chrome, Blink-based Opera (15+), Edge Chromium and Safari.\n */\nfunction isWebKit() {\n return util.matchUserAgentIgnoreCase('WebKit') && !isEdge();\n}\n\n/**\n * @return {boolean} Whether the rendering engine is Gecko.\n */\nfunction isGecko() {\n return util.matchUserAgent('Gecko') && !isWebKit() && !isTrident() &&\n !isEdge();\n}\n\n/**\n * @return {string} The rendering engine's version or empty string if version\n * can't be determined.\n */\nfunction getVersion() {\n const userAgentString = util.getUserAgent();\n if (userAgentString) {\n const tuples = util.extractVersionTuples(userAgentString);\n\n const engineTuple = getEngineTuple(tuples);\n if (engineTuple) {\n // In Gecko, the version string is either in the browser info or the\n // Firefox version. See Gecko user agent string reference:\n // http://goo.gl/mULqa\n if (engineTuple[0] == 'Gecko') {\n return getVersionForKey(tuples, 'Firefox');\n }\n\n return engineTuple[1];\n }\n\n // MSIE has only one version identifier, and the Trident version is\n // specified in the parenthetical. IE Edge is covered in the engine tuple\n // detection.\n const browserTuple = tuples[0];\n let info;\n if (browserTuple && (info = browserTuple[2])) {\n const match = /Trident\\/([^\\s;]+)/.exec(info);\n if (match) {\n return match[1];\n }\n }\n }\n return '';\n}\n\n/**\n * @param {!Array<!Array<string>>} tuples Extracted version tuples.\n * @return {!Array<string>|undefined} The engine tuple or undefined if not\n * found.\n */\nfunction getEngineTuple(tuples) {\n if (!isEdge()) {\n return tuples[1];\n }\n for (let i = 0; i < tuples.length; i++) {\n const tuple = tuples[i];\n if (tuple[0] == 'Edge') {\n return tuple;\n }\n }\n}\n\n/**\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the rendering engine version is higher or the same\n * as the given version.\n */\nfunction isVersionOrHigher(version) {\n return googString.compareVersions(getVersion(), version) >= 0;\n}\n\n/**\n * @param {!Array<!Array<string>>} tuples Version tuples.\n * @param {string} key The key to look for.\n * @return {string} The version string of the given key, if present.\n * Otherwise, the empty string.\n */\nfunction getVersionForKey(tuples, key) {\n // TODO(nnaze): Move to util if useful elsewhere.\n\n const pair = googArray.find(tuples, function(pair) {\n return key == pair[0];\n });\n\n return pair && pair[1] || '';\n}\n\nexports = {\n getVersion,\n isEdge,\n isGecko,\n isPresto,\n isTrident,\n isVersionOrHigher,\n isWebKit,\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A patched, standardized event object for browser events.\n *\n * <pre>\n * The patched event object contains the following members:\n * - type {string} Event type, e.g. 'click'\n * - target {Object} The element that actually triggered the event\n * - currentTarget {Object} The element the listener is attached to\n * - relatedTarget {Object} For mouseover and mouseout, the previous object\n * - offsetX {number} X-coordinate relative to target\n * - offsetY {number} Y-coordinate relative to target\n * - clientX {number} X-coordinate relative to viewport\n * - clientY {number} Y-coordinate relative to viewport\n * - screenX {number} X-coordinate relative to the edge of the screen\n * - screenY {number} Y-coordinate relative to the edge of the screen\n * - button {number} Mouse button. Use isButton() to test.\n * - keyCode {number} Key-code\n * - ctrlKey {boolean} Was ctrl key depressed\n * - altKey {boolean} Was alt key depressed\n * - shiftKey {boolean} Was shift key depressed\n * - metaKey {boolean} Was meta key depressed\n * - pointerId {number} Pointer ID\n * - pointerType {string} Pointer type, e.g. 'mouse', 'pen', or 'touch'\n * - defaultPrevented {boolean} Whether the default action has been prevented\n * - state {Object} History state object\n *\n * NOTE: The keyCode member contains the raw browser keyCode. For normalized\n * key and character code use {@link goog.events.KeyHandler}.\n * </pre>\n */\n\ngoog.provide('goog.events.BrowserEvent');\ngoog.provide('goog.events.BrowserEvent.MouseButton');\ngoog.provide('goog.events.BrowserEvent.PointerType');\n\ngoog.require('goog.debug');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventType');\ngoog.require('goog.reflect');\ngoog.require('goog.userAgent');\n\n/**\n * Accepts a browser event object and creates a patched, cross browser event\n * object.\n * The content of this object will not be initialized if no event object is\n * provided. If this is the case, init() needs to be invoked separately.\n * @param {Event=} opt_e Browser event object.\n * @param {EventTarget=} opt_currentTarget Current target for event.\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.events.BrowserEvent = function(opt_e, opt_currentTarget) {\n 'use strict';\n goog.events.BrowserEvent.base(this, 'constructor', opt_e ? opt_e.type : '');\n\n /**\n * Target that fired the event.\n * @override\n * @type {?Node}\n */\n this.target = null;\n\n /**\n * Node that had the listener attached.\n * @override\n * @type {?Node|undefined}\n */\n this.currentTarget = null;\n\n /**\n * For mouseover and mouseout events, the related object for the event.\n * @type {?Node}\n */\n this.relatedTarget = null;\n\n /**\n * X-coordinate relative to target.\n * @type {number}\n */\n this.offsetX = 0;\n\n /**\n * Y-coordinate relative to target.\n * @type {number}\n */\n this.offsetY = 0;\n\n /**\n * X-coordinate relative to the window.\n * @type {number}\n */\n this.clientX = 0;\n\n /**\n * Y-coordinate relative to the window.\n * @type {number}\n */\n this.clientY = 0;\n\n /**\n * X-coordinate relative to the monitor.\n * @type {number}\n */\n this.screenX = 0;\n\n /**\n * Y-coordinate relative to the monitor.\n * @type {number}\n */\n this.screenY = 0;\n\n /**\n * Which mouse button was pressed.\n * @type {number}\n */\n this.button = 0;\n\n /**\n * Key of key press.\n * @type {string}\n */\n this.key = '';\n\n /**\n * Keycode of key press.\n * @type {number}\n */\n this.keyCode = 0;\n\n /**\n * Keycode of key press.\n * @type {number}\n */\n this.charCode = 0;\n\n /**\n * Whether control was pressed at time of event.\n * @type {boolean}\n */\n this.ctrlKey = false;\n\n /**\n * Whether alt was pressed at time of event.\n * @type {boolean}\n */\n this.altKey = false;\n\n /**\n * Whether shift was pressed at time of event.\n * @type {boolean}\n */\n this.shiftKey = false;\n\n /**\n * Whether the meta key was pressed at time of event.\n * @type {boolean}\n */\n this.metaKey = false;\n\n /**\n * History state object, only set for PopState events where it's a copy of the\n * state object provided to pushState or replaceState.\n * @type {?Object}\n */\n this.state = null;\n\n /**\n * Whether the default platform modifier key was pressed at time of event.\n * (This is control for all platforms except Mac, where it's Meta.)\n * @type {boolean}\n */\n this.platformModifierKey = false;\n\n /**\n * @type {number}\n */\n this.pointerId = 0;\n\n /**\n * @type {string}\n */\n this.pointerType = '';\n\n /**\n * The browser event object.\n * @private {?Event}\n */\n this.event_ = null;\n\n if (opt_e) {\n this.init(opt_e, opt_currentTarget);\n }\n};\ngoog.inherits(goog.events.BrowserEvent, goog.events.Event);\n\n/**\n * @define {boolean} If true, use the layerX and layerY properties of a native\n * browser event over the offsetX and offsetY properties, which cause expensive\n * reflow. If layerX or layerY is not defined, offsetX and offsetY will be used\n * as usual.\n */\ngoog.events.BrowserEvent.USE_LAYER_XY_AS_OFFSET_XY =\n goog.define('goog.events.BrowserEvent.USE_LAYER_XY_AS_OFFSET_XY', false);\n\n\n/**\n * Normalized button constants for the mouse.\n * @enum {number}\n */\ngoog.events.BrowserEvent.MouseButton = {\n LEFT: 0,\n MIDDLE: 1,\n RIGHT: 2,\n BACK: 3,\n FORWARD: 4,\n};\n\n\n/**\n * Normalized pointer type constants for pointer events.\n * @enum {string}\n */\ngoog.events.BrowserEvent.PointerType = {\n MOUSE: 'mouse',\n PEN: 'pen',\n TOUCH: 'touch'\n};\n\n\n/**\n * Static data for mapping mouse buttons.\n * @type {!Array<number>}\n * @deprecated Use `goog.events.BrowserEvent.IE_BUTTON_MAP` instead.\n */\ngoog.events.BrowserEvent.IEButtonMap = goog.debug.freeze([\n 1, // LEFT\n 4, // MIDDLE\n 2 // RIGHT\n]);\n\n\n/**\n * Static data for mapping mouse buttons.\n * @const {!Array<number>}\n */\ngoog.events.BrowserEvent.IE_BUTTON_MAP = goog.events.BrowserEvent.IEButtonMap;\n\n\n/**\n * Static data for mapping MSPointerEvent types to PointerEvent types.\n * @const {!Object<number, goog.events.BrowserEvent.PointerType>}\n */\ngoog.events.BrowserEvent.IE_POINTER_TYPE_MAP = goog.debug.freeze({\n 2: goog.events.BrowserEvent.PointerType.TOUCH,\n 3: goog.events.BrowserEvent.PointerType.PEN,\n 4: goog.events.BrowserEvent.PointerType.MOUSE\n});\n\n\n/**\n * Accepts a browser event object and creates a patched, cross browser event\n * object.\n * @param {Event} e Browser event object.\n * @param {EventTarget=} opt_currentTarget Current target for event.\n */\ngoog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) {\n 'use strict';\n var type = this.type = e.type;\n\n /**\n * On touch devices use the first \"changed touch\" as the relevant touch.\n * @type {?Touch}\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\n var relevantTouch =\n e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : null;\n\n // TODO(nicksantos): Change this.target to type EventTarget.\n this.target = /** @type {Node} */ (e.target) || e.srcElement;\n\n // TODO(nicksantos): Change this.currentTarget to type EventTarget.\n this.currentTarget = /** @type {Node} */ (opt_currentTarget);\n\n var relatedTarget = /** @type {Node} */ (e.relatedTarget);\n if (relatedTarget) {\n // There's a bug in FireFox where sometimes, relatedTarget will be a\n // chrome element, and accessing any property of it will get a permission\n // denied exception. See:\n // https://bugzilla.mozilla.org/show_bug.cgi?id=497780\n if (goog.userAgent.GECKO) {\n if (!goog.reflect.canAccessProperty(relatedTarget, 'nodeName')) {\n relatedTarget = null;\n }\n }\n } else if (type == goog.events.EventType.MOUSEOVER) {\n relatedTarget = e.fromElement;\n } else if (type == goog.events.EventType.MOUSEOUT) {\n relatedTarget = e.toElement;\n }\n\n this.relatedTarget = relatedTarget;\n\n if (relevantTouch) {\n this.clientX = relevantTouch.clientX !== undefined ? relevantTouch.clientX :\n relevantTouch.pageX;\n this.clientY = relevantTouch.clientY !== undefined ? relevantTouch.clientY :\n relevantTouch.pageY;\n this.screenX = relevantTouch.screenX || 0;\n this.screenY = relevantTouch.screenY || 0;\n } else {\n if (goog.events.BrowserEvent.USE_LAYER_XY_AS_OFFSET_XY) {\n this.offsetX = (e.layerX !== undefined) ? e.layerX : e.offsetX;\n this.offsetY = (e.layerY !== undefined) ? e.layerY : e.offsetY;\n } else {\n // Webkit emits a lame warning whenever layerX/layerY is accessed.\n // http://code.google.com/p/chromium/issues/detail?id=101733\n this.offsetX = (goog.userAgent.WEBKIT || e.offsetX !== undefined) ?\n e.offsetX :\n e.layerX;\n this.offsetY = (goog.userAgent.WEBKIT || e.offsetY !== undefined) ?\n e.offsetY :\n e.layerY;\n }\n this.clientX = e.clientX !== undefined ? e.clientX : e.pageX;\n this.clientY = e.clientY !== undefined ? e.clientY : e.pageY;\n this.screenX = e.screenX || 0;\n this.screenY = e.screenY || 0;\n }\n\n this.button = e.button;\n\n this.keyCode = e.keyCode || 0;\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n this.key = e.key || '';\n this.charCode = e.charCode || (type == 'keypress' ? e.keyCode : 0);\n this.ctrlKey = e.ctrlKey;\n this.altKey = e.altKey;\n this.shiftKey = e.shiftKey;\n this.metaKey = e.metaKey;\n this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n this.pointerId = e.pointerId || 0;\n this.pointerType = goog.events.BrowserEvent.getPointerType_(e);\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n this.state = e.state;\n this.event_ = e;\n if (e.defaultPrevented) {\n // Sync native event state to internal state via super class, where default\n // prevention is implemented and managed.\n goog.events.BrowserEvent.superClass_.preventDefault.call(this);\n }\n};\n\n\n/**\n * Tests to see which button was pressed during the event. This is really only\n * useful in IE and Gecko browsers. And in IE, it's only useful for\n * mousedown/mouseup events, because click only fires for the left mouse button.\n *\n * Safari 2 only reports the left button being clicked, and uses the value '1'\n * instead of 0. Opera only reports a mousedown event for the middle button, and\n * no mouse events for the right button. Opera has default behavior for left and\n * middle click that can only be overridden via a configuration setting.\n *\n * There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html.\n *\n * @param {goog.events.BrowserEvent.MouseButton} button The button\n * to test for.\n * @return {boolean} True if button was pressed.\n */\ngoog.events.BrowserEvent.prototype.isButton = function(button) {\n 'use strict';\n return this.event_.button == button;\n};\n\n\n/**\n * Whether this has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @return {boolean} The result.\n */\ngoog.events.BrowserEvent.prototype.isMouseActionButton = function() {\n 'use strict';\n // Ctrl+click should never behave like a left-click on mac, regardless of\n // whether or not the browser will actually ever emit such an event. If\n // we see it, treat it like right-click always.\n return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&\n !(goog.userAgent.MAC && this.ctrlKey);\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.stopPropagation = function() {\n 'use strict';\n goog.events.BrowserEvent.superClass_.stopPropagation.call(this);\n if (this.event_.stopPropagation) {\n this.event_.stopPropagation();\n } else {\n this.event_.cancelBubble = true;\n }\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.preventDefault = function() {\n 'use strict';\n goog.events.BrowserEvent.superClass_.preventDefault.call(this);\n var be = this.event_;\n if (!be.preventDefault) {\n be.returnValue = false;\n } else {\n be.preventDefault();\n }\n};\n\n\n/**\n * @return {Event} The underlying browser event object.\n */\ngoog.events.BrowserEvent.prototype.getBrowserEvent = function() {\n 'use strict';\n return this.event_;\n};\n\n\n/**\n * Extracts the pointer type from the given event.\n * @param {!Event} e\n * @return {string} The pointer type, e.g. 'mouse', 'pen', or 'touch'.\n * @private\n */\ngoog.events.BrowserEvent.getPointerType_ = function(e) {\n 'use strict';\n if (typeof (e.pointerType) === 'string') {\n return e.pointerType;\n }\n // IE10 uses integer codes for pointer type.\n // https://msdn.microsoft.com/en-us/library/hh772359(v=vs.85).aspx\n return goog.events.BrowserEvent.IE_POINTER_TYPE_MAP[e.pointerType] || '';\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.events.EventType');\n\ngoog.require('goog.events.eventTypeHelpers');\ngoog.require('goog.userAgent');\n\n\n/**\n * Constants for event names.\n * @enum {string}\n */\ngoog.events.EventType = {\n // Mouse events\n CLICK: 'click',\n RIGHTCLICK: 'rightclick',\n DBLCLICK: 'dblclick',\n AUXCLICK: 'auxclick',\n MOUSEDOWN: 'mousedown',\n MOUSEUP: 'mouseup',\n MOUSEOVER: 'mouseover',\n MOUSEOUT: 'mouseout',\n MOUSEMOVE: 'mousemove',\n MOUSEENTER: 'mouseenter',\n MOUSELEAVE: 'mouseleave',\n\n // Non-existent event; will never fire. This exists as a mouse counterpart to\n // POINTERCANCEL.\n MOUSECANCEL: 'mousecancel',\n\n // Selection events.\n // https://www.w3.org/TR/selection-api/\n SELECTIONCHANGE: 'selectionchange',\n SELECTSTART: 'selectstart', // IE, Safari, Chrome\n\n // Wheel events\n // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents\n WHEEL: 'wheel',\n\n // Key events\n KEYPRESS: 'keypress',\n KEYDOWN: 'keydown',\n KEYUP: 'keyup',\n\n // Focus\n BLUR: 'blur',\n FOCUS: 'focus',\n DEACTIVATE: 'deactivate', // IE only\n FOCUSIN: 'focusin',\n FOCUSOUT: 'focusout',\n\n // Forms\n CHANGE: 'change',\n RESET: 'reset',\n SELECT: 'select',\n SUBMIT: 'submit',\n INPUT: 'input',\n PROPERTYCHANGE: 'propertychange', // IE only\n\n // Drag and drop\n DRAGSTART: 'dragstart',\n DRAG: 'drag',\n DRAGENTER: 'dragenter',\n DRAGOVER: 'dragover',\n DRAGLEAVE: 'dragleave',\n DROP: 'drop',\n DRAGEND: 'dragend',\n\n // Touch events\n // Note that other touch events exist, but we should follow the W3C list here.\n // http://www.w3.org/TR/touch-events/#list-of-touchevent-types\n TOUCHSTART: 'touchstart',\n TOUCHMOVE: 'touchmove',\n TOUCHEND: 'touchend',\n TOUCHCANCEL: 'touchcancel',\n\n // Misc\n BEFOREUNLOAD: 'beforeunload',\n CONSOLEMESSAGE: 'consolemessage',\n CONTEXTMENU: 'contextmenu',\n DEVICECHANGE: 'devicechange',\n DEVICEMOTION: 'devicemotion',\n DEVICEORIENTATION: 'deviceorientation',\n DOMCONTENTLOADED: 'DOMContentLoaded',\n ERROR: 'error',\n HELP: 'help',\n LOAD: 'load',\n LOSECAPTURE: 'losecapture',\n ORIENTATIONCHANGE: 'orientationchange',\n READYSTATECHANGE: 'readystatechange',\n RESIZE: 'resize',\n SCROLL: 'scroll',\n UNLOAD: 'unload',\n\n // Media events\n CANPLAY: 'canplay',\n CANPLAYTHROUGH: 'canplaythrough',\n DURATIONCHANGE: 'durationchange',\n EMPTIED: 'emptied',\n ENDED: 'ended',\n LOADEDDATA: 'loadeddata',\n LOADEDMETADATA: 'loadedmetadata',\n PAUSE: 'pause',\n PLAY: 'play',\n PLAYING: 'playing',\n PROGRESS: 'progress',\n RATECHANGE: 'ratechange',\n SEEKED: 'seeked',\n SEEKING: 'seeking',\n STALLED: 'stalled',\n SUSPEND: 'suspend',\n TIMEUPDATE: 'timeupdate',\n VOLUMECHANGE: 'volumechange',\n WAITING: 'waiting',\n\n // Media Source Extensions events\n // https://www.w3.org/TR/media-source/#mediasource-events\n SOURCEOPEN: 'sourceopen',\n SOURCEENDED: 'sourceended',\n SOURCECLOSED: 'sourceclosed',\n // https://www.w3.org/TR/media-source/#sourcebuffer-events\n ABORT: 'abort',\n UPDATE: 'update',\n UPDATESTART: 'updatestart',\n UPDATEEND: 'updateend',\n\n // HTML 5 History events\n // See http://www.w3.org/TR/html5/browsers.html#event-definitions-0\n HASHCHANGE: 'hashchange',\n PAGEHIDE: 'pagehide',\n PAGESHOW: 'pageshow',\n POPSTATE: 'popstate',\n\n // Copy and Paste\n // Support is limited. Make sure it works on your favorite browser\n // before using.\n // http://www.quirksmode.org/dom/events/cutcopypaste.html\n COPY: 'copy',\n PASTE: 'paste',\n CUT: 'cut',\n BEFORECOPY: 'beforecopy',\n BEFORECUT: 'beforecut',\n BEFOREPASTE: 'beforepaste',\n\n // HTML5 online/offline events.\n // http://www.w3.org/TR/offline-webapps/#related\n ONLINE: 'online',\n OFFLINE: 'offline',\n\n // HTML 5 worker events\n MESSAGE: 'message',\n CONNECT: 'connect',\n\n // Service Worker Events - ServiceWorkerGlobalScope context\n // See https://w3c.github.io/ServiceWorker/#execution-context-events\n // Note: message event defined in worker events section\n INSTALL: 'install',\n ACTIVATE: 'activate',\n FETCH: 'fetch',\n FOREIGNFETCH: 'foreignfetch',\n MESSAGEERROR: 'messageerror',\n\n // Service Worker Events - Document context\n // See https://w3c.github.io/ServiceWorker/#document-context-events\n STATECHANGE: 'statechange',\n UPDATEFOUND: 'updatefound',\n CONTROLLERCHANGE: 'controllerchange',\n\n // CSS animation events.\n ANIMATIONSTART:\n goog.events.eventTypeHelpers.getVendorPrefixedName('AnimationStart'),\n ANIMATIONEND:\n goog.events.eventTypeHelpers.getVendorPrefixedName('AnimationEnd'),\n ANIMATIONITERATION:\n goog.events.eventTypeHelpers.getVendorPrefixedName('AnimationIteration'),\n\n // CSS transition events. Based on the browser support described at:\n // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility\n TRANSITIONEND:\n goog.events.eventTypeHelpers.getVendorPrefixedName('TransitionEnd'),\n\n // W3C Pointer Events\n // http://www.w3.org/TR/pointerevents/\n POINTERDOWN: 'pointerdown',\n POINTERUP: 'pointerup',\n POINTERCANCEL: 'pointercancel',\n POINTERMOVE: 'pointermove',\n POINTEROVER: 'pointerover',\n POINTEROUT: 'pointerout',\n POINTERENTER: 'pointerenter',\n POINTERLEAVE: 'pointerleave',\n GOTPOINTERCAPTURE: 'gotpointercapture',\n LOSTPOINTERCAPTURE: 'lostpointercapture',\n\n // IE specific events.\n // See http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx\n // Note: these events will be supplanted in IE11.\n MSGESTURECHANGE: 'MSGestureChange',\n MSGESTUREEND: 'MSGestureEnd',\n MSGESTUREHOLD: 'MSGestureHold',\n MSGESTURESTART: 'MSGestureStart',\n MSGESTURETAP: 'MSGestureTap',\n MSGOTPOINTERCAPTURE: 'MSGotPointerCapture',\n MSINERTIASTART: 'MSInertiaStart',\n MSLOSTPOINTERCAPTURE: 'MSLostPointerCapture',\n MSPOINTERCANCEL: 'MSPointerCancel',\n MSPOINTERDOWN: 'MSPointerDown',\n MSPOINTERENTER: 'MSPointerEnter',\n MSPOINTERHOVER: 'MSPointerHover',\n MSPOINTERLEAVE: 'MSPointerLeave',\n MSPOINTERMOVE: 'MSPointerMove',\n MSPOINTEROUT: 'MSPointerOut',\n MSPOINTEROVER: 'MSPointerOver',\n MSPOINTERUP: 'MSPointerUp',\n\n // Native IMEs/input tools events.\n TEXT: 'text',\n // The textInput event is supported in IE9+, but only in lower case. All other\n // browsers use the camel-case event name.\n TEXTINPUT: goog.userAgent.IE ? 'textinput' : 'textInput',\n COMPOSITIONSTART: 'compositionstart',\n COMPOSITIONUPDATE: 'compositionupdate',\n COMPOSITIONEND: 'compositionend',\n\n // The beforeinput event is initially only supported in Safari. See\n // https://bugs.chromium.org/p/chromium/issues/detail?id=342670 for Chrome\n // implementation tracking.\n BEFOREINPUT: 'beforeinput',\n\n // Fullscreen API events. See https://fullscreen.spec.whatwg.org/.\n FULLSCREENCHANGE: 'fullscreenchange',\n // iOS-only fullscreen events. See\n // https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/ControllingMediaWithJavaScript/ControllingMediaWithJavaScript.html\n WEBKITBEGINFULLSCREEN: 'webkitbeginfullscreen',\n WEBKITENDFULLSCREEN: 'webkitendfullscreen',\n\n // Webview tag events\n // See https://developer.chrome.com/apps/tags/webview\n EXIT: 'exit',\n LOADABORT: 'loadabort',\n LOADCOMMIT: 'loadcommit',\n LOADREDIRECT: 'loadredirect',\n LOADSTART: 'loadstart',\n LOADSTOP: 'loadstop',\n RESPONSIVE: 'responsive',\n SIZECHANGED: 'sizechanged',\n UNRESPONSIVE: 'unresponsive',\n\n // HTML5 Page Visibility API. See details at\n // `goog.labs.dom.PageVisibilityMonitor`.\n VISIBILITYCHANGE: 'visibilitychange',\n\n // LocalStorage event.\n STORAGE: 'storage',\n\n // Print events.\n BEFOREPRINT: 'beforeprint',\n AFTERPRINT: 'afterprint',\n\n // Web app manifest events.\n BEFOREINSTALLPROMPT: 'beforeinstallprompt',\n APPINSTALLED: 'appinstalled',\n\n // Web Animation API (WAAPI) playback events\n // https://www.w3.org/TR/web-animations-1/#animation-playback-event-types\n CANCEL: 'cancel',\n FINISH: 'finish',\n REMOVE: 'remove'\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An interface for a listenable JavaScript object.\n */\n\ngoog.provide('goog.events.Listenable');\n\ngoog.requireType('goog.events.EventId');\ngoog.requireType('goog.events.EventLike');\ngoog.requireType('goog.events.ListenableKey');\n\n\n/**\n * A listenable interface. A listenable is an object with the ability\n * to dispatch/broadcast events to \"event listeners\" registered via\n * listen/listenOnce.\n *\n * The interface allows for an event propagation mechanism similar\n * to one offered by native browser event targets, such as\n * capture/bubble mechanism, stopping propagation, and preventing\n * default actions. Capture/bubble mechanism depends on the ancestor\n * tree constructed via `#getParentEventTarget`; this tree\n * must be directed acyclic graph. The meaning of default action(s)\n * in preventDefault is specific to a particular use case.\n *\n * Implementations that do not support capture/bubble or can not have\n * a parent listenable can simply not implement any ability to set the\n * parent listenable (and have `#getParentEventTarget` return\n * null).\n *\n * Implementation of this class can be used with or independently from\n * goog.events.\n *\n * Implementation must call `#addImplementation(implClass)`.\n *\n * @interface\n * @see goog.events\n * @see http://www.w3.org/TR/DOM-Level-2-Events/events.html\n */\ngoog.events.Listenable = function() {};\n\n\n/**\n * An expando property to indicate that an object implements\n * goog.events.Listenable.\n *\n * See addImplementation/isImplementedBy.\n *\n * @type {string}\n * @const\n */\ngoog.events.Listenable.IMPLEMENTED_BY_PROP =\n 'closure_listenable_' + ((Math.random() * 1e6) | 0);\n\n\n/**\n * Marks a given class (constructor) as an implementation of\n * Listenable, so that we can query that fact at runtime. The class\n * must have already implemented the interface.\n * @param {function(new:goog.events.Listenable,...)} cls The class constructor.\n * The corresponding class must have already implemented the interface.\n */\ngoog.events.Listenable.addImplementation = function(cls) {\n 'use strict';\n cls.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = true;\n};\n\n\n/**\n * @param {?Object} obj The object to check.\n * @return {boolean} Whether a given instance implements Listenable. The\n * class/superclass of the instance must call addImplementation.\n */\ngoog.events.Listenable.isImplementedBy = function(obj) {\n 'use strict';\n return !!(obj && obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]);\n};\n\n\n/**\n * Adds an event listener. A listener can only be added once to an\n * object and if it is added again the key for the listener is\n * returned. Note that if the existing listener is a one-off listener\n * (registered via listenOnce), it will no longer be a one-off\n * listener after a call to listen().\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n * method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n * (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.listen = function(\n type, listener, opt_useCapture, opt_listenerScope) {};\n\n\n/**\n * Adds an event listener that is removed automatically after the\n * listener fired once.\n *\n * If an existing listener already exists, listenOnce will do\n * nothing. In particular, if the listener was previously registered\n * via listen(), listenOnce() will not turn the listener into a\n * one-off listener. Similarly, if there is already an existing\n * one-off listener, listenOnce does not modify the listeners (it is\n * still a once listener).\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n * method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n * (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.listenOnce = function(\n type, listener, opt_useCapture, opt_listenerScope) {};\n\n\n/**\n * Removes an event listener which was added with listen() or listenOnce().\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n * method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n * (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call\n * the listener.\n * @return {boolean} Whether any listener was removed.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.unlisten = function(\n type, listener, opt_useCapture, opt_listenerScope) {};\n\n\n/**\n * Removes an event listener which was added with listen() by the key\n * returned by listen().\n *\n * @param {!goog.events.ListenableKey} key The key returned by\n * listen() or listenOnce().\n * @return {boolean} Whether any listener was removed.\n */\ngoog.events.Listenable.prototype.unlistenByKey = function(key) {};\n\n\n/**\n * Dispatches an event (or event like object) and calls all listeners\n * listening for events of this type. The type of the event is decided by the\n * type property on the event object.\n *\n * If any of the listeners returns false OR calls preventDefault then this\n * function will return false. If one of the capture listeners calls\n * stopPropagation, then the bubble listeners won't fire.\n *\n * @param {?goog.events.EventLike} e Event object.\n * @return {boolean} If anyone called preventDefault on the event object (or\n * if any of the listeners returns false) this will also return false.\n */\ngoog.events.Listenable.prototype.dispatchEvent = function(e) {};\n\n\n/**\n * Removes all listeners from this listenable. If type is specified,\n * it will only remove listeners of the particular type. otherwise all\n * registered listeners will be removed.\n *\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove,\n * default is to remove all types.\n * @return {number} Number of listeners removed.\n */\ngoog.events.Listenable.prototype.removeAllListeners = function(opt_type) {};\n\n\n/**\n * Returns the parent of this event target to use for capture/bubble\n * mechanism.\n *\n * NOTE(chrishenry): The name reflects the original implementation of\n * custom event target (`goog.events.EventTarget`). We decided\n * that changing the name is not worth it.\n *\n * @return {?goog.events.Listenable} The parent EventTarget or null if\n * there is no parent.\n */\ngoog.events.Listenable.prototype.getParentEventTarget = function() {};\n\n\n/**\n * Fires all registered listeners in this listenable for the given\n * type and capture mode, passing them the given eventObject. This\n * does not perform actual capture/bubble. Only implementors of the\n * interface should be using this.\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The type of the\n * listeners to fire.\n * @param {boolean} capture The capture mode of the listeners to fire.\n * @param {EVENTOBJ} eventObject The event object to fire.\n * @return {boolean} Whether all listeners succeeded without\n * attempting to prevent default behavior. If any listener returns\n * false or called goog.events.Event#preventDefault, this returns\n * false.\n * @template EVENTOBJ\n */\ngoog.events.Listenable.prototype.fireListeners = function(\n type, capture, eventObject) {};\n\n\n/**\n * Gets all listeners in this listenable for the given type and\n * capture mode.\n *\n * @param {string|!goog.events.EventId} type The type of the listeners to fire.\n * @param {boolean} capture The capture mode of the listeners to fire.\n * @return {!Array<!goog.events.ListenableKey>} An array of registered\n * listeners.\n * @template EVENTOBJ\n */\ngoog.events.Listenable.prototype.getListeners = function(type, capture) {};\n\n\n/**\n * Gets the goog.events.ListenableKey for the event or null if no such\n * listener is in use.\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The name of the event\n * without the 'on' prefix.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener The\n * listener function to get.\n * @param {boolean} capture Whether the listener is a capturing listener.\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {?goog.events.ListenableKey} the found listener or null if not found.\n * @template SCOPE,EVENTOBJ\n */\ngoog.events.Listenable.prototype.getListener = function(\n type, listener, capture, opt_listenerScope) {};\n\n\n/**\n * Whether there is any active listeners matching the specified\n * signature. If either the type or capture parameters are\n * unspecified, the function will match on the remaining criteria.\n *\n * @param {string|!goog.events.EventId<EVENTOBJ>=} opt_type Event type.\n * @param {boolean=} opt_capture Whether to check for capture or bubble\n * listeners.\n * @return {boolean} Whether there is any active listeners matching\n * the requested type and/or capture phase.\n * @template EVENTOBJ\n */\ngoog.events.Listenable.prototype.hasListener = function(\n opt_type, opt_capture) {};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An interface that describes a single registered listener.\n */\ngoog.provide('goog.events.ListenableKey');\n\ngoog.requireType('goog.events.Listenable');\n\n\n/**\n * An interface that describes a single registered listener.\n * @interface\n */\ngoog.events.ListenableKey = function() {};\n\n\n/**\n * Counter used to create a unique key\n * @type {number}\n * @private\n */\ngoog.events.ListenableKey.counter_ = 0;\n\n\n/**\n * Reserves a key to be used for ListenableKey#key field.\n * @return {number} A number to be used to fill ListenableKey#key\n * field.\n */\ngoog.events.ListenableKey.reserveKey = function() {\n 'use strict';\n return ++goog.events.ListenableKey.counter_;\n};\n\n\n/**\n * The source event target.\n * @type {?Object|?goog.events.Listenable}\n */\ngoog.events.ListenableKey.prototype.src;\n\n\n/**\n * The event type the listener is listening to.\n * @type {string}\n */\ngoog.events.ListenableKey.prototype.type;\n\n\n/**\n * The listener function.\n * @type {function(?):?|{handleEvent:function(?):?}|null}\n */\ngoog.events.ListenableKey.prototype.listener;\n\n\n/**\n * Whether the listener works on capture phase.\n * @type {boolean}\n */\ngoog.events.ListenableKey.prototype.capture;\n\n\n/**\n * The 'this' object for the listener function's scope.\n * @type {?Object|undefined}\n */\ngoog.events.ListenableKey.prototype.handler;\n\n\n/**\n * A globally unique number to identify the key.\n * @type {number}\n */\ngoog.events.ListenableKey.prototype.key;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Listener object.\n * @see ../demos/events.html\n */\n\ngoog.provide('goog.events.Listener');\n\ngoog.require('goog.events.ListenableKey');\ngoog.requireType('goog.events.Listenable');\n\n\n\n/**\n * Simple class that stores information about a listener\n * @param {function(?):?} listener Callback function.\n * @param {Function} proxy Wrapper for the listener that patches the event.\n * @param {EventTarget|goog.events.Listenable} src Source object for\n * the event.\n * @param {string} type Event type.\n * @param {boolean} capture Whether in capture or bubble phase.\n * @param {Object=} opt_handler Object in whose context to execute the callback.\n * @implements {goog.events.ListenableKey}\n * @constructor\n */\ngoog.events.Listener = function(\n listener, proxy, src, type, capture, opt_handler) {\n 'use strict';\n if (goog.events.Listener.ENABLE_MONITORING) {\n this.creationStack = new Error().stack;\n }\n\n /** @override */\n this.listener = listener;\n\n /**\n * A wrapper over the original listener. This is used solely to\n * handle native browser events (it is used to simulate the capture\n * phase and to patch the event object).\n * @type {Function}\n */\n this.proxy = proxy;\n\n /**\n * Object or node that callback is listening to\n * @type {EventTarget|goog.events.Listenable}\n */\n this.src = src;\n\n /**\n * The event type.\n * @const {string}\n */\n this.type = type;\n\n /**\n * Whether the listener is being called in the capture or bubble phase\n * @const {boolean}\n */\n this.capture = !!capture;\n\n /**\n * Optional object whose context to execute the listener in\n * @type {Object|undefined}\n */\n this.handler = opt_handler;\n\n /**\n * The key of the listener.\n * @const {number}\n * @override\n */\n this.key = goog.events.ListenableKey.reserveKey();\n\n /**\n * Whether to remove the listener after it has been called.\n * @type {boolean}\n */\n this.callOnce = false;\n\n /**\n * Whether the listener has been removed.\n * @type {boolean}\n */\n this.removed = false;\n};\n\n\n/**\n * @define {boolean} Whether to enable the monitoring of the\n * goog.events.Listener instances. Switching on the monitoring is only\n * recommended for debugging because it has a significant impact on\n * performance and memory usage. If switched off, the monitoring code\n * compiles down to 0 bytes.\n */\ngoog.events.Listener.ENABLE_MONITORING =\n goog.define('goog.events.Listener.ENABLE_MONITORING', false);\n\n\n/**\n * If monitoring the goog.events.Listener instances is enabled, stores the\n * creation stack trace of the Disposable instance.\n * @type {string}\n */\ngoog.events.Listener.prototype.creationStack;\n\n\n/**\n * Marks this listener as removed. This also remove references held by\n * this listener object (such as listener and event source).\n */\ngoog.events.Listener.prototype.markAsRemoved = function() {\n 'use strict';\n this.removed = true;\n this.listener = null;\n this.proxy = null;\n this.src = null;\n this.handler = null;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A map of listeners that provides utility functions to\n * deal with listeners on an event target. Used by\n * `goog.events.EventTarget`.\n *\n * WARNING: Do not use this class from outside goog.events package.\n *\n */\n\ngoog.provide('goog.events.ListenerMap');\n\ngoog.require('goog.array');\ngoog.require('goog.events.Listener');\ngoog.require('goog.object');\ngoog.requireType('goog.events.EventId');\ngoog.requireType('goog.events.Listenable');\ngoog.requireType('goog.events.ListenableKey');\n\n\n\n/**\n * Creates a new listener map.\n * @param {EventTarget|goog.events.Listenable} src The src object.\n * @constructor\n * @final\n */\ngoog.events.ListenerMap = function(src) {\n 'use strict';\n /** @type {EventTarget|goog.events.Listenable} */\n this.src = src;\n\n /**\n * Maps of event type to an array of listeners.\n * @type {!Object<string, !Array<!goog.events.Listener>>}\n */\n this.listeners = {};\n\n /**\n * The count of types in this map that have registered listeners.\n * @private {number}\n */\n this.typeCount_ = 0;\n};\n\n\n/**\n * @return {number} The count of event types in this map that actually\n * have registered listeners.\n */\ngoog.events.ListenerMap.prototype.getTypeCount = function() {\n 'use strict';\n return this.typeCount_;\n};\n\n\n/**\n * @return {number} Total number of registered listeners.\n */\ngoog.events.ListenerMap.prototype.getListenerCount = function() {\n 'use strict';\n var count = 0;\n for (var type in this.listeners) {\n count += this.listeners[type].length;\n }\n return count;\n};\n\n\n/**\n * Adds an event listener. A listener can only be added once to an\n * object and if it is added again the key for the listener is\n * returned.\n *\n * Note that a one-off listener will not change an existing listener,\n * if any. On the other hand a normal listener will change existing\n * one-off listener to become a normal listener.\n *\n * @param {string|!goog.events.EventId} type The listener event type.\n * @param {!Function} listener This listener callback method.\n * @param {boolean} callOnce Whether the listener is a one-off\n * listener.\n * @param {boolean=} opt_useCapture The capture mode of the listener.\n * @param {Object=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n */\ngoog.events.ListenerMap.prototype.add = function(\n type, listener, callOnce, opt_useCapture, opt_listenerScope) {\n 'use strict';\n var typeStr = type.toString();\n var listenerArray = this.listeners[typeStr];\n if (!listenerArray) {\n listenerArray = this.listeners[typeStr] = [];\n this.typeCount_++;\n }\n\n var listenerObj;\n var index = goog.events.ListenerMap.findListenerIndex_(\n listenerArray, listener, opt_useCapture, opt_listenerScope);\n if (index > -1) {\n listenerObj = listenerArray[index];\n if (!callOnce) {\n // Ensure that, if there is an existing callOnce listener, it is no\n // longer a callOnce listener.\n listenerObj.callOnce = false;\n }\n } else {\n listenerObj = new goog.events.Listener(\n listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope);\n listenerObj.callOnce = callOnce;\n listenerArray.push(listenerObj);\n }\n return listenerObj;\n};\n\n\n/**\n * Removes a matching listener.\n * @param {string|!goog.events.EventId} type The listener event type.\n * @param {!Function} listener This listener callback method.\n * @param {boolean=} opt_useCapture The capture mode of the listener.\n * @param {Object=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {boolean} Whether any listener was removed.\n */\ngoog.events.ListenerMap.prototype.remove = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n 'use strict';\n var typeStr = type.toString();\n if (!(typeStr in this.listeners)) {\n return false;\n }\n\n var listenerArray = this.listeners[typeStr];\n var index = goog.events.ListenerMap.findListenerIndex_(\n listenerArray, listener, opt_useCapture, opt_listenerScope);\n if (index > -1) {\n var listenerObj = listenerArray[index];\n listenerObj.markAsRemoved();\n goog.array.removeAt(listenerArray, index);\n if (listenerArray.length == 0) {\n delete this.listeners[typeStr];\n this.typeCount_--;\n }\n return true;\n }\n return false;\n};\n\n\n/**\n * Removes the given listener object.\n * @param {!goog.events.ListenableKey} listener The listener to remove.\n * @return {boolean} Whether the listener is removed.\n */\ngoog.events.ListenerMap.prototype.removeByKey = function(listener) {\n 'use strict';\n var type = listener.type;\n if (!(type in this.listeners)) {\n return false;\n }\n\n var removed = goog.array.remove(this.listeners[type], listener);\n if (removed) {\n /** @type {!goog.events.Listener} */ (listener).markAsRemoved();\n if (this.listeners[type].length == 0) {\n delete this.listeners[type];\n this.typeCount_--;\n }\n }\n return removed;\n};\n\n\n/**\n * Removes all listeners from this map. If opt_type is provided, only\n * listeners that match the given type are removed.\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove.\n * @return {number} Number of listeners removed.\n */\ngoog.events.ListenerMap.prototype.removeAll = function(opt_type) {\n 'use strict';\n var typeStr = opt_type && opt_type.toString();\n var count = 0;\n for (var type in this.listeners) {\n if (!typeStr || type == typeStr) {\n var listenerArray = this.listeners[type];\n for (var i = 0; i < listenerArray.length; i++) {\n ++count;\n listenerArray[i].markAsRemoved();\n }\n delete this.listeners[type];\n this.typeCount_--;\n }\n }\n return count;\n};\n\n\n/**\n * Gets all listeners that match the given type and capture mode. The\n * returned array is a copy (but the listener objects are not).\n * @param {string|!goog.events.EventId} type The type of the listeners\n * to retrieve.\n * @param {boolean} capture The capture mode of the listeners to retrieve.\n * @return {!Array<!goog.events.ListenableKey>} An array of matching\n * listeners.\n */\ngoog.events.ListenerMap.prototype.getListeners = function(type, capture) {\n 'use strict';\n var listenerArray = this.listeners[type.toString()];\n var rv = [];\n if (listenerArray) {\n for (var i = 0; i < listenerArray.length; ++i) {\n var listenerObj = listenerArray[i];\n if (listenerObj.capture == capture) {\n rv.push(listenerObj);\n }\n }\n }\n return rv;\n};\n\n\n/**\n * Gets the goog.events.ListenableKey for the event or null if no such\n * listener is in use.\n *\n * @param {string|!goog.events.EventId} type The type of the listener\n * to retrieve.\n * @param {!Function} listener The listener function to get.\n * @param {boolean} capture Whether the listener is a capturing listener.\n * @param {Object=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {goog.events.ListenableKey} the found listener or null if not found.\n */\ngoog.events.ListenerMap.prototype.getListener = function(\n type, listener, capture, opt_listenerScope) {\n 'use strict';\n var listenerArray = this.listeners[type.toString()];\n var i = -1;\n if (listenerArray) {\n i = goog.events.ListenerMap.findListenerIndex_(\n listenerArray, listener, capture, opt_listenerScope);\n }\n return i > -1 ? listenerArray[i] : null;\n};\n\n\n/**\n * Whether there is a matching listener. If either the type or capture\n * parameters are unspecified, the function will match on the\n * remaining criteria.\n *\n * @param {string|!goog.events.EventId=} opt_type The type of the listener.\n * @param {boolean=} opt_capture The capture mode of the listener.\n * @return {boolean} Whether there is an active listener matching\n * the requested type and/or capture phase.\n */\ngoog.events.ListenerMap.prototype.hasListener = function(\n opt_type, opt_capture) {\n 'use strict';\n var hasType = (opt_type !== undefined);\n var typeStr = hasType ? opt_type.toString() : '';\n var hasCapture = (opt_capture !== undefined);\n\n return goog.object.some(this.listeners, function(listenerArray, type) {\n 'use strict';\n for (var i = 0; i < listenerArray.length; ++i) {\n if ((!hasType || listenerArray[i].type == typeStr) &&\n (!hasCapture || listenerArray[i].capture == opt_capture)) {\n return true;\n }\n }\n\n return false;\n });\n};\n\n\n/**\n * Finds the index of a matching goog.events.Listener in the given\n * listenerArray.\n * @param {!Array<!goog.events.Listener>} listenerArray Array of listener.\n * @param {!Function} listener The listener function.\n * @param {boolean=} opt_useCapture The capture flag for the listener.\n * @param {Object=} opt_listenerScope The listener scope.\n * @return {number} The index of the matching listener within the\n * listenerArray.\n * @private\n */\ngoog.events.ListenerMap.findListenerIndex_ = function(\n listenerArray, listener, opt_useCapture, opt_listenerScope) {\n 'use strict';\n for (var i = 0; i < listenerArray.length; ++i) {\n var listenerObj = listenerArray[i];\n if (!listenerObj.removed && listenerObj.listener == listener &&\n listenerObj.capture == !!opt_useCapture &&\n listenerObj.handler == opt_listenerScope) {\n return i;\n }\n }\n return -1;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating objects/maps/hashes.\n */\ngoog.module('goog.object');\ngoog.module.declareLegacyNamespace();\n\n/**\n * Calls a function for each element in an object/map/hash.\n * @param {?Object<K,V>} obj The object over which to iterate.\n * @param {function(this:T,V,?,?Object<K,V>):?} f The function to call for every\n * element. This function takes 3 arguments (the value, the key and the\n * object) and the return value is ignored.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {void}\n * @template T,K,V\n */\nfunction forEach(obj, f, opt_obj) {\n for (const key in obj) {\n f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);\n }\n}\n\n/**\n * Calls a function for each element in an object/map/hash. If that call returns\n * true, adds the element to a new object.\n * @param {?Object<K,V>} obj The object over which to iterate.\n * @param {function(this:T,V,?,?Object<K,V>):boolean} f The function to call for\n * every element. This function takes 3 arguments (the value, the key and\n * the object) and should return a boolean. If the return value is true the\n * element is added to the result object. If it is false the element is not\n * included.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {!Object<K,V>} a new object in which only elements that passed the\n * test are present.\n * @template T,K,V\n */\nfunction filter(obj, f, opt_obj) {\n const res = {};\n for (const key in obj) {\n if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {\n res[key] = obj[key];\n }\n }\n return res;\n}\n\n/**\n * For every element in an object/map/hash calls a function and inserts the\n * result into a new object.\n * @param {?Object<K,V>} obj The object over which to iterate.\n * @param {function(this:T,V,?,?Object<K,V>):R} f The function to call for every\n * element. This function takes 3 arguments (the value, the key and the\n * object) and should return something. The result will be inserted into a\n * new object.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {!Object<K,R>} a new object with the results from f.\n * @template T,K,V,R\n */\nfunction map(obj, f, opt_obj) {\n const res = {};\n for (const key in obj) {\n res[key] = f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);\n }\n return res;\n}\n\n/**\n * Calls a function for each element in an object/map/hash. If any\n * call returns true, returns true (without checking the rest). If\n * all calls return false, returns false.\n * @param {?Object<K,V>} obj The object to check.\n * @param {function(this:T,V,?,?Object<K,V>):boolean} f The function to call for\n * every element. This function takes 3 arguments (the value, the key and\n * the object) and should return a boolean.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {boolean} true if any element passes the test.\n * @template T,K,V\n */\nfunction some(obj, f, opt_obj) {\n for (const key in obj) {\n if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Calls a function for each element in an object/map/hash. If\n * all calls return true, returns true. If any call returns false, returns\n * false at this point and does not continue to check the remaining elements.\n * @param {?Object<K,V>} obj The object to check.\n * @param {?function(this:T,V,?,?Object<K,V>):boolean} f The function to call\n * for every element. This function takes 3 arguments (the value, the key\n * and the object) and should return a boolean.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @return {boolean} false if any element fails the test.\n * @template T,K,V\n */\nfunction every(obj, f, opt_obj) {\n for (const key in obj) {\n if (!f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Returns the number of key-value pairs in the object map.\n * @param {?Object} obj The object for which to get the number of key-value\n * pairs.\n * @return {number} The number of key-value pairs in the object map.\n */\nfunction getCount(obj) {\n let rv = 0;\n for (const key in obj) {\n rv++;\n }\n return rv;\n}\n\n/**\n * Returns one key from the object map, if any exists.\n * For map literals the returned key will be the first one in most of the\n * browsers (a know exception is Konqueror).\n * @param {?Object} obj The object to pick a key from.\n * @return {string|undefined} The key or undefined if the object is empty.\n */\nfunction getAnyKey(obj) {\n for (const key in obj) {\n return key;\n }\n}\n\n/**\n * Returns one value from the object map, if any exists.\n * For map literals the returned value will be the first one in most of the\n * browsers (a know exception is Konqueror).\n * @param {?Object<K,V>} obj The object to pick a value from.\n * @return {V|undefined} The value or undefined if the object is empty.\n * @template K,V\n */\nfunction getAnyValue(obj) {\n for (const key in obj) {\n return obj[key];\n }\n}\n\n/**\n * Whether the object/hash/map contains the given object as a value.\n * An alias for containsValue(obj, val).\n * @param {?Object<K,V>} obj The object in which to look for val.\n * @param {V} val The object for which to check.\n * @return {boolean} true if val is present.\n * @template K,V\n */\nfunction contains(obj, val) {\n return containsValue(obj, val);\n}\n\n/**\n * Returns the values of the object/map/hash.\n * @param {?Object<K,V>} obj The object from which to get the values.\n * @return {!Array<V>} The values in the object/map/hash.\n * @template K,V\n */\nfunction getValues(obj) {\n const res = [];\n let i = 0;\n for (const key in obj) {\n res[i++] = obj[key];\n }\n return res;\n}\n\n/**\n * Returns the keys of the object/map/hash.\n * @param {?Object} obj The object from which to get the keys.\n * @return {!Array<string>} Array of property keys.\n */\nfunction getKeys(obj) {\n const res = [];\n let i = 0;\n for (const key in obj) {\n res[i++] = key;\n }\n return res;\n}\n\n/**\n * Get a value from an object multiple levels deep. This is useful for\n * pulling values from deeply nested objects, such as JSON responses.\n * Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)\n * @param {?Object} obj An object to get the value from. Can be array-like.\n * @param {...(string|number|!IArrayLike<number|string>)} var_args A number of\n * keys (as strings, or numbers, for array-like objects). Can also be\n * specified as a single array of keys.\n * @return {*} The resulting value. If, at any point, the value for a key in the\n * current object is null or undefined, returns undefined.\n */\nfunction getValueByKeys(obj, var_args) {\n const isArrayLike = goog.isArrayLike(var_args);\n const keys = isArrayLike ?\n /** @type {!IArrayLike<number|string>} */ (var_args) :\n arguments;\n\n // Start with the 2nd parameter for the variable parameters syntax.\n for (let i = isArrayLike ? 0 : 1; i < keys.length; i++) {\n if (obj == null) return undefined;\n obj = obj[keys[i]];\n }\n\n return obj;\n}\n\n/**\n * Whether the object/map/hash contains the given key.\n * @param {?Object} obj The object in which to look for key.\n * @param {?} key The key for which to check.\n * @return {boolean} true If the map contains the key.\n */\nfunction containsKey(obj, key) {\n return obj !== null && key in obj;\n}\n\n/**\n * Whether the object/map/hash contains the given value. This is O(n).\n * @param {?Object<K,V>} obj The object in which to look for val.\n * @param {V} val The value for which to check.\n * @return {boolean} true If the map contains the value.\n * @template K,V\n */\nfunction containsValue(obj, val) {\n for (const key in obj) {\n if (obj[key] == val) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Searches an object for an element that satisfies the given condition and\n * returns its key.\n * @param {?Object<K,V>} obj The object to search in.\n * @param {function(this:T,V,string,?Object<K,V>):boolean} f The function to\n * call for every element. Takes 3 arguments (the value, the key and the\n * object) and should return a boolean.\n * @param {T=} thisObj An optional \"this\" context for the function.\n * @return {string|undefined} The key of an element for which the function\n * returns true or undefined if no such element is found.\n * @template T,K,V\n */\nfunction findKey(obj, f, thisObj = undefined) {\n for (const key in obj) {\n if (f.call(/** @type {?} */ (thisObj), obj[key], key, obj)) {\n return key;\n }\n }\n return undefined;\n}\n\n/**\n * Searches an object for an element that satisfies the given condition and\n * returns its value.\n * @param {?Object<K,V>} obj The object to search in.\n * @param {function(this:T,V,string,?Object<K,V>):boolean} f The function to\n * call for every element. Takes 3 arguments (the value, the key and the\n * object) and should return a boolean.\n * @param {T=} thisObj An optional \"this\" context for the function.\n * @return {V} The value of an element for which the function returns true or\n * undefined if no such element is found.\n * @template T,K,V\n */\nfunction findValue(obj, f, thisObj = undefined) {\n const key = findKey(obj, f, thisObj);\n return key && obj[key];\n}\n\n/**\n * Whether the object/map/hash is empty.\n * @param {?Object} obj The object to test.\n * @return {boolean} true if obj is empty.\n */\nfunction isEmpty(obj) {\n for (const key in obj) {\n return false;\n }\n return true;\n}\n\n/**\n * Removes all key value pairs from the object/map/hash.\n * @param {?Object} obj The object to clear.\n * @return {void}\n */\nfunction clear(obj) {\n for (const i in obj) {\n delete obj[i];\n }\n}\n\n/**\n * Removes a key-value pair based on the key.\n * @param {?Object} obj The object from which to remove the key.\n * @param {?} key The key to remove.\n * @return {boolean} Whether an element was removed.\n */\nfunction remove(obj, key) {\n let rv;\n if (rv = key in /** @type {!Object} */ (obj)) {\n delete obj[key];\n }\n return rv;\n}\n\n/**\n * Adds a key-value pair to the object. Throws an exception if the key is\n * already in use. Use set if you want to change an existing pair.\n * @param {?Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {V} val The value to add.\n * @return {void}\n * @template K,V\n */\nfunction add(obj, key, val) {\n if (obj !== null && key in obj) {\n throw new Error(`The object already contains the key \"${key}\"`);\n }\n set(obj, key, val);\n}\n\n/**\n * Returns the value for the given key.\n * @param {?Object<K,V>} obj The object from which to get the value.\n * @param {string} key The key for which to get the value.\n * @param {R=} val The value to return if no item is found for the given key\n * (default is undefined).\n * @return {V|R|undefined} The value for the given key.\n * @template K,V,R\n */\nfunction get(obj, key, val = undefined) {\n if (obj !== null && key in obj) {\n return obj[key];\n }\n return val;\n}\n\n/**\n * Adds a key-value pair to the object/map/hash.\n * @param {?Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {V} value The value to add.\n * @template K,V\n * @return {void}\n */\nfunction set(obj, key, value) {\n obj[key] = value;\n}\n\n/**\n * Adds a key-value pair to the object/map/hash if it doesn't exist yet.\n * @param {?Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {V} value The value to add if the key wasn't present.\n * @return {V} The value of the entry at the end of the function.\n * @template K,V\n */\nfunction setIfUndefined(obj, key, value) {\n return key in /** @type {!Object} */ (obj) ? obj[key] : (obj[key] = value);\n}\n\n/**\n * Sets a key and value to an object if the key is not set. The value will be\n * the return value of the given function. If the key already exists, the\n * object will not be changed and the function will not be called (the function\n * will be lazily evaluated -- only called if necessary).\n * This function is particularly useful when used with an `Object` which is\n * acting as a cache.\n * @param {?Object<K,V>} obj The object to which to add the key-value pair.\n * @param {string} key The key to add.\n * @param {function():V} f The value to add if the key wasn't present.\n * @return {V} The value of the entry at the end of the function.\n * @template K,V\n */\nfunction setWithReturnValueIfNotSet(obj, key, f) {\n if (key in obj) {\n return obj[key];\n }\n\n const val = f();\n obj[key] = val;\n return val;\n}\n\n/**\n * Compares two objects for equality using === on the values.\n * @param {!Object<K,V>} a\n * @param {!Object<K,V>} b\n * @return {boolean}\n * @template K,V\n */\nfunction equals(a, b) {\n for (const k in a) {\n if (!(k in b) || a[k] !== b[k]) {\n return false;\n }\n }\n for (const k in b) {\n if (!(k in a)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Returns a shallow clone of the object.\n * @param {?Object<K,V>} obj Object to clone.\n * @return {!Object<K,V>} Clone of the input object.\n * @template K,V\n */\nfunction clone(obj) {\n const res = {};\n for (const key in obj) {\n res[key] = obj[key];\n }\n return res;\n}\n\n/**\n * Clones a value. The input may be an Object, Array, or basic type. Objects and\n * arrays will be cloned recursively.\n * WARNINGS:\n * <code>unsafeClone</code> does not detect reference loops. Objects\n * that refer to themselves will cause infinite recursion.\n * <code>unsafeClone</code> is unaware of unique identifiers, and\n * copies UIDs created by <code>getUid</code> into cloned results.\n * @param {T} obj The value to clone.\n * @return {T} A clone of the input value.\n * @template T\n */\nfunction unsafeClone(obj) {\n if (!obj || typeof obj !== 'object') return obj;\n if (typeof obj.clone === 'function') return obj.clone();\n if (typeof Map !== 'undefined' && obj instanceof Map) {\n return new Map(obj);\n } else if (typeof Set !== 'undefined' && obj instanceof Set) {\n return new Set(obj);\n } else if (obj instanceof Date) {\n return new Date(obj.getTime());\n }\n const clone = Array.isArray(obj) ? [] :\n typeof ArrayBuffer === 'function' &&\n typeof ArrayBuffer.isView === 'function' && ArrayBuffer.isView(obj) &&\n !(obj instanceof DataView) ?\n new obj.constructor(obj.length) :\n {};\n for (const key in obj) {\n clone[key] = unsafeClone(obj[key]);\n }\n return clone;\n}\n\n/**\n * Returns a new object in which all the keys and values are interchanged\n * (keys become values and values become keys). If multiple keys map to the\n * same value, the chosen transposed value is implementation-dependent.\n * @param {?Object} obj The object to transpose.\n * @return {!Object} The transposed object.\n */\nfunction transpose(obj) {\n const transposed = {};\n for (const key in obj) {\n transposed[obj[key]] = key;\n }\n return transposed;\n}\n\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {!Array<string>}\n */\nconst PROTOTYPE_FIELDS = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf',\n];\n\n/**\n * Extends an object with another object.\n * This operates 'in-place'; it does not create a new Object.\n * Example:\n * var o = {};\n * extend(o, {a: 0, b: 1});\n * o; // {a: 0, b: 1}\n * extend(o, {b: 2, c: 3});\n * o; // {a: 0, b: 2, c: 3}\n * @param {?Object} target The object to modify. Existing properties will be\n * overwritten if they are also present in one of the objects in `var_args`.\n * @param {...(?Object|undefined)} var_args The objects from which values\n * will be copied.\n * @return {void}\n * @deprecated Prefer Object.assign\n */\nfunction extend(target, var_args) {\n let key;\n let source;\n for (let i = 1; i < arguments.length; i++) {\n source = arguments[i];\n for (key in source) {\n target[key] = source[key];\n }\n\n // For IE the for-in-loop does not contain any properties that are not\n // enumerable on the prototype object (for example isPrototypeOf from\n // Object.prototype) and it will also not include 'replace' on objects that\n // extend String and change 'replace' (not that it is common for anyone to\n // extend anything except Object).\n\n for (let j = 0; j < PROTOTYPE_FIELDS.length; j++) {\n key = PROTOTYPE_FIELDS[j];\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n}\n\n/**\n * Creates a new object built from the key-value pairs provided as arguments.\n * @param {...*} var_args If only one argument is provided and it is an array\n * then this is used as the arguments, otherwise even arguments are used as\n * the property names and odd arguments are used as the property values.\n * @return {!Object} The new object.\n * @throws {!Error} If there are uneven number of arguments or there is only one\n * non array argument.\n */\nfunction create(var_args) {\n const argLength = arguments.length;\n if (argLength == 1 && Array.isArray(arguments[0])) {\n return create.apply(null, arguments[0]);\n }\n\n if (argLength % 2) {\n throw new Error('Uneven number of arguments');\n }\n\n const rv = {};\n for (let i = 0; i < argLength; i += 2) {\n rv[arguments[i]] = arguments[i + 1];\n }\n return rv;\n}\n\n/**\n * Creates a new object where the property names come from the arguments but\n * the value is always set to true\n * @param {...*} var_args If only one argument is provided and it is an array\n * then this is used as the arguments, otherwise the arguments are used as\n * the property names.\n * @return {!Object} The new object.\n */\nfunction createSet(var_args) {\n const argLength = arguments.length;\n if (argLength == 1 && Array.isArray(arguments[0])) {\n return createSet.apply(null, arguments[0]);\n }\n\n const rv = {};\n for (let i = 0; i < argLength; i++) {\n rv[arguments[i]] = true;\n }\n return rv;\n}\n\n/**\n * Creates an immutable view of the underlying object, if the browser\n * supports immutable objects.\n * In default mode, writes to this view will fail silently. In strict mode,\n * they will throw an error.\n * @param {!Object<K,V>} obj An object.\n * @return {!Object<K,V>} An immutable view of that object, or the original\n * object if this browser does not support immutables.\n * @template K,V\n */\nfunction createImmutableView(obj) {\n let result = obj;\n if (Object.isFrozen && !Object.isFrozen(obj)) {\n result = Object.create(obj);\n Object.freeze(result);\n }\n return result;\n}\n\n/**\n * @param {!Object} obj An object.\n * @return {boolean} Whether this is an immutable view of the object.\n */\nfunction isImmutableView(obj) {\n return !!Object.isFrozen && Object.isFrozen(obj);\n}\n\n/**\n * Get all properties names on a given Object regardless of enumerability.\n * <p> If the browser does not support `Object.getOwnPropertyNames` nor\n * `Object.getPrototypeOf` then this is equivalent to using\n * `getKeys`\n * @param {?Object} obj The object to get the properties of.\n * @param {boolean=} includeObjectPrototype Whether properties defined on\n * `Object.prototype` should be included in the result.\n * @param {boolean=} includeFunctionPrototype Whether properties defined on\n * `Function.prototype` should be included in the result.\n * @return {!Array<string>}\n * @public\n */\nfunction getAllPropertyNames(\n obj, includeObjectPrototype = undefined,\n includeFunctionPrototype = undefined) {\n if (!obj) {\n return [];\n }\n\n // Naively use a for..in loop to get the property names if the browser doesn't\n // support any other APIs for getting it.\n if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {\n return getKeys(obj);\n }\n\n const visitedSet = {};\n\n // Traverse the prototype chain and add all properties to the visited set.\n let proto = obj;\n while (proto && (proto !== Object.prototype || !!includeObjectPrototype) &&\n (proto !== Function.prototype || !!includeFunctionPrototype)) {\n const names = Object.getOwnPropertyNames(proto);\n for (let i = 0; i < names.length; i++) {\n visitedSet[names[i]] = true;\n }\n proto = Object.getPrototypeOf(proto);\n }\n\n return getKeys(visitedSet);\n}\n\n/**\n * Given a ES5 or ES6 class reference, return its super class / super\n * constructor.\n * This should be used in rare cases where you need to walk up the inheritance\n * tree (this is generally a bad idea). But this work with ES5 and ES6 classes,\n * unlike relying on the superClass_ property.\n * Note: To start walking up the hierarchy from an instance call this with its\n * `constructor` property; e.g. `getSuperClass(instance.constructor)`.\n * @param {function(new: ?)} constructor\n * @return {?Object}\n */\nfunction getSuperClass(constructor) {\n const proto = Object.getPrototypeOf(constructor.prototype);\n return proto && proto.constructor;\n}\n\nexports = {\n add,\n clear,\n clone,\n contains,\n containsKey,\n containsValue,\n create,\n createImmutableView,\n createSet,\n equals,\n every,\n extend,\n filter,\n findKey,\n findValue,\n forEach,\n get,\n getAllPropertyNames,\n getAnyKey,\n getAnyValue,\n getCount,\n getKeys,\n getSuperClass,\n getValueByKeys,\n getValues,\n isEmpty,\n isImmutableView,\n map,\n remove,\n set,\n setIfUndefined,\n setWithReturnValueIfNotSet,\n some,\n transpose,\n unsafeClone,\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An event manager for both native browser event\n * targets and custom JavaScript event targets\n * (`goog.events.Listenable`). This provides an abstraction\n * over browsers' event systems.\n *\n * It also provides a simulation of W3C event model's capture phase in\n * Internet Explorer (IE 8 and below). Caveat: the simulation does not\n * interact well with listeners registered directly on the elements\n * (bypassing goog.events) or even with listeners registered via\n * goog.events in a separate JS binary. In these cases, we provide\n * no ordering guarantees.\n *\n * The listeners will receive a \"patched\" event object. Such event object\n * contains normalized values for certain event properties that differs in\n * different browsers.\n *\n * Example usage:\n * <pre>\n * goog.events.listen(myNode, 'click', function(e) { alert('woo') });\n * goog.events.listen(myNode, 'mouseover', mouseHandler, true);\n * goog.events.unlisten(myNode, 'mouseover', mouseHandler, true);\n * goog.events.removeAll(myNode);\n * </pre>\n *\n * in IE and event object patching]\n *\n * @see ../demos/events.html\n * @see ../demos/event-propagation.html\n * @see ../demos/stopevent.html\n */\n\n// IMPLEMENTATION NOTES:\n// goog.events stores an auxiliary data structure on each EventTarget\n// source being listened on. This allows us to take advantage of GC,\n// having the data structure GC'd when the EventTarget is GC'd. This\n// GC behavior is equivalent to using W3C DOM Events directly.\n\ngoog.provide('goog.events');\ngoog.provide('goog.events.CaptureSimulationMode');\ngoog.provide('goog.events.Key');\ngoog.provide('goog.events.ListenableType');\n\ngoog.require('goog.asserts');\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.events.BrowserEvent');\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.events.ListenerMap');\ngoog.requireType('goog.debug.ErrorHandler');\ngoog.requireType('goog.events.EventId');\ngoog.requireType('goog.events.EventLike');\ngoog.requireType('goog.events.EventWrapper');\ngoog.requireType('goog.events.ListenableKey');\ngoog.requireType('goog.events.Listener');\n\n\n/**\n * @typedef {number|goog.events.ListenableKey}\n */\ngoog.events.Key;\n\n\n/**\n * @typedef {EventTarget|goog.events.Listenable}\n */\ngoog.events.ListenableType;\n\n\n/**\n * Property name on a native event target for the listener map\n * associated with the event target.\n * @private @const {string}\n */\ngoog.events.LISTENER_MAP_PROP_ = 'closure_lm_' + ((Math.random() * 1e6) | 0);\n\n\n/**\n * String used to prepend to IE event types.\n * @const\n * @private\n */\ngoog.events.onString_ = 'on';\n\n\n/**\n * Map of computed \"on<eventname>\" strings for IE event types. Caching\n * this removes an extra object allocation in goog.events.listen which\n * improves IE6 performance.\n * @const\n * @dict\n * @private\n */\ngoog.events.onStringMap_ = {};\n\n\n/**\n * @enum {number} Different capture simulation mode for IE8-.\n */\ngoog.events.CaptureSimulationMode = {\n /**\n * Does not perform capture simulation. Will asserts in IE8- when you\n * add capture listeners.\n */\n OFF_AND_FAIL: 0,\n\n /**\n * Does not perform capture simulation, silently ignore capture\n * listeners.\n */\n OFF_AND_SILENT: 1,\n\n /**\n * Performs capture simulation.\n */\n ON: 2\n};\n\n\n/**\n * @define {number} The capture simulation mode for IE8-. By default,\n * this is ON.\n */\ngoog.events.CAPTURE_SIMULATION_MODE =\n goog.define('goog.events.CAPTURE_SIMULATION_MODE', 2);\n\n\n/**\n * Estimated count of total native listeners.\n * @private {number}\n */\ngoog.events.listenerCountEstimate_ = 0;\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target (such as a DOM element) or an object that has implemented\n * {@link goog.events.Listenable}. A listener can only be added once\n * to an object and if it is added again the key for the listener is\n * returned. Note that if the existing listener is a one-off listener\n * (registered via listenOnce), it will no longer be a one-off\n * listener after a call to listen().\n *\n * @param {EventTarget|goog.events.Listenable} src The node to listen\n * to events on.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}\n * listener Callback method, or an object with a handleEvent function.\n * WARNING: passing an Object is now softly deprecated.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.Key} Unique key for the listener.\n * @template T,EVENTOBJ\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.listen = function(src, type, listener, opt_options, opt_handler) {\n 'use strict';\n if (opt_options && opt_options.once) {\n return goog.events.listenOnce(\n src, type, listener, opt_options, opt_handler);\n }\n if (Array.isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n goog.events.listen(src, type[i], listener, opt_options, opt_handler);\n }\n return null;\n }\n\n listener = goog.events.wrapListener(listener);\n if (goog.events.Listenable.isImplementedBy(src)) {\n var capture =\n goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n return src.listen(\n /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n opt_handler);\n } else {\n return goog.events.listen_(\n /** @type {!EventTarget} */ (src), type, listener,\n /* callOnce */ false, opt_options, opt_handler);\n }\n};\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target. A listener can only be added once to an object and if it\n * is added again the key for the listener is returned.\n *\n * Note that a one-off listener will not change an existing listener,\n * if any. On the other hand a normal listener will change existing\n * one-off listener to become a normal listener.\n *\n * @param {EventTarget} src The node to listen to events on.\n * @param {string|?goog.events.EventId<EVENTOBJ>} type Event type.\n * @param {!Function} listener Callback function.\n * @param {boolean} callOnce Whether the listener is a one-off\n * listener or otherwise.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.ListenableKey} Unique key for the listener.\n * @template EVENTOBJ\n * @private\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.listen_ = function(\n src, type, listener, callOnce, opt_options, opt_handler) {\n 'use strict';\n if (!type) {\n throw new Error('Invalid event type');\n }\n\n var capture =\n goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n\n var listenerMap = goog.events.getListenerMap_(src);\n if (!listenerMap) {\n src[goog.events.LISTENER_MAP_PROP_] = listenerMap =\n new goog.events.ListenerMap(src);\n }\n\n var listenerObj = /** @type {goog.events.Listener} */ (\n listenerMap.add(type, listener, callOnce, capture, opt_handler));\n\n // If the listenerObj already has a proxy, it has been set up\n // previously. We simply return.\n if (listenerObj.proxy) {\n return listenerObj;\n }\n\n var proxy = goog.events.getProxy();\n listenerObj.proxy = proxy;\n\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n proxy.src = src;\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n proxy.listener = listenerObj;\n\n // Attach the proxy through the browser's API\n if (src.addEventListener) {\n // Don't pass an object as `capture` if the browser doesn't support that.\n if (!goog.events.BrowserFeature.PASSIVE_EVENTS) {\n opt_options = capture;\n }\n // Don't break tests that expect a boolean.\n if (opt_options === undefined) opt_options = false;\n src.addEventListener(type.toString(), proxy, opt_options);\n } else if (src.attachEvent) {\n // The else if above used to be an unconditional else. It would call\n // attachEvent come gws or high water. This would sometimes throw an\n // exception on IE11, spoiling the day of some callers. The previous\n // incarnation of this code, from 2007, indicates that it replaced an\n // earlier still version that caused excess allocations on IE6.\n src.attachEvent(goog.events.getOnString_(type.toString()), proxy);\n } else if (src.addListener && src.removeListener) {\n // In IE, MediaQueryList uses addListener() insteadd of addEventListener. In\n // Safari, there is no global for the MediaQueryList constructor, so we just\n // check whether the object \"looks like\" MediaQueryList.\n goog.asserts.assert(\n type === 'change', 'MediaQueryList only has a change event');\n src.addListener(proxy);\n } else {\n throw new Error('addEventListener and attachEvent are unavailable.');\n }\n\n goog.events.listenerCountEstimate_++;\n return listenerObj;\n};\n\n\n/**\n * Helper function for returning a proxy function.\n * @return {!Function} A new or reused function object.\n */\ngoog.events.getProxy = function() {\n 'use strict';\n const proxyCallbackFunction = goog.events.handleBrowserEvent_;\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n const f = function(eventObject) {\n return proxyCallbackFunction.call(f.src, f.listener, eventObject);\n };\n return f;\n};\n\n\n/**\n * Adds an event listener for a specific event on a native event\n * target (such as a DOM element) or an object that has implemented\n * {@link goog.events.Listenable}. After the event has fired the event\n * listener is removed from the target.\n *\n * If an existing listener already exists, listenOnce will do\n * nothing. In particular, if the listener was previously registered\n * via listen(), listenOnce() will not turn the listener into a\n * one-off listener. Similarly, if there is already an existing\n * one-off listener, listenOnce does not modify the listeners (it is\n * still a once listener).\n *\n * @param {EventTarget|goog.events.Listenable} src The node to listen\n * to events on.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}\n * listener Callback method.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.Key} Unique key for the listener.\n * @template T,EVENTOBJ\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.listenOnce = function(\n src, type, listener, opt_options, opt_handler) {\n 'use strict';\n if (Array.isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n goog.events.listenOnce(src, type[i], listener, opt_options, opt_handler);\n }\n return null;\n }\n\n listener = goog.events.wrapListener(listener);\n if (goog.events.Listenable.isImplementedBy(src)) {\n var capture =\n goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n return src.listenOnce(\n /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n opt_handler);\n } else {\n return goog.events.listen_(\n /** @type {!EventTarget} */ (src), type, listener,\n /* callOnce */ true, opt_options, opt_handler);\n }\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.Listenable}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.Listenable} src The target to\n * listen to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:T, ?):?|{handleEvent:function(?):?}|null} listener\n * Callback method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n * false).\n * @param {T=} opt_handler Element in whose scope to call the listener.\n * @template T\n */\ngoog.events.listenWithWrapper = function(\n src, wrapper, listener, opt_capt, opt_handler) {\n 'use strict';\n wrapper.listen(src, listener, opt_capt, opt_handler);\n};\n\n\n/**\n * Removes an event listener which was added with listen().\n *\n * @param {EventTarget|goog.events.Listenable} src The target to stop\n * listening to events on.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type or array of event types to unlisten to.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n * listener function to remove.\n * @param {(boolean|!EventListenerOptions)=} opt_options\n * whether the listener is fired during the capture or bubble phase of the\n * event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {?boolean} indicating whether the listener was there to remove.\n * @template EVENTOBJ\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.unlisten = function(src, type, listener, opt_options, opt_handler) {\n 'use strict';\n if (Array.isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n goog.events.unlisten(src, type[i], listener, opt_options, opt_handler);\n }\n return null;\n }\n var capture =\n goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n\n listener = goog.events.wrapListener(listener);\n if (goog.events.Listenable.isImplementedBy(src)) {\n return src.unlisten(\n /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n opt_handler);\n }\n\n if (!src) {\n // TODO(chrishenry): We should tighten the API to only accept\n // non-null objects, or add an assertion here.\n return false;\n }\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {!EventTarget} */ (src));\n if (listenerMap) {\n var listenerObj = listenerMap.getListener(\n /** @type {string|!goog.events.EventId} */ (type), listener, capture,\n opt_handler);\n if (listenerObj) {\n return goog.events.unlistenByKey(listenerObj);\n }\n }\n\n return false;\n};\n\n\n/**\n * Removes an event listener which was added with listen() by the key\n * returned by listen().\n *\n * @param {goog.events.Key} key The key returned by listen() for this\n * event listener.\n * @return {boolean} indicating whether the listener was there to remove.\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.unlistenByKey = function(key) {\n 'use strict';\n // TODO(chrishenry): Remove this check when tests that rely on this\n // are fixed.\n if (typeof key === 'number') {\n return false;\n }\n\n var listener = key;\n if (!listener || listener.removed) {\n return false;\n }\n\n var src = listener.src;\n if (goog.events.Listenable.isImplementedBy(src)) {\n return /** @type {!goog.events.Listenable} */ (src).unlistenByKey(listener);\n }\n\n var type = listener.type;\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n var proxy = listener.proxy;\n if (src.removeEventListener) {\n src.removeEventListener(type, proxy, listener.capture);\n } else if (src.detachEvent) {\n src.detachEvent(goog.events.getOnString_(type), proxy);\n } else if (src.addListener && src.removeListener) {\n src.removeListener(proxy);\n }\n goog.events.listenerCountEstimate_--;\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {!EventTarget} */ (src));\n // TODO(chrishenry): Try to remove this conditional and execute the\n // first branch always. This should be safe.\n if (listenerMap) {\n listenerMap.removeByKey(listener);\n if (listenerMap.getTypeCount() == 0) {\n // Null the src, just because this is simple to do (and useful\n // for IE <= 7).\n listenerMap.src = null;\n // We don't use delete here because IE does not allow delete\n // on a window object.\n src[goog.events.LISTENER_MAP_PROP_] = null;\n }\n } else {\n /** @type {!goog.events.Listener} */ (listener).markAsRemoved();\n }\n\n return true;\n};\n\n\n/**\n * Removes an event listener which was added with listenWithWrapper().\n *\n * @param {EventTarget|goog.events.Listenable} src The target to stop\n * listening to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n * listener function to remove.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n * whether the listener is fired during the capture or bubble phase of the\n * event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n */\ngoog.events.unlistenWithWrapper = function(\n src, wrapper, listener, opt_capt, opt_handler) {\n 'use strict';\n wrapper.unlisten(src, listener, opt_capt, opt_handler);\n};\n\n\n/**\n * Removes all listeners from an object. You can also optionally\n * remove listeners of a particular type.\n *\n * @param {Object|undefined} obj Object to remove listeners from. Must be an\n * EventTarget or a goog.events.Listenable.\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove.\n * Default is all types.\n * @return {number} Number of listeners removed.\n */\ngoog.events.removeAll = function(obj, opt_type) {\n 'use strict';\n // TODO(chrishenry): Change the type of obj to\n // (!EventTarget|!goog.events.Listenable).\n\n if (!obj) {\n return 0;\n }\n\n if (goog.events.Listenable.isImplementedBy(obj)) {\n return /** @type {?} */ (obj).removeAllListeners(opt_type);\n }\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {!EventTarget} */ (obj));\n if (!listenerMap) {\n return 0;\n }\n\n var count = 0;\n var typeStr = opt_type && opt_type.toString();\n for (var type in listenerMap.listeners) {\n if (!typeStr || type == typeStr) {\n // Clone so that we don't need to worry about unlistenByKey\n // changing the content of the ListenerMap.\n var listeners = listenerMap.listeners[type].concat();\n for (var i = 0; i < listeners.length; ++i) {\n if (goog.events.unlistenByKey(listeners[i])) {\n ++count;\n }\n }\n }\n }\n return count;\n};\n\n\n/**\n * Gets the listeners for a given object, type and capture phase.\n *\n * @param {Object} obj Object to get listeners for.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Capture phase?.\n * @return {!Array<!goog.events.Listener>} Array of listener objects.\n */\ngoog.events.getListeners = function(obj, type, capture) {\n 'use strict';\n if (goog.events.Listenable.isImplementedBy(obj)) {\n return /** @type {!goog.events.Listenable} */ (obj).getListeners(\n type, capture);\n } else {\n if (!obj) {\n // TODO(chrishenry): We should tighten the API to accept\n // !EventTarget|goog.events.Listenable, and add an assertion here.\n return [];\n }\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {!EventTarget} */ (obj));\n return listenerMap ? listenerMap.getListeners(type, capture) : [];\n }\n};\n\n\n/**\n * Gets the goog.events.Listener for the event or null if no such listener is\n * in use.\n *\n * @param {EventTarget|goog.events.Listenable} src The target from\n * which to get listeners.\n * @param {?string|!goog.events.EventId<EVENTOBJ>} type The type of the event.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null} listener The\n * listener function to get.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n * whether the listener is fired during the\n * capture or bubble phase of the event.\n * @param {Object=} opt_handler Element in whose scope to call the listener.\n * @return {goog.events.ListenableKey} the found listener or null if not found.\n * @template EVENTOBJ\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {\n 'use strict';\n // TODO(chrishenry): Change type from ?string to string, or add assertion.\n type = /** @type {string} */ (type);\n listener = goog.events.wrapListener(listener);\n var capture = !!opt_capt;\n if (goog.events.Listenable.isImplementedBy(src)) {\n return src.getListener(type, listener, capture, opt_handler);\n }\n\n if (!src) {\n // TODO(chrishenry): We should tighten the API to only accept\n // non-null objects, or add an assertion here.\n return null;\n }\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {!EventTarget} */ (src));\n if (listenerMap) {\n return listenerMap.getListener(type, listener, capture, opt_handler);\n }\n return null;\n};\n\n\n/**\n * Returns whether an event target has any active listeners matching the\n * specified signature. If either the type or capture parameters are\n * unspecified, the function will match on the remaining criteria.\n *\n * @param {EventTarget|goog.events.Listenable} obj Target to get\n * listeners for.\n * @param {string|!goog.events.EventId=} opt_type Event type.\n * @param {boolean=} opt_capture Whether to check for capture or bubble-phase\n * listeners.\n * @return {boolean} Whether an event target has one or more listeners matching\n * the requested type and/or capture phase.\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.hasListener = function(obj, opt_type, opt_capture) {\n 'use strict';\n if (goog.events.Listenable.isImplementedBy(obj)) {\n return obj.hasListener(opt_type, opt_capture);\n }\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {!EventTarget} */ (obj));\n return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture);\n};\n\n\n/**\n * Provides a nice string showing the normalized event objects public members\n * @param {Object} e Event Object.\n * @return {string} String of the public members of the normalized event object.\n */\ngoog.events.expose = function(e) {\n 'use strict';\n var str = [];\n for (var key in e) {\n if (e[key] && e[key].id) {\n str.push(key + ' = ' + e[key] + ' (' + e[key].id + ')');\n } else {\n str.push(key + ' = ' + e[key]);\n }\n }\n return str.join('\\n');\n};\n\n\n/**\n * Returns a string with on prepended to the specified type. This is used for IE\n * which expects \"on\" to be prepended. This function caches the string in order\n * to avoid extra allocations in steady state.\n * @param {string} type Event type.\n * @return {string} The type string with 'on' prepended.\n * @private\n */\ngoog.events.getOnString_ = function(type) {\n 'use strict';\n if (type in goog.events.onStringMap_) {\n return goog.events.onStringMap_[type];\n }\n return goog.events.onStringMap_[type] = goog.events.onString_ + type;\n};\n\n\n/**\n * Fires an object's listeners of a particular type and phase\n *\n * @param {Object} obj Object whose listeners to call.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Which event phase.\n * @param {Object} eventObject Event object to be passed to listener.\n * @return {boolean} True if all listeners returned true else false.\n */\ngoog.events.fireListeners = function(obj, type, capture, eventObject) {\n 'use strict';\n if (goog.events.Listenable.isImplementedBy(obj)) {\n return /** @type {!goog.events.Listenable} */ (obj).fireListeners(\n type, capture, eventObject);\n }\n\n return goog.events.fireListeners_(obj, type, capture, eventObject);\n};\n\n\n/**\n * Fires an object's listeners of a particular type and phase.\n * @param {Object} obj Object whose listeners to call.\n * @param {string|!goog.events.EventId} type Event type.\n * @param {boolean} capture Which event phase.\n * @param {Object} eventObject Event object to be passed to listener.\n * @return {boolean} True if all listeners returned true else false.\n * @private\n */\ngoog.events.fireListeners_ = function(obj, type, capture, eventObject) {\n 'use strict';\n /** @type {boolean} */\n var retval = true;\n\n var listenerMap = goog.events.getListenerMap_(\n /** @type {EventTarget} */ (obj));\n if (listenerMap) {\n // TODO(chrishenry): Original code avoids array creation when there\n // is no listener, so we do the same. If this optimization turns\n // out to be not required, we can replace this with\n // listenerMap.getListeners(type, capture) instead, which is simpler.\n var listenerArray = listenerMap.listeners[type.toString()];\n if (listenerArray) {\n listenerArray = listenerArray.concat();\n for (var i = 0; i < listenerArray.length; i++) {\n var listener = listenerArray[i];\n // We might not have a listener if the listener was removed.\n if (listener && listener.capture == capture && !listener.removed) {\n var result = goog.events.fireListener(listener, eventObject);\n retval = retval && (result !== false);\n }\n }\n }\n }\n return retval;\n};\n\n\n/**\n * Fires a listener with a set of arguments\n *\n * @param {goog.events.Listener} listener The listener object to call.\n * @param {Object} eventObject The event object to pass to the listener.\n * @return {*} Result of listener.\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.fireListener = function(listener, eventObject) {\n 'use strict';\n var listenerFn = listener.listener;\n var listenerHandler = listener.handler || listener.src;\n\n if (listener.callOnce) {\n goog.events.unlistenByKey(listener);\n }\n return listenerFn.call(listenerHandler, eventObject);\n};\n\n\n/**\n * Gets the total number of listeners currently in the system.\n * @return {number} Number of listeners.\n * @deprecated This returns estimated count, now that Closure no longer\n * stores a central listener registry. We still return an estimation\n * to keep existing listener-related tests passing. In the near future,\n * this function will be removed.\n */\ngoog.events.getTotalListenerCount = function() {\n 'use strict';\n return goog.events.listenerCountEstimate_;\n};\n\n\n/**\n * Dispatches an event (or event like object) and calls all listeners\n * listening for events of this type. The type of the event is decided by the\n * type property on the event object.\n *\n * If any of the listeners returns false OR calls preventDefault then this\n * function will return false. If one of the capture listeners calls\n * stopPropagation, then the bubble listeners won't fire.\n *\n * @param {goog.events.Listenable} src The event target.\n * @param {goog.events.EventLike} e Event object.\n * @return {boolean} If anyone called preventDefault on the event object (or\n * if any of the handlers returns false) this will also return false.\n * If there are no handlers, or if all handlers return true, this returns\n * true.\n */\ngoog.events.dispatchEvent = function(src, e) {\n 'use strict';\n goog.asserts.assert(\n goog.events.Listenable.isImplementedBy(src),\n 'Can not use goog.events.dispatchEvent with ' +\n 'non-goog.events.Listenable instance.');\n return src.dispatchEvent(e);\n};\n\n\n/**\n * Installs exception protection for the browser event entry point using the\n * given error handler.\n *\n * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to\n * protect the entry point.\n */\ngoog.events.protectBrowserEventEntryPoint = function(errorHandler) {\n 'use strict';\n goog.events.handleBrowserEvent_ =\n errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_);\n};\n\n\n/**\n * Handles an event and dispatches it to the correct listeners. This\n * function is a proxy for the real listener the user specified.\n *\n * @param {goog.events.Listener} listener The listener object.\n * @param {Event=} opt_evt Optional event object that gets passed in via the\n * native event handlers.\n * @return {*} Result of the event handler.\n * @this {EventTarget} The object or Element that fired the event.\n * @private\n */\ngoog.events.handleBrowserEvent_ = function(listener, opt_evt) {\n 'use strict';\n if (listener.removed) {\n return true;\n }\n\n // Otherwise, simply fire the listener.\n return goog.events.fireListener(\n listener, new goog.events.BrowserEvent(opt_evt, this));\n};\n\n\n/**\n * This is used to mark the IE event object so we do not do the Closure pass\n * twice for a bubbling event.\n * @param {Event} e The IE browser event.\n * @private\n */\ngoog.events.markIeEvent_ = function(e) {\n 'use strict';\n // Only the keyCode and the returnValue can be changed. We use keyCode for\n // non keyboard events.\n // event.returnValue is a bit more tricky. It is undefined by default. A\n // boolean false prevents the default action. In a window.onbeforeunload and\n // the returnValue is non undefined it will be alerted. However, we will only\n // modify the returnValue for keyboard events. We can get a problem if non\n // closure events sets the keyCode or the returnValue\n\n var useReturnValue = false;\n\n if (e.keyCode == 0) {\n // We cannot change the keyCode in case that srcElement is input[type=file].\n // We could test that that is the case but that would allocate 3 objects.\n // If we use try/catch we will only allocate extra objects in the case of a\n // failure.\n\n try {\n e.keyCode = -1;\n return;\n } catch (ex) {\n useReturnValue = true;\n }\n }\n\n if (useReturnValue ||\n /** @type {boolean|undefined} */ (e.returnValue) == undefined) {\n e.returnValue = true;\n }\n};\n\n\n/**\n * This is used to check if an IE event has already been handled by the Closure\n * system so we do not do the Closure pass twice for a bubbling event.\n * @param {Event} e The IE browser event.\n * @return {boolean} True if the event object has been marked.\n * @private\n */\ngoog.events.isMarkedIeEvent_ = function(e) {\n 'use strict';\n return e.keyCode < 0 || e.returnValue != undefined;\n};\n\n\n/**\n * Counter to create unique event ids.\n * @private {number}\n */\ngoog.events.uniqueIdCounter_ = 0;\n\n\n/**\n * Creates a unique event id.\n *\n * @param {string} identifier The identifier.\n * @return {string} A unique identifier.\n * @idGenerator {unique}\n */\ngoog.events.getUniqueId = function(identifier) {\n 'use strict';\n return identifier + '_' + goog.events.uniqueIdCounter_++;\n};\n\n\n/**\n * @param {EventTarget} src The source object.\n * @return {goog.events.ListenerMap} A listener map for the given\n * source object, or null if none exists.\n * @private\n */\ngoog.events.getListenerMap_ = function(src) {\n 'use strict';\n var listenerMap = src[goog.events.LISTENER_MAP_PROP_];\n // IE serializes the property as well (e.g. when serializing outer\n // HTML). So we must check that the value is of the correct type.\n return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null;\n};\n\n\n/**\n * Expando property for listener function wrapper for Object with\n * handleEvent.\n * @private @const {string}\n */\ngoog.events.LISTENER_WRAPPER_PROP_ =\n '__closure_events_fn_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * @param {Object|Function} listener The listener function or an\n * object that contains handleEvent method.\n * @return {!Function} Either the original function or a function that\n * calls obj.handleEvent. If the same listener is passed to this\n * function more than once, the same function is guaranteed to be\n * returned.\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.events.wrapListener = function(listener) {\n 'use strict';\n goog.asserts.assert(listener, 'Listener can not be null.');\n\n if (typeof listener === 'function') {\n return listener;\n }\n\n goog.asserts.assert(\n listener.handleEvent, 'An object listener must have handleEvent method.');\n if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) {\n listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) {\n 'use strict';\n return /** @type {?} */ (listener).handleEvent(e);\n };\n }\n return listener[goog.events.LISTENER_WRAPPER_PROP_];\n};\n\n\n// Register the browser event handler as an entry point, so that\n// it can be monitored for exception handling, etc.\ngoog.debug.entryPointRegistry.register(\n /**\n * @param {function(!Function): !Function} transformer The transforming\n * function.\n */\n function(transformer) {\n 'use strict';\n goog.events.handleBrowserEvent_ =\n transformer(goog.events.handleBrowserEvent_);\n });\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A disposable implementation of a custom\n * listenable/event target. See also: documentation for\n * `goog.events.Listenable`.\n *\n * @see ../demos/eventtarget.html\n * @see goog.events.Listenable\n */\n\ngoog.provide('goog.events.EventTarget');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.asserts');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.events.ListenerMap');\ngoog.require('goog.object');\ngoog.requireType('goog.events.EventId');\ngoog.requireType('goog.events.EventLike');\ngoog.requireType('goog.events.ListenableKey');\n\n\n\n/**\n * An implementation of `goog.events.Listenable` with full W3C\n * EventTarget-like support (capture/bubble mechanism, stopping event\n * propagation, preventing default actions).\n *\n * You may subclass this class to turn your class into a Listenable.\n *\n * Unless propagation is stopped, an event dispatched by an\n * EventTarget will bubble to the parent returned by\n * `getParentEventTarget`. To set the parent, call\n * `setParentEventTarget`. Subclasses that don't support\n * changing the parent can override the setter to throw an error.\n *\n * Example usage:\n * <pre>\n * var source = new goog.events.EventTarget();\n * function handleEvent(e) {\n * alert('Type: ' + e.type + '; Target: ' + e.target);\n * }\n * source.listen('foo', handleEvent);\n * // Or: goog.events.listen(source, 'foo', handleEvent);\n * ...\n * source.dispatchEvent('foo'); // will call handleEvent\n * ...\n * source.unlisten('foo', handleEvent);\n * // Or: goog.events.unlisten(source, 'foo', handleEvent);\n * </pre>\n *\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.events.Listenable}\n */\ngoog.events.EventTarget = function() {\n 'use strict';\n goog.Disposable.call(this);\n\n /**\n * Maps of event type to an array of listeners.\n * @private {!goog.events.ListenerMap}\n */\n this.eventTargetListeners_ = new goog.events.ListenerMap(this);\n\n /**\n * The object to use for event.target. Useful when mixing in an\n * EventTarget to another object.\n * @private {!Object}\n */\n this.actualEventTarget_ = this;\n\n /**\n * Parent event target, used during event bubbling.\n *\n * TODO(chrishenry): Change this to goog.events.Listenable. This\n * currently breaks people who expect getParentEventTarget to return\n * goog.events.EventTarget.\n *\n * @private {?goog.events.EventTarget}\n */\n this.parentEventTarget_ = null;\n};\ngoog.inherits(goog.events.EventTarget, goog.Disposable);\ngoog.events.Listenable.addImplementation(goog.events.EventTarget);\n\n\n/**\n * An artificial cap on the number of ancestors you can have. This is mainly\n * for loop detection.\n * @const {number}\n * @private\n */\ngoog.events.EventTarget.MAX_ANCESTORS_ = 1000;\n\n\n/**\n * Returns the parent of this event target to use for bubbling.\n *\n * @return {goog.events.EventTarget} The parent EventTarget or null if\n * there is no parent.\n * @override\n */\ngoog.events.EventTarget.prototype.getParentEventTarget = function() {\n 'use strict';\n return this.parentEventTarget_;\n};\n\n\n/**\n * Sets the parent of this event target to use for capture/bubble\n * mechanism.\n * @param {goog.events.EventTarget} parent Parent listenable (null if none).\n */\ngoog.events.EventTarget.prototype.setParentEventTarget = function(parent) {\n 'use strict';\n this.parentEventTarget_ = parent;\n};\n\n\n/**\n * Adds an event listener to the event target. The same handler can only be\n * added once per the type. Even if you add the same handler multiple times\n * using the same type then it will only be called once when the event is\n * dispatched.\n *\n * @param {string|!goog.events.EventId} type The type of the event to listen for\n * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function\n * to handle the event. The handler can also be an object that implements\n * the handleEvent method which takes the event object as argument.\n * @param {boolean=} opt_capture In DOM-compliant browsers, this determines\n * whether the listener is fired during the capture or bubble phase\n * of the event.\n * @param {Object=} opt_handlerScope Object in whose scope to call\n * the listener.\n * @deprecated Use `#listen` instead, when possible. Otherwise, use\n * `goog.events.listen` if you are passing Object\n * (instead of Function) as handler.\n */\ngoog.events.EventTarget.prototype.addEventListener = function(\n type, handler, opt_capture, opt_handlerScope) {\n 'use strict';\n goog.events.listen(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/**\n * Removes an event listener from the event target. The handler must be the\n * same object as the one added. If the handler has not been added then\n * nothing is done.\n *\n * @param {string|!goog.events.EventId} type The type of the event to listen for\n * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function\n * to handle the event. The handler can also be an object that implements\n * the handleEvent method which takes the event object as argument.\n * @param {boolean=} opt_capture In DOM-compliant browsers, this determines\n * whether the listener is fired during the capture or bubble phase\n * of the event.\n * @param {Object=} opt_handlerScope Object in whose scope to call\n * the listener.\n * @deprecated Use `#unlisten` instead, when possible. Otherwise, use\n * `goog.events.unlisten` if you are passing Object\n * (instead of Function) as handler.\n */\ngoog.events.EventTarget.prototype.removeEventListener = function(\n type, handler, opt_capture, opt_handlerScope) {\n 'use strict';\n goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/**\n * @param {?goog.events.EventLike} e Event object.\n * @return {boolean} If anyone called preventDefault on the event object (or\n * if any of the listeners returns false) this will also return false.\n * @override\n */\ngoog.events.EventTarget.prototype.dispatchEvent = function(e) {\n 'use strict';\n this.assertInitialized_();\n\n var ancestorsTree, ancestor = this.getParentEventTarget();\n if (ancestor) {\n ancestorsTree = [];\n var ancestorCount = 1;\n for (; ancestor; ancestor = ancestor.getParentEventTarget()) {\n ancestorsTree.push(ancestor);\n goog.asserts.assert(\n (++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_),\n 'infinite loop');\n }\n }\n\n return goog.events.EventTarget.dispatchEventInternal_(\n this.actualEventTarget_, e, ancestorsTree);\n};\n\n\n/**\n * Removes listeners from this object. Classes that extend EventTarget may\n * need to override this method in order to remove references to DOM Elements\n * and additional listeners.\n * @override\n * @protected\n */\ngoog.events.EventTarget.prototype.disposeInternal = function() {\n 'use strict';\n goog.events.EventTarget.superClass_.disposeInternal.call(this);\n\n this.removeAllListeners();\n this.parentEventTarget_ = null;\n};\n\n\n/**\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n * method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n * (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n * @template SCOPE,EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.listen = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n 'use strict';\n this.assertInitialized_();\n return this.eventTargetListeners_.add(\n String(type), listener, false /* callOnce */, opt_useCapture,\n opt_listenerScope);\n};\n\n\n/**\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n * method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n * (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {!goog.events.ListenableKey} Unique key for the listener.\n * @template SCOPE,EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.listenOnce = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n 'use strict';\n return this.eventTargetListeners_.add(\n String(type), listener, true /* callOnce */, opt_useCapture,\n opt_listenerScope);\n};\n\n\n/**\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback\n * method.\n * @param {boolean=} opt_useCapture Whether to fire in capture phase\n * (defaults to false).\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call\n * the listener.\n * @return {boolean} Whether any listener was removed.\n * @template SCOPE,EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.unlisten = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n 'use strict';\n return this.eventTargetListeners_.remove(\n String(type), listener, opt_useCapture, opt_listenerScope);\n};\n\n\n/**\n * @param {!goog.events.ListenableKey} key The key returned by\n * listen() or listenOnce().\n * @return {boolean} Whether any listener was removed.\n * @override\n */\ngoog.events.EventTarget.prototype.unlistenByKey = function(key) {\n 'use strict';\n return this.eventTargetListeners_.removeByKey(key);\n};\n\n\n/**\n * @param {string|!goog.events.EventId=} opt_type Type of event to remove,\n * default is to remove all types.\n * @return {number} Number of listeners removed.\n * @override\n */\ngoog.events.EventTarget.prototype.removeAllListeners = function(opt_type) {\n 'use strict';\n // TODO(chrishenry): Previously, removeAllListeners can be called on\n // uninitialized EventTarget, so we preserve that behavior. We\n // should remove this when usages that rely on that fact are purged.\n if (!this.eventTargetListeners_) {\n return 0;\n }\n return this.eventTargetListeners_.removeAll(opt_type);\n};\n\n\n/**\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The type of the\n * listeners to fire.\n * @param {boolean} capture The capture mode of the listeners to fire.\n * @param {EVENTOBJ} eventObject The event object to fire.\n * @return {boolean} Whether all listeners succeeded without\n * attempting to prevent default behavior. If any listener returns\n * false or called goog.events.Event#preventDefault, this returns\n * false.\n * @template EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.fireListeners = function(\n type, capture, eventObject) {\n 'use strict';\n // TODO(chrishenry): Original code avoids array creation when there\n // is no listener, so we do the same. If this optimization turns\n // out to be not required, we can replace this with\n // getListeners(type, capture) instead, which is simpler.\n var listenerArray = this.eventTargetListeners_.listeners[String(type)];\n if (!listenerArray) {\n return true;\n }\n listenerArray = listenerArray.concat();\n\n var rv = true;\n for (var i = 0; i < listenerArray.length; ++i) {\n var listener = listenerArray[i];\n // We might not have a listener if the listener was removed.\n if (listener && !listener.removed && listener.capture == capture) {\n var listenerFn = listener.listener;\n var listenerHandler = listener.handler || listener.src;\n\n if (listener.callOnce) {\n this.unlistenByKey(listener);\n }\n rv = listenerFn.call(listenerHandler, eventObject) !== false && rv;\n }\n }\n\n return rv && !eventObject.defaultPrevented;\n};\n\n\n/**\n * @param {string|!goog.events.EventId} type The type of the listeners to fire.\n * @param {boolean} capture The capture mode of the listeners to fire.\n * @return {!Array<!goog.events.ListenableKey>} An array of registered\n * listeners.\n * @template EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.getListeners = function(type, capture) {\n 'use strict';\n return this.eventTargetListeners_.getListeners(String(type), capture);\n};\n\n\n/**\n * @param {string|!goog.events.EventId<EVENTOBJ>} type The name of the event\n * without the 'on' prefix.\n * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener The\n * listener function to get.\n * @param {boolean} capture Whether the listener is a capturing listener.\n * @param {SCOPE=} opt_listenerScope Object in whose scope to call the\n * listener.\n * @return {?goog.events.ListenableKey} the found listener or null if not found.\n * @template SCOPE,EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.getListener = function(\n type, listener, capture, opt_listenerScope) {\n 'use strict';\n return this.eventTargetListeners_.getListener(\n String(type), listener, capture, opt_listenerScope);\n};\n\n\n/**\n * @param {string|!goog.events.EventId<EVENTOBJ>=} opt_type Event type.\n * @param {boolean=} opt_capture Whether to check for capture or bubble\n * listeners.\n * @return {boolean} Whether there is any active listeners matching\n * the requested type and/or capture phase.\n * @template EVENTOBJ\n * @override\n */\ngoog.events.EventTarget.prototype.hasListener = function(\n opt_type, opt_capture) {\n 'use strict';\n var id = (opt_type !== undefined) ? String(opt_type) : undefined;\n return this.eventTargetListeners_.hasListener(id, opt_capture);\n};\n\n\n/**\n * Sets the target to be used for `event.target` when firing\n * event. Mainly used for testing. For example, see\n * `goog.testing.events.mixinListenable`.\n * @param {!Object} target The target.\n */\ngoog.events.EventTarget.prototype.setTargetForTesting = function(target) {\n 'use strict';\n this.actualEventTarget_ = target;\n};\n\n\n/**\n * Asserts that the event target instance is initialized properly.\n * @private\n */\ngoog.events.EventTarget.prototype.assertInitialized_ = function() {\n 'use strict';\n goog.asserts.assert(\n this.eventTargetListeners_,\n 'Event target is not initialized. Did you call the superclass ' +\n '(goog.events.EventTarget) constructor?');\n};\n\n\n/**\n * Dispatches the given event on the ancestorsTree.\n *\n * @param {!Object} target The target to dispatch on.\n * @param {goog.events.Event|Object|string} e The event object.\n * @param {Array<goog.events.Listenable>=} opt_ancestorsTree The ancestors\n * tree of the target, in reverse order from the closest ancestor\n * to the root event target. May be null if the target has no ancestor.\n * @return {boolean} If anyone called preventDefault on the event object (or\n * if any of the listeners returns false) this will also return false.\n * @private\n */\ngoog.events.EventTarget.dispatchEventInternal_ = function(\n target, e, opt_ancestorsTree) {\n 'use strict';\n /** @suppress {missingProperties} */\n var type = e.type || /** @type {string} */ (e);\n\n // If accepting a string or object, create a custom event object so that\n // preventDefault and stopPropagation work with the event.\n if (typeof e === 'string') {\n e = new goog.events.Event(e, target);\n } else if (!(e instanceof goog.events.Event)) {\n var oldEvent = e;\n e = new goog.events.Event(type, target);\n goog.object.extend(e, oldEvent);\n } else {\n e.target = e.target || target;\n }\n\n var rv = true, currentTarget;\n\n // Executes all capture listeners on the ancestors, if any.\n if (opt_ancestorsTree) {\n for (var i = opt_ancestorsTree.length - 1;\n !e.hasPropagationStopped() && i >= 0; i--) {\n currentTarget = e.currentTarget = opt_ancestorsTree[i];\n rv = currentTarget.fireListeners(type, true, e) && rv;\n }\n }\n\n // Executes capture and bubble listeners on the target.\n if (!e.hasPropagationStopped()) {\n currentTarget = /** @type {?} */ (e.currentTarget = target);\n rv = currentTarget.fireListeners(type, true, e) && rv;\n if (!e.hasPropagationStopped()) {\n rv = currentTarget.fireListeners(type, false, e) && rv;\n }\n }\n\n // Executes all bubble listeners on the ancestors, if any.\n if (opt_ancestorsTree) {\n for (i = 0; !e.hasPropagationStopped() && i < opt_ancestorsTree.length;\n i++) {\n currentTarget = e.currentTarget = opt_ancestorsTree[i];\n rv = currentTarget.fireListeners(type, false, e) && rv;\n }\n }\n\n return rv;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview JSON utility functions.\n */\n\n\ngoog.provide('goog.json');\ngoog.provide('goog.json.Replacer');\ngoog.provide('goog.json.Reviver');\ngoog.provide('goog.json.Serializer');\n\n\n/**\n * @define {boolean} If true, use the native JSON parsing API.\n * NOTE: The default `goog.json.parse` implementation is able to handle\n * invalid JSON. JSPB used to produce invalid JSON which is not the case\n * anymore so this is safe to enable for parsing JSPB. Using native JSON is\n * faster and safer than the default implementation using `eval`.\n */\ngoog.json.USE_NATIVE_JSON = goog.define('goog.json.USE_NATIVE_JSON', false);\n\n\n/**\n * Tests if a string is an invalid JSON string. This only ensures that we are\n * not using any invalid characters\n * @param {string} s The string to test.\n * @return {boolean} True if the input is a valid JSON string.\n */\ngoog.json.isValid = function(s) {\n 'use strict';\n // All empty whitespace is not valid.\n if (/^\\s*$/.test(s)) {\n return false;\n }\n\n // This is taken from http://www.json.org/json2.js which is released to the\n // public domain.\n // Changes: We dissallow \\u2028 Line separator and \\u2029 Paragraph separator\n // inside strings. We also treat \\u2028 and \\u2029 as whitespace which they\n // are in the RFC but IE and Safari does not match \\s to these so we need to\n // include them in the reg exps in all places where whitespace is allowed.\n // We allowed \\x7f inside strings because some tools don't escape it,\n // e.g. http://www.json.org/java/org/json/JSONObject.java\n\n // Parsing happens in three stages. In the first stage, we run the text\n // against regular expressions that look for non-JSON patterns. We are\n // especially concerned with '()' and 'new' because they can cause invocation,\n // and '=' because it can cause mutation. But just to be safe, we want to\n // reject all unexpected forms.\n\n // We split the first stage into 4 regexp operations in order to work around\n // crippling inefficiencies in IE's and Safari's regexp engines. First we\n // replace all backslash pairs with '@' (a non-JSON character). Second, we\n // replace all simple value tokens with ']' characters, but only when followed\n // by a colon, comma, closing bracket or end of string. Third, we delete all\n // open brackets that follow a colon or comma or that begin the text. Finally,\n // we look to see that the remaining characters are only whitespace or ']' or\n // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n // Don't make these static since they have the global flag.\n const backslashesRe = /\\\\[\"\\\\\\/bfnrtu]/g;\n const simpleValuesRe =\n /(?:\"[^\"\\\\\\n\\r\\u2028\\u2029\\x00-\\x08\\x0a-\\x1f]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)[\\s\\u2028\\u2029]*(?=:|,|]|}|$)/g;\n const openBracketsRe = /(?:^|:|,)(?:[\\s\\u2028\\u2029]*\\[)+/g;\n const remainderRe = /^[\\],:{}\\s\\u2028\\u2029]*$/;\n\n return remainderRe.test(\n s.replace(backslashesRe, '@')\n .replace(simpleValuesRe, ']')\n .replace(openBracketsRe, ''));\n};\n\n/**\n * Logs a parsing error in `JSON.parse` solvable by using `eval`.\n * @private {function(string, !Error)} The first parameter is the error message,\n * the second is the exception thrown by `JSON.parse`.\n */\ngoog.json.errorLogger_ = () => {};\n\n\n/**\n * Sets an error logger to use if there's a recoverable parsing error.\n * @param {function(string, !Error)} errorLogger The first parameter is the\n * error message, the second is the exception thrown by `JSON.parse`.\n */\ngoog.json.setErrorLogger = function(errorLogger) {\n 'use strict';\n goog.json.errorLogger_ = errorLogger;\n};\n\n\n/**\n * Parses a JSON string and returns the result. This throws an exception if\n * the string is an invalid JSON string.\n *\n * Note that this is very slow on large strings. Use JSON.parse if possible.\n *\n * @param {*} s The JSON string to parse.\n * @throws Error if s is invalid JSON.\n * @return {Object} The object generated from the JSON string, or null.\n * @deprecated Use JSON.parse.\n */\ngoog.json.parse = goog.json.USE_NATIVE_JSON ?\n /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :\n function(s) {\n 'use strict';\n let error;\n try {\n return goog.global['JSON']['parse'](s);\n } catch (ex) {\n error = ex;\n }\n const o = String(s);\n if (goog.json.isValid(o)) {\n\n try {\n const result = /** @type {?Object} */ (eval('(' + o + ')'));\n if (error) {\n goog.json.errorLogger_('Invalid JSON: ' + o, error);\n }\n return result;\n } catch (ex) {\n }\n }\n throw new Error('Invalid JSON string: ' + o);\n };\n\n\n/**\n * JSON replacer, as defined in Section 15.12.3 of the ES5 spec.\n * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3\n *\n * TODO(nicksantos): Array should also be a valid replacer.\n *\n * @typedef {function(this:Object, string, *): *}\n */\ngoog.json.Replacer;\n\n\n/**\n * JSON reviver, as defined in Section 15.12.2 of the ES5 spec.\n * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3\n *\n * @typedef {function(this:Object, string, *): *}\n */\ngoog.json.Reviver;\n\n\n/**\n * Serializes an object or a value to a JSON string.\n *\n * @param {*} object The object to serialize.\n * @param {?goog.json.Replacer=} opt_replacer A replacer function\n * called for each (key, value) pair that determines how the value\n * should be serialized. By defult, this just returns the value\n * and allows default serialization to kick in.\n * @throws Error if there are loops in the object graph.\n * @return {string} A JSON string representation of the input.\n */\ngoog.json.serialize = goog.json.USE_NATIVE_JSON ?\n /** @type {function(*, ?goog.json.Replacer=):string} */\n (goog.global['JSON']['stringify']) :\n function(object, opt_replacer) {\n 'use strict';\n // NOTE(nicksantos): Currently, we never use JSON.stringify.\n //\n // The last time I evaluated this, JSON.stringify had subtle bugs and\n // behavior differences on all browsers, and the performance win was not\n // large enough to justify all the issues. This may change in the future\n // as browser implementations get better.\n //\n // assertSerialize in json_test contains if branches for the cases\n // that fail.\n return new goog.json.Serializer(opt_replacer).serialize(object);\n };\n\n\n\n/**\n * Class that is used to serialize JSON objects to a string.\n * @param {?goog.json.Replacer=} opt_replacer Replacer.\n * @constructor\n */\ngoog.json.Serializer = function(opt_replacer) {\n 'use strict';\n /**\n * @type {goog.json.Replacer|null|undefined}\n * @private\n */\n this.replacer_ = opt_replacer;\n};\n\n\n/**\n * Serializes an object or a value to a JSON string.\n *\n * @param {*} object The object to serialize.\n * @throws Error if there are loops in the object graph.\n * @return {string} A JSON string representation of the input.\n */\ngoog.json.Serializer.prototype.serialize = function(object) {\n 'use strict';\n const sb = [];\n this.serializeInternal(object, sb);\n return sb.join('');\n};\n\n\n/**\n * Serializes a generic value to a JSON string\n * @protected\n * @param {*} object The object to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n * @throws Error if there are loops in the object graph.\n */\ngoog.json.Serializer.prototype.serializeInternal = function(object, sb) {\n 'use strict';\n if (object == null) {\n // undefined == null so this branch covers undefined as well as null\n sb.push('null');\n return;\n }\n\n if (typeof object == 'object') {\n if (Array.isArray(object)) {\n this.serializeArray(object, sb);\n return;\n } else if (\n object instanceof String || object instanceof Number ||\n object instanceof Boolean) {\n object = object.valueOf();\n // Fall through to switch below.\n } else {\n this.serializeObject_(/** @type {!Object} */ (object), sb);\n return;\n }\n }\n\n switch (typeof object) {\n case 'string':\n this.serializeString_(object, sb);\n break;\n case 'number':\n this.serializeNumber_(object, sb);\n break;\n case 'boolean':\n sb.push(String(object));\n break;\n case 'function':\n sb.push('null');\n break;\n default:\n throw new Error('Unknown type: ' + typeof object);\n }\n};\n\n\n/**\n * Character mappings used internally for goog.string.quote\n * @private\n * @type {!Object}\n */\ngoog.json.Serializer.charToJsonCharCache_ = {\n '\\\"': '\\\\\"',\n '\\\\': '\\\\\\\\',\n '/': '\\\\/',\n '\\b': '\\\\b',\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n\n '\\x0B': '\\\\u000b' // '\\v' is not supported in JScript\n};\n\n\n/**\n * Regular expression used to match characters that need to be replaced.\n * The S60 browser has a bug where unicode characters are not matched by\n * regular expressions. The condition below detects such behaviour and\n * adjusts the regular expression accordingly.\n * @private\n * @type {!RegExp}\n */\ngoog.json.Serializer.charsToReplace_ = /\\uffff/.test('\\uffff') ?\n /[\\\\\\\"\\x00-\\x1f\\x7f-\\uffff]/g :\n /[\\\\\\\"\\x00-\\x1f\\x7f-\\xff]/g;\n\n\n/**\n * Serializes a string to a JSON string\n * @private\n * @param {string} s The string to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeString_ = function(s, sb) {\n 'use strict';\n // The official JSON implementation does not work with international\n // characters.\n sb.push('\"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {\n 'use strict';\n // caching the result improves performance by a factor 2-3\n let rv = goog.json.Serializer.charToJsonCharCache_[c];\n if (!rv) {\n rv = '\\\\u' + (c.charCodeAt(0) | 0x10000).toString(16).slice(1);\n goog.json.Serializer.charToJsonCharCache_[c] = rv;\n }\n return rv;\n }), '\"');\n};\n\n\n/**\n * Serializes a number to a JSON string\n * @private\n * @param {number} n The number to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {\n 'use strict';\n sb.push(isFinite(n) && !isNaN(n) ? String(n) : 'null');\n};\n\n\n/**\n * Serializes an array to a JSON string\n * @param {Array<string>} arr The array to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n * @protected\n */\ngoog.json.Serializer.prototype.serializeArray = function(arr, sb) {\n 'use strict';\n const l = arr.length;\n sb.push('[');\n let sep = '';\n for (let i = 0; i < l; i++) {\n sb.push(sep);\n\n const value = arr[i];\n this.serializeInternal(\n this.replacer_ ? this.replacer_.call(arr, String(i), value) : value,\n sb);\n\n sep = ',';\n }\n sb.push(']');\n};\n\n\n/**\n * Serializes an object to a JSON string\n * @private\n * @param {!Object} obj The object to serialize.\n * @param {Array<string>} sb Array used as a string builder.\n */\ngoog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {\n 'use strict';\n sb.push('{');\n let sep = '';\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const value = obj[key];\n // Skip functions.\n if (typeof value != 'function') {\n sb.push(sep);\n this.serializeString_(key, sb);\n sb.push(':');\n\n this.serializeInternal(\n this.replacer_ ? this.replacer_.call(obj, key, value) : value, sb);\n\n sep = ',';\n }\n }\n }\n sb.push('}');\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Simple freelist.\n *\n * An anterative to goog.structs.SimplePool, it imposes the requirement that the\n * objects in the list contain a \"next\" property that can be used to maintain\n * the pool.\n */\ngoog.module('goog.async.FreeList');\ngoog.module.declareLegacyNamespace();\n\n/** @template ITEM */\nclass FreeList {\n /**\n * @param {function():ITEM} create\n * @param {function(ITEM):void} reset\n * @param {number} limit\n */\n constructor(create, reset, limit) {\n /** @private @const {number} */\n this.limit_ = limit;\n /** @private @const {function()} */\n this.create_ = create;\n /** @private @const {function(ITEM):void} */\n this.reset_ = reset;\n\n /** @private {number} */\n this.occupants_ = 0;\n /** @private {ITEM} */\n this.head_ = null;\n }\n\n /** @return {ITEM} */\n get() {\n let item;\n if (this.occupants_ > 0) {\n this.occupants_--;\n item = this.head_;\n this.head_ = item.next;\n item.next = null;\n } else {\n item = this.create_();\n }\n return item;\n }\n\n /** @param {ITEM} item An item available for possible future reuse. */\n put(item) {\n this.reset_(item);\n if (this.occupants_ < this.limit_) {\n this.occupants_++;\n item.next = this.head_;\n this.head_ = item;\n }\n }\n\n /**\n * Visible for testing.\n * @return {number}\n * @package\n */\n occupants() {\n return this.occupants_;\n }\n}\n\nexports = FreeList;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.module('goog.async.WorkQueue');\ngoog.module.declareLegacyNamespace();\n\nconst FreeList = goog.require('goog.async.FreeList');\nconst {assert} = goog.require('goog.asserts');\n\n// TODO(johnlenz): generalize the WorkQueue if this is used by more\n// than goog.async.run.\n\n\n/**\n * A low GC workqueue. The key elements of this design:\n * - avoids the need for goog.bind or equivalent by carrying scope\n * - avoids the need for array reallocation by using a linked list\n * - minimizes work entry objects allocation by recycling objects\n * @final\n * @struct\n */\nclass WorkQueue {\n constructor() {\n this.workHead_ = null;\n this.workTail_ = null;\n }\n\n /**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\n add(fn, scope) {\n const item = this.getUnusedItem_();\n item.set(fn, scope);\n\n if (this.workTail_) {\n this.workTail_.next = item;\n this.workTail_ = item;\n } else {\n assert(!this.workHead_);\n this.workHead_ = item;\n this.workTail_ = item;\n }\n }\n\n /**\n * @return {?WorkItem}\n */\n remove() {\n let item = null;\n\n if (this.workHead_) {\n item = this.workHead_;\n this.workHead_ = this.workHead_.next;\n if (!this.workHead_) {\n this.workTail_ = null;\n }\n item.next = null;\n }\n return item;\n }\n\n /**\n * @param {!WorkItem} item\n */\n returnUnused(item) {\n WorkQueue.freelist_.put(item);\n }\n\n /**\n * @return {!WorkItem}\n * @private\n */\n getUnusedItem_() {\n return WorkQueue.freelist_.get();\n }\n}\n\n/** @define {number} The maximum number of entries to keep for recycling. */\nWorkQueue.DEFAULT_MAX_UNUSED =\n goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);\n\n/** @const @private {!FreeList<!WorkItem>} */\nWorkQueue.freelist_ = new FreeList(\n () => new WorkItem(), item => item.reset(), WorkQueue.DEFAULT_MAX_UNUSED);\n\n/**\n * @final\n * @struct\n */\nclass WorkItem {\n constructor() {\n /** @type {?function()} */\n this.fn = null;\n /** @type {?Object|null|undefined} */\n this.scope = null;\n /** @type {?WorkItem} */\n this.next = null;\n }\n\n /**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\n set(fn, scope) {\n this.fn = fn;\n this.scope = scope;\n this.next = null;\n }\n\n /** Reset the work item so they don't prevent GC before reuse */\n reset() {\n this.fn = null;\n this.scope = null;\n this.next = null;\n }\n}\n\nexports = WorkQueue;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\ngoog.module('goog.async.run');\ngoog.module.declareLegacyNamespace();\n\nconst WorkQueue = goog.require('goog.async.WorkQueue');\nconst asyncStackTag = goog.require('goog.debug.asyncStackTag');\nconst nextTick = goog.require('goog.async.nextTick');\nconst throwException = goog.require('goog.async.throwException');\n\n/**\n * @define {boolean} If true, use the global Promise to implement run\n * assuming either the native, or polyfill version will be used. Does still\n * permit tests to use forceNextTick.\n */\ngoog.ASSUME_NATIVE_PROMISE = goog.define('goog.ASSUME_NATIVE_PROMISE', false);\n\n/**\n * The function used to schedule work asynchronousely.\n * @private {function()}\n */\nlet schedule;\n\n/** @private {boolean} */\nlet workQueueScheduled = false;\n\n/** @type {!WorkQueue} */\nlet workQueue = new WorkQueue();\n\n/**\n * Fires the provided callback just before the current callstack unwinds, or as\n * soon as possible after the current JS execution context.\n * @param {function(this:THIS)} callback\n * @param {THIS=} context Object to use as the \"this value\" when calling the\n * provided function.\n * @template THIS\n */\nlet run = (callback, context = undefined) => {\n if (!schedule) {\n initializeRunner();\n }\n if (!workQueueScheduled) {\n // Nothing is currently scheduled, schedule it now.\n schedule();\n workQueueScheduled = true;\n }\n callback = asyncStackTag.wrap(callback, 'goog.async.run');\n\n workQueue.add(callback, context);\n};\n\n/** Initializes the function to use to process the work queue. */\nlet initializeRunner = () => {\n if (goog.ASSUME_NATIVE_PROMISE ||\n (goog.global.Promise && goog.global.Promise.resolve)) {\n // Use goog.global.Promise instead of just Promise because the relevant\n // externs may be missing, and don't alias it because this could confuse the\n // compiler into thinking the polyfill is required when it should be treated\n // as optional.\n const promise = goog.global.Promise.resolve(undefined);\n schedule = () => {\n promise.then(run.processWorkQueue);\n };\n } else {\n schedule = () => {\n nextTick(run.processWorkQueue);\n };\n }\n};\n\n/**\n * Forces run to use nextTick instead of Promise.\n * This should only be done in unit tests. It's useful because MockClock\n * replaces nextTick, but not the browser Promise implementation, so it allows\n * Promise-based code to be tested with MockClock.\n * However, we also want to run promises if the MockClock is no longer in\n * control so we schedule a backup \"setTimeout\" to the unmocked timeout if\n * provided.\n * @param {function(function())=} realSetTimeout\n */\nrun.forceNextTick = (realSetTimeout = undefined) => {\n schedule = () => {\n nextTick(run.processWorkQueue);\n if (realSetTimeout) {\n realSetTimeout(run.processWorkQueue);\n }\n };\n};\n\nif (goog.DEBUG) {\n /** Reset the work queue. Only available for tests in debug mode. */\n run.resetQueue = () => {\n workQueueScheduled = false;\n workQueue = new WorkQueue();\n };\n\n /** Resets the scheduler. Only available for tests in debug mode. */\n run.resetSchedulerForTest = () => {\n initializeRunner();\n };\n}\n\n/**\n * Run any pending run work items. This function is not intended\n * for general use, but for use by entry point handlers to run items ahead of\n * nextTick.\n */\nrun.processWorkQueue = () => {\n // NOTE: additional work queue items may be added while processing.\n let item = null;\n while (item = workQueue.remove()) {\n try {\n item.fn.call(item.scope);\n } catch (e) {\n throwException(e);\n }\n workQueue.returnUnused(item);\n }\n\n // There are no more work items, allow processing to be scheduled again.\n workQueueScheduled = false;\n};\n\nexports = run;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for string manipulation.\n */\n\n\n/**\n * Namespace for string utilities\n */\ngoog.provide('goog.string');\ngoog.provide('goog.string.Unicode');\n\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.internal');\n\n\n/**\n * @define {boolean} Enables HTML escaping of lowercase letter \"e\" which helps\n * with detection of double-escaping as this letter is frequently used.\n */\ngoog.string.DETECT_DOUBLE_ESCAPING =\n goog.define('goog.string.DETECT_DOUBLE_ESCAPING', false);\n\n\n/**\n * @define {boolean} Whether to force non-dom html unescaping.\n */\ngoog.string.FORCE_NON_DOM_HTML_UNESCAPING =\n goog.define('goog.string.FORCE_NON_DOM_HTML_UNESCAPING', false);\n\n\n/**\n * Common Unicode string characters.\n * @enum {string}\n */\ngoog.string.Unicode = {\n NBSP: '\\xa0',\n ZERO_WIDTH_SPACE: '\\u200b' // This is equivalent to <wbr>.\n};\n\n\n/**\n * Fast prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the start of `str`.\n * @return {boolean} True if `str` begins with `prefix`.\n */\ngoog.string.startsWith = goog.string.internal.startsWith;\n\n\n/**\n * Fast suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix`.\n */\ngoog.string.endsWith = goog.string.internal.endsWith;\n\n\n/**\n * Case-insensitive prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the end of `str`.\n * @return {boolean} True if `str` begins with `prefix` (ignoring\n * case).\n */\ngoog.string.caseInsensitiveStartsWith =\n goog.string.internal.caseInsensitiveStartsWith;\n\n\n/**\n * Case-insensitive suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix` (ignoring\n * case).\n */\ngoog.string.caseInsensitiveEndsWith =\n goog.string.internal.caseInsensitiveEndsWith;\n\n\n/**\n * Case-insensitive equality checker.\n * @param {string} str1 First string to check.\n * @param {string} str2 Second string to check.\n * @return {boolean} True if `str1` and `str2` are the same string,\n * ignoring case.\n */\ngoog.string.caseInsensitiveEquals = goog.string.internal.caseInsensitiveEquals;\n\n\n/**\n * Does simple python-style string substitution.\n * subs(\"foo%s hot%s\", \"bar\", \"dog\") becomes \"foobar hotdog\".\n * @param {string} str The string containing the pattern.\n * @param {...*} var_args The items to substitute into the pattern.\n * @return {string} A copy of `str` in which each occurrence of\n * {@code %s} has been replaced an argument from `var_args`.\n */\ngoog.string.subs = function(str, var_args) {\n 'use strict';\n const splitParts = str.split('%s');\n let returnString = '';\n\n const subsArguments = Array.prototype.slice.call(arguments, 1);\n while (subsArguments.length &&\n // Replace up to the last split part. We are inserting in the\n // positions between split parts.\n splitParts.length > 1) {\n returnString += splitParts.shift() + subsArguments.shift();\n }\n\n return returnString + splitParts.join('%s'); // Join unused '%s'\n};\n\n\n/**\n * Converts multiple whitespace chars (spaces, non-breaking-spaces, new lines\n * and tabs) to a single space, and strips leading and trailing whitespace.\n * @param {string} str Input string.\n * @return {string} A copy of `str` with collapsed whitespace.\n */\ngoog.string.collapseWhitespace = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/[\\s\\xa0]+/g, ' ').replace(/^\\s+|\\s+$/g, '');\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n */\ngoog.string.isEmptyOrWhitespace = goog.string.internal.isEmptyOrWhitespace;\n\n\n/**\n * Checks if a string is empty.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty.\n */\ngoog.string.isEmptyString = function(str) {\n 'use strict';\n return str.length == 0;\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n *\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\n */\ngoog.string.isEmpty = goog.string.isEmptyOrWhitespace;\n\n\n/**\n * Checks if a string is null, undefined, empty or contains only whitespaces.\n * @param {*} str The string to check.\n * @return {boolean} Whether `str` is null, undefined, empty, or\n * whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str))\n * instead.\n */\ngoog.string.isEmptyOrWhitespaceSafe = function(str) {\n 'use strict';\n return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));\n};\n\n\n/**\n * Checks if a string is null, undefined, empty or contains only whitespaces.\n *\n * @param {*} str The string to check.\n * @return {boolean} Whether `str` is null, undefined, empty, or\n * whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\n */\ngoog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;\n\n\n/**\n * Checks if a string is all breaking whitespace.\n * @param {string} str The string to check.\n * @return {boolean} Whether the string is all breaking whitespace.\n */\ngoog.string.isBreakingWhitespace = function(str) {\n 'use strict';\n return !/[^\\t\\n\\r ]/.test(str);\n};\n\n\n/**\n * Checks if a string contains all letters.\n * @param {string} str string to check.\n * @return {boolean} True if `str` consists entirely of letters.\n */\ngoog.string.isAlpha = function(str) {\n 'use strict';\n return !/[^a-zA-Z]/.test(str);\n};\n\n\n/**\n * Checks if a string contains only numbers.\n * @param {*} str string to check. If not a string, it will be\n * casted to one.\n * @return {boolean} True if `str` is numeric.\n */\ngoog.string.isNumeric = function(str) {\n 'use strict';\n return !/[^0-9]/.test(str);\n};\n\n\n/**\n * Checks if a string contains only numbers or letters.\n * @param {string} str string to check.\n * @return {boolean} True if `str` is alphanumeric.\n */\ngoog.string.isAlphaNumeric = function(str) {\n 'use strict';\n return !/[^a-zA-Z0-9]/.test(str);\n};\n\n\n/**\n * Checks if a character is a space character.\n * @param {string} ch Character to check.\n * @return {boolean} True if `ch` is a space.\n */\ngoog.string.isSpace = function(ch) {\n 'use strict';\n return ch == ' ';\n};\n\n\n/**\n * Checks if a character is a valid unicode character.\n * @param {string} ch Character to check.\n * @return {boolean} True if `ch` is a valid unicode character.\n */\ngoog.string.isUnicodeChar = function(ch) {\n 'use strict';\n return ch.length == 1 && ch >= ' ' && ch <= '~' ||\n ch >= '\\u0080' && ch <= '\\uFFFD';\n};\n\n\n/**\n * Takes a string and replaces newlines with a space. Multiple lines are\n * replaced with a single space.\n * @param {string} str The string from which to strip newlines.\n * @return {string} A copy of `str` stripped of newlines.\n */\ngoog.string.stripNewlines = function(str) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)+/g, ' ');\n};\n\n\n/**\n * Replaces Windows and Mac new lines with unix style: \\r or \\r\\n with \\n.\n * @param {string} str The string to in which to canonicalize newlines.\n * @return {string} `str` A copy of {@code} with canonicalized newlines.\n */\ngoog.string.canonicalizeNewlines = function(str) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)/g, '\\n');\n};\n\n\n/**\n * Normalizes whitespace in a string, replacing all whitespace chars with\n * a space.\n * @param {string} str The string in which to normalize whitespace.\n * @return {string} A copy of `str` with all whitespace normalized.\n */\ngoog.string.normalizeWhitespace = function(str) {\n 'use strict';\n return str.replace(/\\xa0|\\s/g, ' ');\n};\n\n\n/**\n * Normalizes spaces in a string, replacing all consecutive spaces and tabs\n * with a single space. Replaces non-breaking space with a space.\n * @param {string} str The string in which to normalize spaces.\n * @return {string} A copy of `str` with all consecutive spaces and tabs\n * replaced with a single space.\n */\ngoog.string.normalizeSpaces = function(str) {\n 'use strict';\n return str.replace(/\\xa0|[ \\t]+/g, ' ');\n};\n\n\n/**\n * Removes the breaking spaces from the left and right of the string and\n * collapses the sequences of breaking spaces in the middle into single spaces.\n * The original and the result strings render the same way in HTML.\n * @param {string} str A string in which to collapse spaces.\n * @return {string} Copy of the string with normalized breaking spaces.\n */\ngoog.string.collapseBreakingSpaces = function(str) {\n 'use strict';\n return str.replace(/[\\t\\r\\n ]+/g, ' ')\n .replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, '');\n};\n\n\n/**\n * Trims white spaces to the left and right of a string.\n * @param {string} str The string to trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trim = goog.string.internal.trim;\n\n\n/**\n * Trims whitespaces at the left end of a string.\n * @param {string} str The string to left trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trimLeft = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/^[\\s\\xa0]+/, '');\n};\n\n\n/**\n * Trims whitespaces at the right end of a string.\n * @param {string} str The string to right trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trimRight = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/[\\s\\xa0]+$/, '');\n};\n\n\n/**\n * A string comparator that ignores case.\n * -1 = str1 less than str2\n * 0 = str1 equals str2\n * 1 = str1 greater than str2\n *\n * @param {string} str1 The string to compare.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} The comparator result, as described above.\n */\ngoog.string.caseInsensitiveCompare =\n goog.string.internal.caseInsensitiveCompare;\n\n\n/**\n * Compares two strings interpreting their numeric substrings as numbers.\n *\n * @param {string} str1 First string.\n * @param {string} str2 Second string.\n * @param {!RegExp} tokenizerRegExp Splits a string into substrings of\n * non-negative integers, non-numeric characters and optionally fractional\n * numbers starting with a decimal point.\n * @return {number} Negative if str1 < str2, 0 is str1 == str2, positive if\n * str1 > str2.\n * @private\n */\ngoog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) {\n 'use strict';\n if (str1 == str2) {\n return 0;\n }\n if (!str1) {\n return -1;\n }\n if (!str2) {\n return 1;\n }\n\n // Using match to split the entire string ahead of time turns out to be faster\n // for most inputs than using RegExp.exec or iterating over each character.\n const tokens1 = str1.toLowerCase().match(tokenizerRegExp);\n const tokens2 = str2.toLowerCase().match(tokenizerRegExp);\n\n const count = Math.min(tokens1.length, tokens2.length);\n\n for (let i = 0; i < count; i++) {\n const a = tokens1[i];\n const b = tokens2[i];\n\n // Compare pairs of tokens, returning if one token sorts before the other.\n if (a != b) {\n // Only if both tokens are integers is a special comparison required.\n // Decimal numbers are sorted as strings (e.g., '.09' < '.1').\n const num1 = parseInt(a, 10);\n if (!isNaN(num1)) {\n const num2 = parseInt(b, 10);\n if (!isNaN(num2) && num1 - num2) {\n return num1 - num2;\n }\n }\n return a < b ? -1 : 1;\n }\n }\n\n // If one string is a substring of the other, the shorter string sorts first.\n if (tokens1.length != tokens2.length) {\n return tokens1.length - tokens2.length;\n }\n\n // The two strings must be equivalent except for case (perfect equality is\n // tested at the head of the function.) Revert to default ASCII string\n // comparison to stabilize the sort.\n return str1 < str2 ? -1 : 1;\n};\n\n\n/**\n * String comparison function that handles non-negative integer numbers in a\n * way humans might expect. Using this function, the string 'File 2.jpg' sorts\n * before 'File 10.jpg', and 'Version 1.9' before 'Version 1.10'. The comparison\n * is mostly case-insensitive, though strings that are identical except for case\n * are sorted with the upper-case strings before lower-case.\n *\n * This comparison function is up to 50x slower than either the default or the\n * case-insensitive compare. It should not be used in time-critical code, but\n * should be fast enough to sort several hundred short strings (like filenames)\n * with a reasonable delay.\n *\n * @param {string} str1 The string to compare in a numerically sensitive way.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\n * 0 if str1 > str2.\n */\ngoog.string.intAwareCompare = function(str1, str2) {\n 'use strict';\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\D+/g);\n};\n\n\n/**\n * String comparison function that handles non-negative integer and fractional\n * numbers in a way humans might expect. Using this function, the string\n * 'File 2.jpg' sorts before 'File 10.jpg', and '3.14' before '3.2'. Equivalent\n * to {@link goog.string.intAwareCompare} apart from the way how it interprets\n * dots.\n *\n * @param {string} str1 The string to compare in a numerically sensitive way.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\n * 0 if str1 > str2.\n */\ngoog.string.floatAwareCompare = function(str1, str2) {\n 'use strict';\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\.\\d+|\\D+/g);\n};\n\n\n/**\n * Alias for {@link goog.string.floatAwareCompare}.\n *\n * @param {string} str1\n * @param {string} str2\n * @return {number}\n */\ngoog.string.numerateCompare = goog.string.floatAwareCompare;\n\n\n/**\n * URL-encodes a string\n * @param {*} str The string to url-encode.\n * @return {string} An encoded copy of `str` that is safe for urls.\n * Note that '#', ':', and other characters used to delimit portions\n * of URLs *will* be encoded.\n */\ngoog.string.urlEncode = function(str) {\n 'use strict';\n return encodeURIComponent(String(str));\n};\n\n\n/**\n * URL-decodes the string. We need to specially handle '+'s because\n * the javascript library doesn't convert them to spaces.\n * @param {string} str The string to url decode.\n * @return {string} The decoded `str`.\n */\ngoog.string.urlDecode = function(str) {\n 'use strict';\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n};\n\n\n/**\n * Converts \\n to <br>s or <br />s.\n * @param {string} str The string in which to convert newlines.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} A copy of `str` with converted newlines.\n */\ngoog.string.newLineToBr = goog.string.internal.newLineToBr;\n\n\n/**\n * Escapes double quote '\"' and single quote '\\'' characters in addition to\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\n * value within double or single quotes.\n *\n * It should be noted that > doesn't need to be escaped for the HTML or XML to\n * be valid, but it has been decided to escape it for consistency with other\n * implementations.\n *\n * With goog.string.DETECT_DOUBLE_ESCAPING, this function escapes also the\n * lowercase letter \"e\".\n *\n * NOTE(user):\n * HtmlEscape is often called during the generation of large blocks of HTML.\n * Using statics for the regular expressions and strings is an optimization\n * that can more than half the amount of time IE spends in this function for\n * large apps, since strings and regexes both contribute to GC allocations.\n *\n * Testing for the presence of a character before escaping increases the number\n * of function calls, but actually provides a speed increase for the average\n * case -- since the average case often doesn't require the escaping of all 4\n * characters and indexOf() is much cheaper than replace().\n * The worst case does suffer slightly from the additional calls, therefore the\n * opt_isLikelyToContainHtmlChars option has been included for situations\n * where all 4 HTML entities are very likely to be present and need escaping.\n *\n * Some benchmarks (times tended to fluctuate +-0.05ms):\n * FireFox IE6\n * (no chars / average (mix of cases) / all 4 chars)\n * no checks 0.13 / 0.22 / 0.22 0.23 / 0.53 / 0.80\n * indexOf 0.08 / 0.17 / 0.26 0.22 / 0.54 / 0.84\n * indexOf + re test 0.07 / 0.17 / 0.28 0.19 / 0.50 / 0.85\n *\n * An additional advantage of checking if replace actually needs to be called\n * is a reduction in the number of object allocations, so as the size of the\n * application grows the difference between the various methods would increase.\n *\n * @param {string} str string to be escaped.\n * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see\n * if the character needs replacing - use this option if you expect each of\n * the characters to appear often. Leave false if you expect few html\n * characters to occur in your strings, such as if you are escaping HTML.\n * @return {string} An escaped copy of `str`.\n */\ngoog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {\n 'use strict';\n str = goog.string.internal.htmlEscape(str, opt_isLikelyToContainHtmlChars);\n if (goog.string.DETECT_DOUBLE_ESCAPING) {\n str = str.replace(goog.string.E_RE_, 'e');\n }\n return str;\n};\n\n\n/**\n * Regular expression that matches a lowercase letter \"e\", for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.E_RE_ = /e/g;\n\n\n/**\n * Unescapes an HTML string.\n *\n * @param {string} str The string to unescape.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapeEntities = function(str) {\n 'use strict';\n if (goog.string.contains(str, '&')) {\n // We are careful not to use a DOM if we do not have one or we explicitly\n // requested non-DOM html unescaping.\n if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING &&\n 'document' in goog.global) {\n return goog.string.unescapeEntitiesUsingDom_(str);\n } else {\n // Fall back on pure XML entities\n return goog.string.unescapePureXmlEntities_(str);\n }\n }\n return str;\n};\n\n\n/**\n * Unescapes a HTML string using the provided document.\n *\n * @param {string} str The string to unescape.\n * @param {!Document} document A document to use in escaping the string.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapeEntitiesWithDocument = function(str, document) {\n 'use strict';\n if (goog.string.contains(str, '&')) {\n return goog.string.unescapeEntitiesUsingDom_(str, document);\n }\n return str;\n};\n\n\n/**\n * Unescapes an HTML string using a DOM to resolve non-XML, non-numeric\n * entities. This function is XSS-safe and whitespace-preserving.\n * @private\n * @param {string} str The string to unescape.\n * @param {Document=} opt_document An optional document to use for creating\n * elements. If this is not specified then the default window.document\n * will be used.\n * @return {string} The unescaped `str` string.\n */\ngoog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {\n 'use strict';\n /** @type {!Object<string, string>} */\n const seen = {'&': '&', '<': '<', '>': '>', '"': '\"'};\n /** @type {!Element} */\n let div;\n if (opt_document) {\n div = opt_document.createElement('div');\n } else {\n div = goog.global.document.createElement('div');\n }\n // Match as many valid entity characters as possible. If the actual entity\n // happens to be shorter, it will still work as innerHTML will return the\n // trailing characters unchanged. Since the entity characters do not include\n // open angle bracket, there is no chance of XSS from the innerHTML use.\n // Since no whitespace is passed to innerHTML, whitespace is preserved.\n return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {\n 'use strict';\n // Check for cached entity.\n let value = seen[s];\n if (value) {\n return value;\n }\n // Check for numeric entity.\n if (entity.charAt(0) == '#') {\n // Prefix with 0 so that hex entities (e.g. ) parse as hex numbers.\n const n = Number('0' + entity.slice(1));\n if (!isNaN(n)) {\n value = String.fromCharCode(n);\n }\n }\n // Fall back to innerHTML otherwise.\n if (!value) {\n // Append a non-entity character to avoid a bug in Webkit that parses\n // an invalid entity at the end of innerHTML text as the empty string.\n goog.dom.safe.setInnerHtml(\n div,\n goog.html.uncheckedconversions\n .safeHtmlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from('Single HTML entity.'), s + ' '));\n // Then remove the trailing character from the result.\n value = div.firstChild.nodeValue.slice(0, -1);\n }\n // Cache and return.\n return seen[s] = value;\n });\n};\n\n\n/**\n * Unescapes XML entities.\n * @private\n * @param {string} str The string to unescape.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapePureXmlEntities_ = function(str) {\n 'use strict';\n return str.replace(/&([^;]+);/g, function(s, entity) {\n 'use strict';\n switch (entity) {\n case 'amp':\n return '&';\n case 'lt':\n return '<';\n case 'gt':\n return '>';\n case 'quot':\n return '\"';\n default:\n if (entity.charAt(0) == '#') {\n // Prefix with 0 so that hex entities (e.g. ) parse as hex.\n const n = Number('0' + entity.slice(1));\n if (!isNaN(n)) {\n return String.fromCharCode(n);\n }\n }\n // For invalid entities we just return the entity\n return s;\n }\n });\n};\n\n\n/**\n * Regular expression that matches an HTML entity.\n * See also HTML5: Tokenization / Tokenizing character references.\n * @private\n * @type {!RegExp}\n */\ngoog.string.HTML_ENTITY_PATTERN_ = /&([^;\\s<&]+);?/g;\n\n\n/**\n * Do escaping of whitespace to preserve spatial formatting. We use character\n * entity #160 to make it safer for xml.\n * @param {string} str The string in which to escape whitespace.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} An escaped copy of `str`.\n */\ngoog.string.whitespaceEscape = function(str, opt_xml) {\n 'use strict';\n // This doesn't use goog.string.preserveSpaces for backwards compatibility.\n return goog.string.newLineToBr(str.replace(/ /g, '  '), opt_xml);\n};\n\n\n/**\n * Preserve spaces that would be otherwise collapsed in HTML by replacing them\n * with non-breaking space Unicode characters.\n * @param {string} str The string in which to preserve whitespace.\n * @return {string} A copy of `str` with preserved whitespace.\n */\ngoog.string.preserveSpaces = function(str) {\n 'use strict';\n return str.replace(/(^|[\\n ]) /g, '$1' + goog.string.Unicode.NBSP);\n};\n\n\n/**\n * Strip quote characters around a string. The second argument is a string of\n * characters to treat as quotes. This can be a single character or a string of\n * multiple character and in that case each of those are treated as possible\n * quote characters. For example:\n *\n * <pre>\n * goog.string.stripQuotes('\"abc\"', '\"`') --> 'abc'\n * goog.string.stripQuotes('`abc`', '\"`') --> 'abc'\n * </pre>\n *\n * @param {string} str The string to strip.\n * @param {string} quoteChars The quote characters to strip.\n * @return {string} A copy of `str` without the quotes.\n */\ngoog.string.stripQuotes = function(str, quoteChars) {\n 'use strict';\n const length = quoteChars.length;\n for (let i = 0; i < length; i++) {\n const quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);\n if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {\n return str.substring(1, str.length - 1);\n }\n }\n return str;\n};\n\n\n/**\n * Truncates a string to a certain length and adds '...' if necessary. The\n * length also accounts for the ellipsis, so a maximum length of 10 and a string\n * 'Hello World!' produces 'Hello W...'.\n * @param {string} str The string to truncate.\n * @param {number} chars Max number of characters.\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\n * characters from being cut off in the middle.\n * @return {string} The truncated `str` string.\n */\ngoog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {\n 'use strict';\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n\n if (str.length > chars) {\n str = str.substring(0, chars - 3) + '...';\n }\n\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n\n return str;\n};\n\n\n/**\n * Truncate a string in the middle, adding \"...\" if necessary,\n * and favoring the beginning of the string.\n * @param {string} str The string to truncate the middle of.\n * @param {number} chars Max number of characters.\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\n * characters from being cutoff in the middle.\n * @param {number=} opt_trailingChars Optional number of trailing characters to\n * leave at the end of the string, instead of truncating as close to the\n * middle as possible.\n * @return {string} A truncated copy of `str`.\n */\ngoog.string.truncateMiddle = function(\n str, chars, opt_protectEscapedCharacters, opt_trailingChars) {\n 'use strict';\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n\n if (opt_trailingChars && str.length > chars) {\n if (opt_trailingChars > chars) {\n opt_trailingChars = chars;\n }\n const endPoint = str.length - opt_trailingChars;\n const startPoint = chars - opt_trailingChars;\n str = str.substring(0, startPoint) + '...' + str.substring(endPoint);\n } else if (str.length > chars) {\n // Favor the beginning of the string:\n let half = Math.floor(chars / 2);\n const endPos = str.length - half;\n half += chars % 2;\n str = str.substring(0, half) + '...' + str.substring(endPos);\n }\n\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n\n return str;\n};\n\n\n/**\n * Special chars that need to be escaped for goog.string.quote.\n * @private {!Object<string, string>}\n */\ngoog.string.specialEscapeChars_ = {\n '\\0': '\\\\0',\n '\\b': '\\\\b',\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n '\\x0B': '\\\\x0B', // '\\v' is not supported in JScript\n '\"': '\\\\\"',\n '\\\\': '\\\\\\\\',\n // To support the use case of embedding quoted strings inside of script\n // tags, we have to make sure HTML comments and opening/closing script tags do\n // not appear in the resulting string. The specific strings that must be\n // escaped are documented at:\n // https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements\n '<': '\\\\u003C' // NOTE: JSON.parse crashes on '\\\\x3c'.\n};\n\n\n/**\n * Character mappings used internally for goog.string.escapeChar.\n * @private {!Object<string, string>}\n */\ngoog.string.jsEscapeCache_ = {\n '\\'': '\\\\\\''\n};\n\n\n/**\n * Encloses a string in double quotes and escapes characters so that the\n * string is a valid JS string. The resulting string is safe to embed in\n * `<script>` tags as \"<\" is escaped.\n * @param {string} s The string to quote.\n * @return {string} A copy of `s` surrounded by double quotes.\n */\ngoog.string.quote = function(s) {\n 'use strict';\n s = String(s);\n const sb = ['\"'];\n for (let i = 0; i < s.length; i++) {\n const ch = s.charAt(i);\n const cc = ch.charCodeAt(0);\n sb[i + 1] = goog.string.specialEscapeChars_[ch] ||\n ((cc > 31 && cc < 127) ? ch : goog.string.escapeChar(ch));\n }\n sb.push('\"');\n return sb.join('');\n};\n\n\n/**\n * Takes a string and returns the escaped string for that input string.\n * @param {string} str The string to escape.\n * @return {string} An escaped string representing `str`.\n */\ngoog.string.escapeString = function(str) {\n 'use strict';\n const sb = [];\n for (let i = 0; i < str.length; i++) {\n sb[i] = goog.string.escapeChar(str.charAt(i));\n }\n return sb.join('');\n};\n\n\n/**\n * Takes a character and returns the escaped string for that character. For\n * example escapeChar(String.fromCharCode(15)) -> \"\\\\x0E\".\n * @param {string} c The character to escape.\n * @return {string} An escaped string representing `c`.\n */\ngoog.string.escapeChar = function(c) {\n 'use strict';\n if (c in goog.string.jsEscapeCache_) {\n return goog.string.jsEscapeCache_[c];\n }\n\n if (c in goog.string.specialEscapeChars_) {\n return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];\n }\n\n let rv = c;\n const cc = c.charCodeAt(0);\n if (cc > 31 && cc < 127) {\n rv = c;\n } else {\n // tab is 9 but handled above\n if (cc < 256) {\n rv = '\\\\x';\n if (cc < 16 || cc > 256) {\n rv += '0';\n }\n } else {\n rv = '\\\\u';\n if (cc < 4096) { // \\u1000\n rv += '0';\n }\n }\n rv += cc.toString(16).toUpperCase();\n }\n\n return goog.string.jsEscapeCache_[c] = rv;\n};\n\n\n/**\n * Determines whether a string contains a substring.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n */\ngoog.string.contains = goog.string.internal.contains;\n\n\n/**\n * Determines whether a string contains a substring, ignoring case.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n */\ngoog.string.caseInsensitiveContains =\n goog.string.internal.caseInsensitiveContains;\n\n\n/**\n * Returns the non-overlapping occurrences of ss in s.\n * If either s or ss evalutes to false, then returns zero.\n * @param {string} s The string to look in.\n * @param {string} ss The string to look for.\n * @return {number} Number of occurrences of ss in s.\n */\ngoog.string.countOf = function(s, ss) {\n 'use strict';\n return s && ss ? s.split(ss).length - 1 : 0;\n};\n\n\n/**\n * Removes a substring of a specified length at a specific\n * index in a string.\n * @param {string} s The base string from which to remove.\n * @param {number} index The index at which to remove the substring.\n * @param {number} stringLength The length of the substring to remove.\n * @return {string} A copy of `s` with the substring removed or the full\n * string if nothing is removed or the input is invalid.\n */\ngoog.string.removeAt = function(s, index, stringLength) {\n 'use strict';\n let resultStr = s;\n // If the index is greater or equal to 0 then remove substring\n if (index >= 0 && index < s.length && stringLength > 0) {\n resultStr = s.slice(0, index) + s.slice(index + stringLength);\n }\n return resultStr;\n};\n\n\n/**\n * Removes the first occurrence of a substring from a string.\n * @param {string} str The base string from which to remove.\n * @param {string} substr The string to remove.\n * @return {string} A copy of `str` with `substr` removed or the\n * full string if nothing is removed.\n */\ngoog.string.remove = function(str, substr) {\n 'use strict';\n return str.replace(substr, '');\n};\n\n\n/**\n * Removes all occurrences of a substring from a string.\n * @param {string} s The base string from which to remove.\n * @param {string} ss The string to remove.\n * @return {string} A copy of `s` with `ss` removed or the full\n * string if nothing is removed.\n */\ngoog.string.removeAll = function(s, ss) {\n 'use strict';\n const re = new RegExp(goog.string.regExpEscape(ss), 'g');\n return s.replace(re, '');\n};\n\n\n/**\n * Replaces all occurrences of a substring of a string with a new substring.\n * @param {string} s The base string from which to remove.\n * @param {string} ss The string to replace.\n * @param {string} replacement The replacement string.\n * @return {string} A copy of `s` with `ss` replaced by\n * `replacement` or the original string if nothing is replaced.\n */\ngoog.string.replaceAll = function(s, ss, replacement) {\n 'use strict';\n const re = new RegExp(goog.string.regExpEscape(ss), 'g');\n return s.replace(re, replacement.replace(/\\$/g, '$$$$'));\n};\n\n\n/**\n * Escapes characters in the string that are not safe to use in a RegExp.\n * @param {*} s The string to escape. If not a string, it will be casted\n * to one.\n * @return {string} A RegExp safe, escaped copy of `s`.\n */\ngoog.string.regExpEscape = function(s) {\n 'use strict';\n return String(s)\n .replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g, '\\\\$1')\n .replace(/\\x08/g, '\\\\x08');\n};\n\n\n/**\n * Repeats a string n times.\n * @param {string} string The string to repeat.\n * @param {number} length The number of times to repeat.\n * @return {string} A string containing `length` repetitions of\n * `string`.\n */\ngoog.string.repeat = (String.prototype.repeat) ? function(string, length) {\n 'use strict';\n // The native method is over 100 times faster than the alternative.\n return string.repeat(length);\n} : function(string, length) {\n 'use strict';\n return new Array(length + 1).join(string);\n};\n\n\n/**\n * Pads number to given length and optionally rounds it to a given precision.\n * For example:\n * <pre>padNumber(1.25, 2, 3) -> '01.250'\n * padNumber(1.25, 2) -> '01.25'\n * padNumber(1.25, 2, 1) -> '01.3'\n * padNumber(1.25, 0) -> '1.25'</pre>\n *\n * @param {number} num The number to pad.\n * @param {number} length The desired length.\n * @param {number=} opt_precision The desired precision.\n * @return {string} `num` as a string with the given options.\n */\ngoog.string.padNumber = function(num, length, opt_precision) {\n 'use strict';\n if (!Number.isFinite(num)) return String(num);\n let s =\n (opt_precision !== undefined) ? num.toFixed(opt_precision) : String(num);\n let index = s.indexOf('.');\n if (index === -1) {\n index = s.length;\n }\n const sign = s[0] === '-' ? '-' : '';\n if (sign) {\n s = s.substring(1);\n }\n return sign + goog.string.repeat('0', Math.max(0, length - index)) + s;\n};\n\n\n/**\n * Returns a string representation of the given object, with\n * null and undefined being returned as the empty string.\n *\n * @param {*} obj The object to convert.\n * @return {string} A string representation of the `obj`.\n */\ngoog.string.makeSafe = function(obj) {\n 'use strict';\n return obj == null ? '' : String(obj);\n};\n\n/**\n * Returns a string with at least 64-bits of randomness.\n *\n * Doesn't trust JavaScript's random function entirely. Uses a combination of\n * random and current timestamp, and then encodes the string in base-36 to\n * make it shorter.\n *\n * @return {string} A random string, e.g. sn1s7vb4gcic.\n */\ngoog.string.getRandomString = function() {\n 'use strict';\n const x = 2147483648;\n return Math.floor(Math.random() * x).toString(36) +\n Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);\n};\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string|number} version1 Version of first item.\n * @param {string|number} version2 Version of second item.\n *\n * @return {number} 1 if `version1` is higher.\n * 0 if arguments are equal.\n * -1 if `version2` is higher.\n */\ngoog.string.compareVersions = goog.string.internal.compareVersions;\n\n\n/**\n * String hash function similar to java.lang.String.hashCode().\n * The hash code for a string is computed as\n * s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],\n * where s[i] is the ith character of the string and n is the length of\n * the string. We mod the result to make it between 0 (inclusive) and 2^32\n * (exclusive).\n * @param {string} str A string.\n * @return {number} Hash value for `str`, between 0 (inclusive) and 2^32\n * (exclusive). The empty string returns 0.\n */\ngoog.string.hashCode = function(str) {\n 'use strict';\n let result = 0;\n for (let i = 0; i < str.length; ++i) {\n // Normalize to 4 byte range, 0 ... 2^32.\n result = (31 * result + str.charCodeAt(i)) >>> 0;\n }\n return result;\n};\n\n\n/**\n * The most recent unique ID. |0 is equivalent to Math.floor in this case.\n * @type {number}\n * @private\n */\ngoog.string.uniqueStringCounter_ = Math.random() * 0x80000000 | 0;\n\n\n/**\n * Generates and returns a string which is unique in the current document.\n * This is useful, for example, to create unique IDs for DOM elements.\n * @return {string} A unique id.\n */\ngoog.string.createUniqueString = function() {\n 'use strict';\n return 'goog_' + goog.string.uniqueStringCounter_++;\n};\n\n\n/**\n * Converts the supplied string to a number, which may be Infinity or NaN.\n * This function strips whitespace: (toNumber(' 123') === 123)\n * This function accepts scientific notation: (toNumber('1e1') === 10)\n *\n * This is better than JavaScript's built-in conversions because, sadly:\n * (Number(' ') === 0) and (parseFloat('123a') === 123)\n *\n * @param {string} str The string to convert.\n * @return {number} The number the supplied string represents, or NaN.\n */\ngoog.string.toNumber = function(str) {\n 'use strict';\n const num = Number(str);\n if (num == 0 && goog.string.isEmptyOrWhitespace(str)) {\n return NaN;\n }\n return num;\n};\n\n\n/**\n * Returns whether the given string is lower camel case (e.g. \"isFooBar\").\n *\n * Note that this assumes the string is entirely letters.\n * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms\n *\n * @param {string} str String to test.\n * @return {boolean} Whether the string is lower camel case.\n */\ngoog.string.isLowerCamelCase = function(str) {\n 'use strict';\n return /^[a-z]+([A-Z][a-z]*)*$/.test(str);\n};\n\n\n/**\n * Returns whether the given string is upper camel case (e.g. \"FooBarBaz\").\n *\n * Note that this assumes the string is entirely letters.\n * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms\n *\n * @param {string} str String to test.\n * @return {boolean} Whether the string is upper camel case.\n */\ngoog.string.isUpperCamelCase = function(str) {\n 'use strict';\n return /^([A-Z][a-z]*)+$/.test(str);\n};\n\n\n/**\n * Converts a string from selector-case to camelCase (e.g. from\n * \"multi-part-string\" to \"multiPartString\"), useful for converting\n * CSS selectors and HTML dataset keys to their equivalent JS properties.\n * @param {string} str The string in selector-case form.\n * @return {string} The string in camelCase form.\n */\ngoog.string.toCamelCase = function(str) {\n 'use strict';\n return String(str).replace(/\\-([a-z])/g, function(all, match) {\n 'use strict';\n return match.toUpperCase();\n });\n};\n\n\n/**\n * Converts a string from camelCase to selector-case (e.g. from\n * \"multiPartString\" to \"multi-part-string\"), useful for converting JS\n * style and dataset properties to equivalent CSS selectors and HTML keys.\n * @param {string} str The string in camelCase form.\n * @return {string} The string in selector-case form.\n */\ngoog.string.toSelectorCase = function(str) {\n 'use strict';\n return String(str).replace(/([A-Z])/g, '-$1').toLowerCase();\n};\n\n\n/**\n * Converts a string into TitleCase. First character of the string is always\n * capitalized in addition to the first letter of every subsequent word.\n * Words are delimited by one or more whitespaces by default. Custom delimiters\n * can optionally be specified to replace the default, which doesn't preserve\n * whitespace delimiters and instead must be explicitly included if needed.\n *\n * Default delimiter => \" \":\n * goog.string.toTitleCase('oneTwoThree') => 'OneTwoThree'\n * goog.string.toTitleCase('one two three') => 'One Two Three'\n * goog.string.toTitleCase(' one two ') => ' One Two '\n * goog.string.toTitleCase('one_two_three') => 'One_two_three'\n * goog.string.toTitleCase('one-two-three') => 'One-two-three'\n *\n * Custom delimiter => \"_-.\":\n * goog.string.toTitleCase('oneTwoThree', '_-.') => 'OneTwoThree'\n * goog.string.toTitleCase('one two three', '_-.') => 'One two three'\n * goog.string.toTitleCase(' one two ', '_-.') => ' one two '\n * goog.string.toTitleCase('one_two_three', '_-.') => 'One_Two_Three'\n * goog.string.toTitleCase('one-two-three', '_-.') => 'One-Two-Three'\n * goog.string.toTitleCase('one...two...three', '_-.') => 'One...Two...Three'\n * goog.string.toTitleCase('one. two. three', '_-.') => 'One. two. three'\n * goog.string.toTitleCase('one-two.three', '_-.') => 'One-Two.Three'\n *\n * @param {string} str String value in camelCase form.\n * @param {string=} opt_delimiters Custom delimiter character set used to\n * distinguish words in the string value. Each character represents a\n * single delimiter. When provided, default whitespace delimiter is\n * overridden and must be explicitly included if needed.\n * @return {string} String value in TitleCase form.\n */\ngoog.string.toTitleCase = function(str, opt_delimiters) {\n 'use strict';\n let delimiters = (typeof opt_delimiters === 'string') ?\n goog.string.regExpEscape(opt_delimiters) :\n '\\\\s';\n\n // For IE8, we need to prevent using an empty character set. Otherwise,\n // incorrect matching will occur.\n delimiters = delimiters ? '|[' + delimiters + ']+' : '';\n\n const regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g');\n return str.replace(regexp, function(all, p1, p2) {\n 'use strict';\n return p1 + p2.toUpperCase();\n });\n};\n\n\n/**\n * Capitalizes a string, i.e. converts the first letter to uppercase\n * and all other letters to lowercase, e.g.:\n *\n * goog.string.capitalize('one') => 'One'\n * goog.string.capitalize('ONE') => 'One'\n * goog.string.capitalize('one two') => 'One two'\n *\n * Note that this function does not trim initial whitespace.\n *\n * @param {string} str String value to capitalize.\n * @return {string} String value with first letter in uppercase.\n */\ngoog.string.capitalize = function(str) {\n 'use strict';\n return String(str.charAt(0)).toUpperCase() +\n String(str.slice(1)).toLowerCase();\n};\n\n\n/**\n * Parse a string in decimal or hexidecimal ('0xFFFF') form.\n *\n * To parse a particular radix, please use parseInt(string, radix) directly. See\n * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt\n *\n * This is a wrapper for the built-in parseInt function that will only parse\n * numbers as base 10 or base 16. Some JS implementations assume strings\n * starting with \"0\" are intended to be octal. ES3 allowed but discouraged\n * this behavior. ES5 forbids it. This function emulates the ES5 behavior.\n *\n * For more information, see Mozilla JS Reference: http://goo.gl/8RiFj\n *\n * @param {string|number|null|undefined} value The value to be parsed.\n * @return {number} The number, parsed. If the string failed to parse, this\n * will be NaN.\n */\ngoog.string.parseInt = function(value) {\n 'use strict';\n // Force finite numbers to strings.\n if (isFinite(value)) {\n value = String(value);\n }\n\n if (typeof value === 'string') {\n // If the string starts with '0x' or '-0x', parse as hex.\n return /^\\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10);\n }\n\n return NaN;\n};\n\n\n/**\n * Splits a string on a separator a limited number of times.\n *\n * This implementation is more similar to Python or Java, where the limit\n * parameter specifies the maximum number of splits rather than truncating\n * the number of results.\n *\n * See http://docs.python.org/2/library/stdtypes.html#str.split\n * See JavaDoc: http://goo.gl/F2AsY\n * See Mozilla reference: http://goo.gl/dZdZs\n *\n * @param {string} str String to split.\n * @param {string} separator The separator.\n * @param {number} limit The limit to the number of splits. The resulting array\n * will have a maximum length of limit+1. Negative numbers are the same\n * as zero.\n * @return {!Array<string>} The string, split.\n */\ngoog.string.splitLimit = function(str, separator, limit) {\n 'use strict';\n const parts = str.split(separator);\n const returnVal = [];\n\n // Only continue doing this while we haven't hit the limit and we have\n // parts left.\n while (limit > 0 && parts.length) {\n returnVal.push(parts.shift());\n limit--;\n }\n\n // If there are remaining parts, append them to the end.\n if (parts.length) {\n returnVal.push(parts.join(separator));\n }\n\n return returnVal;\n};\n\n\n/**\n * Finds the characters to the right of the last instance of any separator\n *\n * This function is similar to goog.string.path.baseName, except it can take a\n * list of characters to split the string on. It will return the rightmost\n * grouping of characters to the right of any separator as a left-to-right\n * oriented string.\n *\n * @see goog.string.path.baseName\n * @param {string} str The string\n * @param {string|!Array<string>} separators A list of separator characters\n * @return {string} The last part of the string with respect to the separators\n */\ngoog.string.lastComponent = function(str, separators) {\n 'use strict';\n if (!separators) {\n return str;\n } else if (typeof separators == 'string') {\n separators = [separators];\n }\n\n let lastSeparatorIndex = -1;\n for (let i = 0; i < separators.length; i++) {\n if (separators[i] == '') {\n continue;\n }\n const currentSeparatorIndex = str.lastIndexOf(separators[i]);\n if (currentSeparatorIndex > lastSeparatorIndex) {\n lastSeparatorIndex = currentSeparatorIndex;\n }\n }\n if (lastSeparatorIndex == -1) {\n return str;\n }\n return str.slice(lastSeparatorIndex + 1);\n};\n\n\n/**\n * Computes the Levenshtein edit distance between two strings.\n * @param {string} a\n * @param {string} b\n * @return {number} The edit distance between the two strings.\n */\ngoog.string.editDistance = function(a, b) {\n 'use strict';\n const v0 = [];\n const v1 = [];\n\n if (a == b) {\n return 0;\n }\n\n if (!a.length || !b.length) {\n return Math.max(a.length, b.length);\n }\n\n for (let i = 0; i < b.length + 1; i++) {\n v0[i] = i;\n }\n\n for (let i = 0; i < a.length; i++) {\n v1[0] = i + 1;\n\n for (let j = 0; j < b.length; j++) {\n const cost = Number(a[i] != b[j]);\n // Cost for the substring is the minimum of adding one character, removing\n // one character, or a swap.\n v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);\n }\n\n for (let j = 0; j < v0.length; j++) {\n v0[j] = v1[j];\n }\n }\n\n return v1[b.length];\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Wrapper class for handling XmlHttpRequests.\n *\n * One off requests can be sent through goog.net.XhrIo.send() or an\n * instance can be created to send multiple requests. Each request uses its\n * own XmlHttpRequest object and handles clearing of the event callback to\n * ensure no leaks.\n *\n * XhrIo is event based, it dispatches events on success, failure, finishing,\n * ready-state change, or progress (download and upload).\n *\n * The ready-state or timeout event fires first, followed by\n * a generic completed event. Then the abort, error, or success event\n * is fired as appropriate. Progress events are fired as they are\n * received. Lastly, the ready event will fire to indicate that the\n * object may be used to make another request.\n *\n * The error event may also be called before completed and\n * ready-state-change if the XmlHttpRequest.open() or .send() methods throw.\n *\n * This class does not support multiple requests, queuing, or prioritization.\n *\n * When progress events are supported by the browser, and progress is\n * enabled via .setProgressEventsEnabled(true), the\n * goog.net.EventType.PROGRESS event will be the re-dispatched browser\n * progress event. Additionally, a DOWNLOAD_PROGRESS or UPLOAD_PROGRESS event\n * will be fired for download and upload progress respectively.\n */\n\n\ngoog.provide('goog.net.XhrIo');\ngoog.provide('goog.net.XhrIo.ResponseType');\n\ngoog.require('goog.Timer');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.collections.maps');\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.json.hybrid');\ngoog.require('goog.log');\ngoog.require('goog.net.ErrorCode');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.HttpStatus');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.uri.utils');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.Uri');\ngoog.requireType('goog.debug.ErrorHandler');\ngoog.requireType('goog.net.XhrLike');\ngoog.requireType('goog.net.XmlHttpFactory');\n\ngoog.scope(function() {\n\n'use strict';\n/**\n * Basic class for handling XMLHttpRequests.\n * @param {goog.net.XmlHttpFactory=} opt_xmlHttpFactory Factory to use when\n * creating XMLHttpRequest objects.\n * @constructor\n * @extends {goog.events.EventTarget}\n */\ngoog.net.XhrIo = function(opt_xmlHttpFactory) {\n 'use strict';\n XhrIo.base(this, 'constructor');\n\n /**\n * Map of default headers to add to every request, use:\n * XhrIo.headers.set(name, value)\n * @type {!Map<string,string>}\n */\n this.headers = new Map();\n\n /**\n * Optional XmlHttpFactory\n * @private {goog.net.XmlHttpFactory}\n */\n this.xmlHttpFactory_ = opt_xmlHttpFactory || null;\n\n /**\n * Whether XMLHttpRequest is active. A request is active from the time send()\n * is called until onReadyStateChange() is complete, or error() or abort()\n * is called.\n * @private {boolean}\n */\n this.active_ = false;\n\n /**\n * The XMLHttpRequest object that is being used for the transfer.\n * @private {?goog.net.XhrLike.OrNative}\n */\n this.xhr_ = null;\n\n /**\n * The options to use with the current XMLHttpRequest object.\n * @private {?Object}\n */\n this.xhrOptions_ = null;\n\n /**\n * Last URL that was requested.\n * @private {string|goog.Uri}\n */\n this.lastUri_ = '';\n\n /**\n * Method for the last request.\n * @private {string}\n */\n this.lastMethod_ = '';\n\n /**\n * Last error code.\n * @private {!goog.net.ErrorCode}\n */\n this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;\n\n /**\n * Last error message.\n * @private {Error|string}\n */\n this.lastError_ = '';\n\n /**\n * Used to ensure that we don't dispatch an multiple ERROR events. This can\n * happen in IE when it does a synchronous load and one error is handled in\n * the ready state change and one is handled due to send() throwing an\n * exception.\n * @private {boolean}\n */\n this.errorDispatched_ = false;\n\n /**\n * Used to make sure we don't fire the complete event from inside a send call.\n * @private {boolean}\n */\n this.inSend_ = false;\n\n /**\n * Used in determining if a call to {@link #onReadyStateChange_} is from\n * within a call to this.xhr_.open.\n * @private {boolean}\n */\n this.inOpen_ = false;\n\n /**\n * Used in determining if a call to {@link #onReadyStateChange_} is from\n * within a call to this.xhr_.abort.\n * @private {boolean}\n */\n this.inAbort_ = false;\n\n /**\n * Number of milliseconds after which an incomplete request will be aborted\n * and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no timeout\n * is set.\n * @private {number}\n */\n this.timeoutInterval_ = 0;\n\n /**\n * Timer to track request timeout.\n * @private {?number}\n */\n this.timeoutId_ = null;\n\n /**\n * The requested type for the response. The empty string means use the default\n * XHR behavior.\n * @private {goog.net.XhrIo.ResponseType}\n */\n this.responseType_ = ResponseType.DEFAULT;\n\n /**\n * Whether a \"credentialed\" request is to be sent (one that is aware of\n * cookies and authentication). This is applicable only for cross-domain\n * requests and more recent browsers that support this part of the HTTP Access\n * Control standard.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-withcredentials-attribute\n *\n * @private {boolean}\n */\n this.withCredentials_ = false;\n\n /**\n * Whether progress events are enabled for this request. This is\n * disabled by default because setting a progress event handler\n * causes pre-flight OPTIONS requests to be sent for CORS requests,\n * even in cases where a pre-flight request would not otherwise be\n * sent.\n *\n * @see http://xhr.spec.whatwg.org/#security-considerations\n *\n * Note that this can cause problems for Firefox 22 and below, as an\n * older \"LSProgressEvent\" will be dispatched by the browser. That\n * progress event is no longer supported, and can lead to failures,\n * including throwing exceptions.\n *\n * @see http://bugzilla.mozilla.org/show_bug.cgi?id=845631\n * @see b/23469793\n *\n * @private {boolean}\n */\n this.progressEventsEnabled_ = false;\n\n /**\n * True if we can use XMLHttpRequest's timeout directly.\n * @private {boolean}\n */\n this.useXhr2Timeout_ = false;\n\n /**\n * Specification for Trust Token operations (issuance, signing, and\n * redemption).\n * @private {?TrustTokenAttributeType}\n */\n this.trustToken_ = null;\n};\ngoog.inherits(goog.net.XhrIo, goog.events.EventTarget);\n\nconst XhrIo = goog.net.XhrIo;\n\n/**\n * Response types that may be requested for XMLHttpRequests.\n * @enum {string}\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute\n */\ngoog.net.XhrIo.ResponseType = {\n DEFAULT: '',\n TEXT: 'text',\n DOCUMENT: 'document',\n // Not supported as of Chrome 10.0.612.1 dev\n BLOB: 'blob',\n ARRAY_BUFFER: 'arraybuffer',\n};\n\nconst ResponseType = goog.net.XhrIo.ResponseType;\n\n\n/**\n * A reference to the XhrIo logger\n * @private {?goog.log.Logger}\n * @const\n */\ngoog.net.XhrIo.prototype.logger_ = goog.log.getLogger('goog.net.XhrIo');\n\n\n/**\n * The Content-Type HTTP header name\n * @type {string}\n */\ngoog.net.XhrIo.CONTENT_TYPE_HEADER = 'Content-Type';\n\n\n/**\n * The Content-Transfer-Encoding HTTP header name\n * @type {string}\n */\ngoog.net.XhrIo.CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding';\n\n\n/**\n * The pattern matching the 'http' and 'https' URI schemes\n * @type {!RegExp}\n */\ngoog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i;\n\nconst HTTP_SCHEME_PATTERN = goog.net.XhrIo.HTTP_SCHEME_PATTERN;\n\n\n/**\n * The methods that typically come along with form data. We set different\n * headers depending on whether the HTTP action is one of these.\n * @type {!Array<string>}\n */\ngoog.net.XhrIo.METHODS_WITH_FORM_DATA = ['POST', 'PUT'];\n\n\n/**\n * The Content-Type HTTP header value for a url-encoded form\n * @type {string}\n */\ngoog.net.XhrIo.FORM_CONTENT_TYPE =\n 'application/x-www-form-urlencoded;charset=utf-8';\n\n\n/**\n * The XMLHttpRequest Level two timeout delay ms property name.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n *\n * @private {string}\n * @const\n */\ngoog.net.XhrIo.XHR2_TIMEOUT_ = 'timeout';\n\n\n/**\n * The XMLHttpRequest Level two ontimeout handler property name.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n *\n * @private {string}\n * @const\n */\ngoog.net.XhrIo.XHR2_ON_TIMEOUT_ = 'ontimeout';\n\n\n/**\n * All non-disposed instances of goog.net.XhrIo created\n * by {@link goog.net.XhrIo.send} are in this Array.\n * @see goog.net.XhrIo.cleanup\n * @private {!Array<!goog.net.XhrIo>}\n */\ngoog.net.XhrIo.sendInstances_ = [];\n\n\n/**\n * Static send that creates a short lived instance of XhrIo to send the\n * request.\n * @see goog.net.XhrIo.cleanup\n * @param {string|goog.Uri} url Uri to make request to.\n * @param {?function(this:goog.net.XhrIo, ?)=} opt_callback Callback function\n * for when request is complete.\n * @param {string=} opt_method Send method, default: GET.\n * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=}\n * opt_content Body data.\n * @param {(?Object|?goog.collections.maps.MapLike<string, string>)=}\n * opt_headers Map of headers to add to the request.\n * @param {number=} opt_timeoutInterval Number of milliseconds after which an\n * incomplete request will be aborted; 0 means no timeout is set.\n * @param {boolean=} opt_withCredentials Whether to send credentials with the\n * request. Default to false. See {@link goog.net.XhrIo#setWithCredentials}.\n * @return {!goog.net.XhrIo} The sent XhrIo.\n */\ngoog.net.XhrIo.send = function(\n url, opt_callback, opt_method, opt_content, opt_headers,\n opt_timeoutInterval, opt_withCredentials) {\n 'use strict';\n const x = new goog.net.XhrIo();\n goog.net.XhrIo.sendInstances_.push(x);\n if (opt_callback) {\n x.listen(goog.net.EventType.COMPLETE, opt_callback);\n }\n x.listenOnce(goog.net.EventType.READY, x.cleanupSend_);\n if (opt_timeoutInterval) {\n x.setTimeoutInterval(opt_timeoutInterval);\n }\n if (opt_withCredentials) {\n x.setWithCredentials(opt_withCredentials);\n }\n x.send(url, opt_method, opt_content, opt_headers);\n return x;\n};\n\n\n/**\n * Disposes all non-disposed instances of goog.net.XhrIo created by\n * {@link goog.net.XhrIo.send}.\n * {@link goog.net.XhrIo.send} cleans up the goog.net.XhrIo instance\n * it creates when the request completes or fails. However, if\n * the request never completes, then the goog.net.XhrIo is not disposed.\n * This can occur if the window is unloaded before the request completes.\n * We could have {@link goog.net.XhrIo.send} return the goog.net.XhrIo\n * it creates and make the client of {@link goog.net.XhrIo.send} be\n * responsible for disposing it in this case. However, this makes things\n * significantly more complicated for the client, and the whole point\n * of {@link goog.net.XhrIo.send} is that it's simple and easy to use.\n * Clients of {@link goog.net.XhrIo.send} should call\n * {@link goog.net.XhrIo.cleanup} when doing final\n * cleanup on window unload.\n */\ngoog.net.XhrIo.cleanup = function() {\n 'use strict';\n const instances = goog.net.XhrIo.sendInstances_;\n while (instances.length) {\n instances.pop().dispose();\n }\n};\n\n\n/**\n * Installs exception protection for all entry point introduced by\n * goog.net.XhrIo instances which are not protected by\n * {@link goog.debug.ErrorHandler#protectWindowSetTimeout},\n * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or\n * {@link goog.events.protectBrowserEventEntryPoint}.\n *\n * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to\n * protect the entry point(s).\n */\ngoog.net.XhrIo.protectEntryPoints = function(errorHandler) {\n 'use strict';\n goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =\n errorHandler.protectEntryPoint(\n goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);\n};\n\n\n/**\n * Disposes of the specified goog.net.XhrIo created by\n * {@link goog.net.XhrIo.send} and removes it from\n * {@link goog.net.XhrIo.pendingStaticSendInstances_}.\n * @private\n */\ngoog.net.XhrIo.prototype.cleanupSend_ = function() {\n 'use strict';\n this.dispose();\n goog.array.remove(goog.net.XhrIo.sendInstances_, this);\n};\n\n\n/**\n * Returns the number of milliseconds after which an incomplete request will be\n * aborted, or 0 if no timeout is set.\n * @return {number} Timeout interval in milliseconds.\n */\ngoog.net.XhrIo.prototype.getTimeoutInterval = function() {\n 'use strict';\n return this.timeoutInterval_;\n};\n\n\n/**\n * Sets the number of milliseconds after which an incomplete request will be\n * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no\n * timeout is set.\n * @param {number} ms Timeout interval in milliseconds; 0 means none.\n */\ngoog.net.XhrIo.prototype.setTimeoutInterval = function(ms) {\n 'use strict';\n this.timeoutInterval_ = Math.max(0, ms);\n};\n\n\n/**\n * Sets the desired type for the response. At time of writing, this is only\n * supported in very recent versions of WebKit (10.0.612.1 dev and later).\n *\n * If this is used, the response may only be accessed via {@link #getResponse}.\n *\n * @param {goog.net.XhrIo.ResponseType} type The desired type for the response.\n */\ngoog.net.XhrIo.prototype.setResponseType = function(type) {\n 'use strict';\n this.responseType_ = type;\n};\n\n\n/**\n * Gets the desired type for the response.\n * @return {goog.net.XhrIo.ResponseType} The desired type for the response.\n */\ngoog.net.XhrIo.prototype.getResponseType = function() {\n 'use strict';\n return this.responseType_;\n};\n\n\n/**\n * Sets whether a \"credentialed\" request that is aware of cookie and\n * authentication information should be made. This option is only supported by\n * browsers that support HTTP Access Control. As of this writing, this option\n * is not supported in IE.\n *\n * @param {boolean} withCredentials Whether this should be a \"credentialed\"\n * request.\n */\ngoog.net.XhrIo.prototype.setWithCredentials = function(withCredentials) {\n 'use strict';\n this.withCredentials_ = withCredentials;\n};\n\n\n/**\n * Gets whether a \"credentialed\" request is to be sent.\n * @return {boolean} The desired type for the response.\n */\ngoog.net.XhrIo.prototype.getWithCredentials = function() {\n 'use strict';\n return this.withCredentials_;\n};\n\n\n/**\n * Sets whether progress events are enabled for this request. Note\n * that progress events require pre-flight OPTIONS request handling\n * for CORS requests, and may cause trouble with older browsers. See\n * progressEventsEnabled_ for details.\n * @param {boolean} enabled Whether progress events should be enabled.\n */\ngoog.net.XhrIo.prototype.setProgressEventsEnabled = function(enabled) {\n 'use strict';\n this.progressEventsEnabled_ = enabled;\n};\n\n\n/**\n * Gets whether progress events are enabled.\n * @return {boolean} Whether progress events are enabled for this request.\n */\ngoog.net.XhrIo.prototype.getProgressEventsEnabled = function() {\n 'use strict';\n return this.progressEventsEnabled_;\n};\n\n/**\n * Specify a Trust Tokens operation to execute alongside the request.\n * @param {!TrustTokenAttributeType} trustToken a Trust Tokens operation to\n * execute.\n */\ngoog.net.XhrIo.prototype.setTrustToken = function(trustToken) {\n 'use strict';\n this.trustToken_ = trustToken;\n};\n/**\n * Instance send that actually uses XMLHttpRequest to make a server call.\n * @param {string|goog.Uri} url Uri to make request to.\n * @param {string=} opt_method Send method, default: GET.\n * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=}\n * opt_content Body data.\n * @param {(?Object|?goog.collections.maps.MapLike<string, string>)=}\n * opt_headers Map of headers to add to the request.\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters for opt_headers.\n */\ngoog.net.XhrIo.prototype.send = function(\n url, opt_method, opt_content, opt_headers) {\n 'use strict';\n if (this.xhr_) {\n throw new Error(\n '[goog.net.XhrIo] Object is active with another request=' +\n this.lastUri_ + '; newUri=' + url);\n }\n\n const method = opt_method ? opt_method.toUpperCase() : 'GET';\n\n this.lastUri_ = url;\n this.lastError_ = '';\n this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;\n this.lastMethod_ = method;\n this.errorDispatched_ = false;\n this.active_ = true;\n\n // Use the factory to create the XHR object and options\n this.xhr_ = this.createXhr();\n this.xhrOptions_ = this.xmlHttpFactory_ ? this.xmlHttpFactory_.getOptions() :\n goog.net.XmlHttp.getOptions();\n\n // Set up the onreadystatechange callback\n this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this);\n\n // Set up upload/download progress events, if progress events are supported.\n if (this.getProgressEventsEnabled() && 'onprogress' in this.xhr_) {\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n this.xhr_.onprogress = goog.bind(function(e) {\n 'use strict';\n this.onProgressHandler_(e, true);\n }, this);\n if (this.xhr_.upload) {\n /**\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\n this.xhr_.upload.onprogress = goog.bind(this.onProgressHandler_, this);\n }\n }\n\n /**\n * Try to open the XMLHttpRequest (always async), if an error occurs here it\n * is generally permission denied\n */\n try {\n goog.log.fine(this.logger_, this.formatMsg_('Opening Xhr'));\n this.inOpen_ = true;\n this.xhr_.open(method, String(url), true); // Always async!\n this.inOpen_ = false;\n } catch (err) {\n goog.log.fine(\n this.logger_, this.formatMsg_('Error opening Xhr: ' + err.message));\n this.error_(goog.net.ErrorCode.EXCEPTION, err);\n return;\n }\n\n // We can't use null since this won't allow requests with form data to have a\n // content length specified which will cause some proxies to return a 411\n // error.\n const content = opt_content || '';\n\n const headers = new Map(this.headers);\n\n // Add headers specific to this request\n if (opt_headers) {\n if (Object.getPrototypeOf(opt_headers) === Object.prototype) {\n for (let key in opt_headers) {\n headers.set(key, opt_headers[key]);\n }\n } else if (\n typeof opt_headers.keys === 'function' &&\n typeof opt_headers.get === 'function') {\n for (const key of opt_headers.keys()) {\n headers.set(key, opt_headers.get(key));\n }\n } else {\n throw new Error(\n 'Unknown input type for opt_headers: ' + String(opt_headers));\n }\n }\n\n // Find whether a content type header is set, ignoring case.\n // HTTP header names are case-insensitive. See:\n // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2\n const contentTypeKey =\n Array.from(headers.keys())\n .find(\n header => goog.string.caseInsensitiveEquals(\n goog.net.XhrIo.CONTENT_TYPE_HEADER, header));\n\n const contentIsFormData =\n (goog.global['FormData'] && (content instanceof goog.global['FormData']));\n if (goog.array.contains(goog.net.XhrIo.METHODS_WITH_FORM_DATA, method) &&\n !contentTypeKey && !contentIsFormData) {\n // For requests typically with form data, default to the url-encoded form\n // content type unless this is a FormData request. For FormData,\n // the browser will automatically add a multipart/form-data content type\n // with an appropriate multipart boundary.\n headers.set(\n goog.net.XhrIo.CONTENT_TYPE_HEADER, goog.net.XhrIo.FORM_CONTENT_TYPE);\n }\n\n // Add the headers to the Xhr object\n for (const [key, value] of headers) {\n this.xhr_.setRequestHeader(key, value);\n }\n\n if (this.responseType_) {\n this.xhr_.responseType = this.responseType_;\n }\n // Set xhr_.withCredentials only when the value is different, or else in\n // synchronous XMLHtppRequest.open Firefox will throw an exception.\n // https://bugzilla.mozilla.org/show_bug.cgi?id=736340\n if ('withCredentials' in this.xhr_ &&\n this.xhr_.withCredentials !== this.withCredentials_) {\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n this.xhr_.withCredentials = this.withCredentials_;\n }\n\n if ('setTrustToken' in this.xhr_ && this.trustToken_) {\n try {\n this.xhr_.setTrustToken(this.trustToken_);\n } catch (err) {\n goog.log.fine(\n this.logger_, this.formatMsg_('Error SetTrustToken: ' + err.message));\n }\n }\n /**\n * Try to send the request, or other wise report an error (404 not found).\n */\n try {\n this.cleanUpTimeoutTimer_(); // Paranoid, should never be running.\n if (this.timeoutInterval_ > 0) {\n this.useXhr2Timeout_ = goog.net.XhrIo.shouldUseXhr2Timeout_(this.xhr_);\n goog.log.fine(\n this.logger_,\n this.formatMsg_(\n 'Will abort after ' + this.timeoutInterval_ +\n 'ms if incomplete, xhr2 ' + this.useXhr2Timeout_));\n if (this.useXhr2Timeout_) {\n this.xhr_[goog.net.XhrIo.XHR2_TIMEOUT_] = this.timeoutInterval_;\n this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] =\n goog.bind(this.timeout_, this);\n } else {\n this.timeoutId_ =\n goog.Timer.callOnce(this.timeout_, this.timeoutInterval_, this);\n }\n }\n goog.log.fine(this.logger_, this.formatMsg_('Sending request'));\n this.inSend_ = true;\n this.xhr_.send(content);\n this.inSend_ = false;\n\n } catch (err) {\n goog.log.fine(this.logger_, this.formatMsg_('Send error: ' + err.message));\n this.error_(goog.net.ErrorCode.EXCEPTION, err);\n }\n};\n\n\n/**\n * Determines if the argument is an XMLHttpRequest that supports the level 2\n * timeout value and event.\n *\n * Currently, FF 21.0 OS X has the fields but won't actually call the timeout\n * handler. Perhaps the confusion in the bug referenced below hasn't\n * entirely been resolved.\n *\n * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute\n * @see https://bugzilla.mozilla.org/show_bug.cgi?id=525816\n *\n * @param {!goog.net.XhrLike.OrNative} xhr The request.\n * @return {boolean} True if the request supports level 2 timeout.\n * @private\n */\ngoog.net.XhrIo.shouldUseXhr2Timeout_ = function(xhr) {\n 'use strict';\n return goog.userAgent.IE &&\n typeof xhr[goog.net.XhrIo.XHR2_TIMEOUT_] === 'number' &&\n xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_] !== undefined;\n};\n\n\n/**\n * Creates a new XHR object.\n * @return {!goog.net.XhrLike.OrNative} The newly created XHR object.\n * @protected\n */\ngoog.net.XhrIo.prototype.createXhr = function() {\n 'use strict';\n return this.xmlHttpFactory_ ? this.xmlHttpFactory_.createInstance() :\n goog.net.XmlHttp();\n};\n\n\n/**\n * The request didn't complete after {@link goog.net.XhrIo#timeoutInterval_}\n * milliseconds; raises a {@link goog.net.EventType.TIMEOUT} event and aborts\n * the request.\n * @private\n */\ngoog.net.XhrIo.prototype.timeout_ = function() {\n 'use strict';\n if (typeof goog == 'undefined') {\n // If goog is undefined then the callback has occurred as the application\n // is unloading and will error. Thus we let it silently fail.\n } else if (this.xhr_) {\n this.lastError_ =\n 'Timed out after ' + this.timeoutInterval_ + 'ms, aborting';\n this.lastErrorCode_ = goog.net.ErrorCode.TIMEOUT;\n goog.log.fine(this.logger_, this.formatMsg_(this.lastError_));\n this.dispatchEvent(goog.net.EventType.TIMEOUT);\n this.abort(goog.net.ErrorCode.TIMEOUT);\n }\n};\n\n\n/**\n * Something errorred, so inactivate, fire error callback and clean up\n * @param {goog.net.ErrorCode} errorCode The error code.\n * @param {Error} err The error object.\n * @private\n */\ngoog.net.XhrIo.prototype.error_ = function(errorCode, err) {\n 'use strict';\n this.active_ = false;\n if (this.xhr_) {\n this.inAbort_ = true;\n this.xhr_.abort(); // Ensures XHR isn't hung (FF)\n this.inAbort_ = false;\n }\n this.lastError_ = err;\n this.lastErrorCode_ = errorCode;\n this.dispatchErrors_();\n this.cleanUpXhr_();\n};\n\n\n/**\n * Dispatches COMPLETE and ERROR in case of an error. This ensures that we do\n * not dispatch multiple error events.\n * @private\n */\ngoog.net.XhrIo.prototype.dispatchErrors_ = function() {\n 'use strict';\n if (!this.errorDispatched_) {\n this.errorDispatched_ = true;\n this.dispatchEvent(goog.net.EventType.COMPLETE);\n this.dispatchEvent(goog.net.EventType.ERROR);\n }\n};\n\n\n/**\n * Abort the current XMLHttpRequest\n * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use -\n * defaults to ABORT.\n */\ngoog.net.XhrIo.prototype.abort = function(opt_failureCode) {\n 'use strict';\n if (this.xhr_ && this.active_) {\n goog.log.fine(this.logger_, this.formatMsg_('Aborting'));\n this.active_ = false;\n this.inAbort_ = true;\n this.xhr_.abort();\n this.inAbort_ = false;\n this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT;\n this.dispatchEvent(goog.net.EventType.COMPLETE);\n this.dispatchEvent(goog.net.EventType.ABORT);\n this.cleanUpXhr_();\n }\n};\n\n\n/**\n * Nullifies all callbacks to reduce risks of leaks.\n * @override\n * @protected\n */\ngoog.net.XhrIo.prototype.disposeInternal = function() {\n 'use strict';\n if (this.xhr_) {\n // We explicitly do not call xhr_.abort() unless active_ is still true.\n // This is to avoid unnecessarily aborting a successful request when\n // dispose() is called in a callback triggered by a complete response, but\n // in which browser cleanup has not yet finished.\n // (See http://b/issue?id=1684217.)\n if (this.active_) {\n this.active_ = false;\n this.inAbort_ = true;\n this.xhr_.abort();\n this.inAbort_ = false;\n }\n this.cleanUpXhr_(true);\n }\n\n XhrIo.base(this, 'disposeInternal');\n};\n\n\n/**\n * Internal handler for the XHR object's readystatechange event. This method\n * checks the status and the readystate and fires the correct callbacks.\n * If the request has ended, the handlers are cleaned up and the XHR object is\n * nullified.\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChange_ = function() {\n 'use strict';\n if (this.isDisposed()) {\n // This method is the target of an untracked goog.Timer.callOnce().\n return;\n }\n if (!this.inOpen_ && !this.inSend_ && !this.inAbort_) {\n // Were not being called from within a call to this.xhr_.send\n // this.xhr_.abort, or this.xhr_.open, so this is an entry point\n this.onReadyStateChangeEntryPoint_();\n } else {\n this.onReadyStateChangeHelper_();\n }\n};\n\n\n/**\n * Used to protect the onreadystatechange handler entry point. Necessary\n * as {#onReadyStateChange_} maybe called from within send or abort, this\n * method is only called when {#onReadyStateChange_} is called as an\n * entry point.\n * {@see #protectEntryPoints}\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() {\n 'use strict';\n this.onReadyStateChangeHelper_();\n};\n\n\n/**\n * Helper for {@link #onReadyStateChange_}. This is used so that\n * entry point calls to {@link #onReadyStateChange_} can be routed through\n * {@link #onReadyStateChangeEntryPoint_}.\n * @private\n */\ngoog.net.XhrIo.prototype.onReadyStateChangeHelper_ = function() {\n 'use strict';\n if (!this.active_) {\n // can get called inside abort call\n return;\n }\n\n if (typeof goog == 'undefined') {\n // NOTE(user): If goog is undefined then the callback has occurred as the\n // application is unloading and will error. Thus we let it silently fail.\n\n } else if (\n this.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] &&\n this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE &&\n this.getStatus() == 2) {\n // NOTE(user): In IE if send() errors on a *local* request the readystate\n // is still changed to COMPLETE. We need to ignore it and allow the\n // try/catch around send() to pick up the error.\n goog.log.fine(\n this.logger_,\n this.formatMsg_('Local request error detected and ignored'));\n\n } else {\n // In IE when the response has been cached we sometimes get the callback\n // from inside the send call and this usually breaks code that assumes that\n // XhrIo is asynchronous. If that is the case we delay the callback\n // using a timer.\n if (this.inSend_ &&\n this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE) {\n goog.Timer.callOnce(this.onReadyStateChange_, 0, this);\n return;\n }\n\n this.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE);\n\n // readyState indicates the transfer has finished\n if (this.isComplete()) {\n goog.log.fine(this.logger_, this.formatMsg_('Request complete'));\n\n this.active_ = false;\n\n try {\n // Call the specific callbacks for success or failure. Only call the\n // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED)\n if (this.isSuccess()) {\n this.dispatchEvent(goog.net.EventType.COMPLETE);\n this.dispatchEvent(goog.net.EventType.SUCCESS);\n } else {\n this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;\n this.lastError_ =\n this.getStatusText() + ' [' + this.getStatus() + ']';\n this.dispatchErrors_();\n }\n } finally {\n this.cleanUpXhr_();\n }\n }\n }\n};\n\n\n/**\n * Internal handler for the XHR object's onprogress event. Fires both a generic\n * PROGRESS event and either a DOWNLOAD_PROGRESS or UPLOAD_PROGRESS event to\n * allow specific binding for each XHR progress event.\n * @param {!ProgressEvent} e XHR progress event.\n * @param {boolean=} opt_isDownload Whether the current progress event is from a\n * download. Used to determine whether DOWNLOAD_PROGRESS or UPLOAD_PROGRESS\n * event should be dispatched.\n * @private\n */\ngoog.net.XhrIo.prototype.onProgressHandler_ = function(e, opt_isDownload) {\n 'use strict';\n goog.asserts.assert(\n e.type === goog.net.EventType.PROGRESS,\n 'goog.net.EventType.PROGRESS is of the same type as raw XHR progress.');\n this.dispatchEvent(\n goog.net.XhrIo.buildProgressEvent_(e, goog.net.EventType.PROGRESS));\n this.dispatchEvent(goog.net.XhrIo.buildProgressEvent_(\n e,\n opt_isDownload ? goog.net.EventType.DOWNLOAD_PROGRESS :\n goog.net.EventType.UPLOAD_PROGRESS));\n};\n\n\n/**\n * Creates a representation of the native ProgressEvent. IE doesn't support\n * constructing ProgressEvent via \"new\", and the alternatives (e.g.,\n * ProgressEvent.initProgressEvent) are non-standard or deprecated.\n * @param {!ProgressEvent} e XHR progress event.\n * @param {!goog.net.EventType} eventType The type of the event.\n * @return {!ProgressEvent} The progress event.\n * @private\n */\ngoog.net.XhrIo.buildProgressEvent_ = function(e, eventType) {\n 'use strict';\n return /** @type {!ProgressEvent} */ ({\n type: eventType,\n lengthComputable: e.lengthComputable,\n loaded: e.loaded,\n total: e.total,\n });\n};\n\n\n/**\n * Remove the listener to protect against leaks, and nullify the XMLHttpRequest\n * object.\n * @param {boolean=} opt_fromDispose If this is from the dispose (don't want to\n * fire any events).\n * @private\n */\ngoog.net.XhrIo.prototype.cleanUpXhr_ = function(opt_fromDispose) {\n 'use strict';\n if (this.xhr_) {\n // Cancel any pending timeout event handler.\n this.cleanUpTimeoutTimer_();\n\n // Save reference so we can mark it as closed after the READY event. The\n // READY event may trigger another request, thus we must nullify this.xhr_\n const xhr = this.xhr_;\n const clearedOnReadyStateChange =\n this.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ?\n () => {} :\n null;\n this.xhr_ = null;\n this.xhrOptions_ = null;\n\n if (!opt_fromDispose) {\n this.dispatchEvent(goog.net.EventType.READY);\n }\n\n try {\n // NOTE(user): Not nullifying in FireFox can still leak if the callbacks\n // are defined in the same scope as the instance of XhrIo. But, IE doesn't\n // allow you to set the onreadystatechange to NULL so nullFunction is\n // used.\n xhr.onreadystatechange = clearedOnReadyStateChange;\n } catch (e) {\n // This seems to occur with a Gears HTTP request. Delayed the setting of\n // this onreadystatechange until after READY is sent out and catching the\n // error to see if we can track down the problem.\n goog.log.error(\n this.logger_,\n 'Problem encountered resetting onreadystatechange: ' + e.message);\n }\n }\n};\n\n\n/**\n * Make sure the timeout timer isn't running.\n * @private\n */\ngoog.net.XhrIo.prototype.cleanUpTimeoutTimer_ = function() {\n 'use strict';\n if (this.xhr_ && this.useXhr2Timeout_) {\n this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = null;\n }\n if (this.timeoutId_) {\n goog.Timer.clear(this.timeoutId_);\n this.timeoutId_ = null;\n }\n};\n\n\n/**\n * @return {boolean} Whether there is an active request.\n */\ngoog.net.XhrIo.prototype.isActive = function() {\n 'use strict';\n return !!this.xhr_;\n};\n\n\n/**\n * @return {boolean} Whether the request has completed.\n */\ngoog.net.XhrIo.prototype.isComplete = function() {\n 'use strict';\n return this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE;\n};\n\n\n/**\n * @return {boolean} Whether the request completed with a success.\n */\ngoog.net.XhrIo.prototype.isSuccess = function() {\n 'use strict';\n const status = this.getStatus();\n // A zero status code is considered successful for local files.\n return goog.net.HttpStatus.isSuccess(status) ||\n status === 0 && !this.isLastUriEffectiveSchemeHttp_();\n};\n\n\n/**\n * @return {boolean} whether the effective scheme of the last URI that was\n * fetched was 'http' or 'https'.\n * @private\n */\ngoog.net.XhrIo.prototype.isLastUriEffectiveSchemeHttp_ = function() {\n 'use strict';\n const scheme = goog.uri.utils.getEffectiveScheme(String(this.lastUri_));\n return HTTP_SCHEME_PATTERN.test(scheme);\n};\n\n\n/**\n * Get the readystate from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {goog.net.XmlHttp.ReadyState} goog.net.XmlHttp.ReadyState.*.\n */\ngoog.net.XhrIo.prototype.getReadyState = function() {\n 'use strict';\n return this.xhr_ ?\n /** @type {goog.net.XmlHttp.ReadyState} */ (this.xhr_.readyState) :\n goog.net.XmlHttp.ReadyState.UNINITIALIZED;\n};\n\n\n/**\n * Get the status from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {number} Http status.\n */\ngoog.net.XhrIo.prototype.getStatus = function() {\n 'use strict';\n /**\n * IE doesn't like you checking status until the readystate is greater than 2\n * (i.e. it is receiving or complete). The try/catch is used for when the\n * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.\n */\n try {\n return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?\n this.xhr_.status :\n -1;\n } catch (e) {\n return -1;\n }\n};\n\n\n/**\n * Get the status text from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @return {string} Status text.\n */\ngoog.net.XhrIo.prototype.getStatusText = function() {\n 'use strict';\n /**\n * IE doesn't like you checking status until the readystate is greater than 2\n * (i.e. it is receiving or complete). The try/catch is used for when the\n * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.\n */\n try {\n return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?\n this.xhr_.statusText :\n '';\n } catch (e) {\n goog.log.fine(this.logger_, 'Can not get status: ' + e.message);\n return '';\n }\n};\n\n\n/**\n * Get the last Uri that was requested\n * @return {string} Last Uri.\n */\ngoog.net.XhrIo.prototype.getLastUri = function() {\n 'use strict';\n return String(this.lastUri_);\n};\n\n\n/**\n * Get the response text from the Xhr object\n * Will only return correct result when called from the context of a callback.\n * @return {string} Result from the server, or '' if no result available.\n */\ngoog.net.XhrIo.prototype.getResponseText = function() {\n 'use strict';\n try {\n return this.xhr_ ? this.xhr_.responseText : '';\n } catch (e) {\n // http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute\n // states that responseText should return '' (and responseXML null)\n // when the state is not LOADING or DONE. Instead, IE can\n // throw unexpected exceptions, for example when a request is aborted\n // or no data is available yet.\n goog.log.fine(this.logger_, 'Can not get responseText: ' + e.message);\n return '';\n }\n};\n\n\n/**\n * Get the response body from the Xhr object. This property is only available\n * in IE since version 7 according to MSDN:\n * http://msdn.microsoft.com/en-us/library/ie/ms534368(v=vs.85).aspx\n * Will only return correct result when called from the context of a callback.\n *\n * One option is to construct a VBArray from the returned object and convert\n * it to a JavaScript array using the toArray method:\n * `(new window['VBArray'](xhrIo.getResponseBody())).toArray()`\n * This will result in an array of numbers in the range of [0..255]\n *\n * Another option is to use the VBScript CStr method to convert it into a\n * string as outlined in http://stackoverflow.com/questions/1919972\n *\n * @return {Object} Binary result from the server or null if not available.\n */\ngoog.net.XhrIo.prototype.getResponseBody = function() {\n 'use strict';\n try {\n if (this.xhr_ && 'responseBody' in this.xhr_) {\n return this.xhr_['responseBody'];\n }\n } catch (e) {\n // IE can throw unexpected exceptions, for example when a request is aborted\n // or no data is yet available.\n goog.log.fine(this.logger_, 'Can not get responseBody: ' + e.message);\n }\n return null;\n};\n\n\n/**\n * Get the response XML from the Xhr object\n * Will only return correct result when called from the context of a callback.\n * @return {Document} The DOM Document representing the XML file, or null\n * if no result available.\n */\ngoog.net.XhrIo.prototype.getResponseXml = function() {\n 'use strict';\n try {\n return this.xhr_ ? this.xhr_.responseXML : null;\n } catch (e) {\n goog.log.fine(this.logger_, 'Can not get responseXML: ' + e.message);\n return null;\n }\n};\n\n\n/**\n * Get the response and evaluates it as JSON from the Xhr object\n * Will only return correct result when called from the context of a callback\n * @param {string=} opt_xssiPrefix Optional XSSI prefix string to use for\n * stripping of the response before parsing. This needs to be set only if\n * your backend server prepends the same prefix string to the JSON response.\n * @throws Error if the response text is invalid JSON.\n * @return {Object|undefined} JavaScript object.\n */\ngoog.net.XhrIo.prototype.getResponseJson = function(opt_xssiPrefix) {\n 'use strict';\n if (!this.xhr_) {\n return undefined;\n }\n\n let responseText = this.xhr_.responseText;\n if (opt_xssiPrefix && responseText.indexOf(opt_xssiPrefix) == 0) {\n responseText = responseText.substring(opt_xssiPrefix.length);\n }\n\n return goog.json.hybrid.parse(responseText);\n};\n\n\n/**\n * Get the response as the type specificed by {@link #setResponseType}. At time\n * of writing, this is only directly supported in very recent versions of WebKit\n * (10.0.612.1 dev and later). If the field is not supported directly, we will\n * try to emulate it.\n *\n * Emulating the response means following the rules laid out at\n * http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute\n *\n * On browsers with no support for this (Chrome < 10, Firefox < 4, etc), only\n * response types of DEFAULT or TEXT may be used, and the response returned will\n * be the text response.\n *\n * On browsers with Mozilla's draft support for array buffers (Firefox 4, 5),\n * only response types of DEFAULT, TEXT, and ARRAY_BUFFER may be used, and the\n * response returned will be either the text response or the Mozilla\n * implementation of the array buffer response.\n *\n * On browsers will full support, any valid response type supported by the\n * browser may be used, and the response provided by the browser will be\n * returned.\n *\n * @return {*} The response.\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.net.XhrIo.prototype.getResponse = function() {\n 'use strict';\n try {\n if (!this.xhr_) {\n return null;\n }\n if ('response' in this.xhr_) {\n return this.xhr_.response;\n }\n switch (this.responseType_) {\n case ResponseType.DEFAULT:\n case ResponseType.TEXT:\n return this.xhr_.responseText;\n // DOCUMENT and BLOB don't need to be handled here because they are\n // introduced in the same spec that adds the .response field, and would\n // have been caught above.\n // ARRAY_BUFFER needs an implementation for Firefox 4, where it was\n // implemented using a draft spec rather than the final spec.\n case ResponseType.ARRAY_BUFFER:\n if ('mozResponseArrayBuffer' in this.xhr_) {\n return this.xhr_.mozResponseArrayBuffer;\n }\n }\n // Fell through to a response type that is not supported on this browser.\n goog.log.error(\n this.logger_,\n 'Response type ' + this.responseType_ + ' is not ' +\n 'supported on this browser');\n return null;\n } catch (e) {\n goog.log.fine(this.logger_, 'Can not get response: ' + e.message);\n return null;\n }\n};\n\n\n/**\n * Get the value of the response-header with the given name from the Xhr object\n * Will only return correct result when called from the context of a callback\n * and the request has completed\n * @param {string} key The name of the response-header to retrieve.\n * @return {string|undefined} The value of the response-header named key.\n */\ngoog.net.XhrIo.prototype.getResponseHeader = function(key) {\n 'use strict';\n if (!this.xhr_ || !this.isComplete()) {\n return undefined;\n }\n\n const value = this.xhr_.getResponseHeader(key);\n return value === null ? undefined : value;\n};\n\n\n/**\n * Gets the text of all the headers in the response.\n * Will only return correct result after ready state reaches `LOADED` (i.e.\n * `HEADERS_RECEIVED` as per MDN).\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllResponseHeaders = function() {\n 'use strict';\n // getAllResponseHeaders can return null if no response has been received,\n // ensure we always return an empty string.\n return this.xhr_ &&\n this.getReadyState() >= goog.net.XmlHttp.ReadyState.LOADED ?\n (this.xhr_.getAllResponseHeaders() || '') :\n '';\n};\n\n\n/**\n * Returns all response headers as a key-value map.\n * Multiple values for the same header key can be combined into one,\n * separated by a comma and a space.\n * Note that the native getResponseHeader method for retrieving a single header\n * does a case insensitive match on the header name. This method does not\n * include any case normalization logic, it will just return a key-value\n * representation of the headers.\n * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method\n * @return {!Object<string, string>} An object with the header keys as keys\n * and header values as values.\n */\ngoog.net.XhrIo.prototype.getResponseHeaders = function() {\n 'use strict';\n // TODO(user): Make this function parse headers as per the spec\n // (https://tools.ietf.org/html/rfc2616#section-4.2).\n\n const headersObject = {};\n const headersArray = this.getAllResponseHeaders().split('\\r\\n');\n for (let i = 0; i < headersArray.length; i++) {\n if (goog.string.isEmptyOrWhitespace(headersArray[i])) {\n continue;\n }\n const keyValue =\n goog.string.splitLimit(headersArray[i], ':', /* maxSplitCount= */ 1);\n const key = keyValue[0];\n let value = keyValue[1];\n\n if (typeof value !== 'string') {\n // There must be a value but it can be the empty string.\n continue;\n }\n\n // Whitespace at the start and end of the value is meaningless.\n value = value.trim();\n // The key should not contain whitespace but we currently ignore that.\n\n const values = headersObject[key] || [];\n headersObject[key] = values;\n values.push(value);\n }\n\n return goog.object.map(headersObject, function(values) {\n 'use strict';\n return values.join(', ');\n });\n};\n\n\n/**\n * Get the value of the response-header with the given name from the Xhr object.\n * As opposed to {@link #getResponseHeader}, this method does not require that\n * the request has completed.\n * @param {string} key The name of the response-header to retrieve.\n * @return {?string} The value of the response-header, or null if it is\n * unavailable.\n */\ngoog.net.XhrIo.prototype.getStreamingResponseHeader = function(key) {\n 'use strict';\n return this.xhr_ ? this.xhr_.getResponseHeader(key) : null;\n};\n\n\n/**\n * Gets the text of all the headers in the response. As opposed to\n * {@link #getAllResponseHeaders}, this method does not require that the request\n * has completed.\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllStreamingResponseHeaders = function() {\n 'use strict';\n return this.xhr_ ? this.xhr_.getAllResponseHeaders() : '';\n};\n\n\n/**\n * Get the last error message\n * @return {!goog.net.ErrorCode} Last error code.\n */\ngoog.net.XhrIo.prototype.getLastErrorCode = function() {\n 'use strict';\n return this.lastErrorCode_;\n};\n\n\n/**\n * Get the last error message\n * @return {string} Last error message.\n */\ngoog.net.XhrIo.prototype.getLastError = function() {\n 'use strict';\n return typeof this.lastError_ === 'string' ? this.lastError_ :\n String(this.lastError_);\n};\n\n\n/**\n * Adds the last method, status and URI to the message. This is used to add\n * this information to the logging calls.\n * @param {string} msg The message text that we want to add the extra text to.\n * @return {string} The message with the extra text appended.\n * @private\n */\ngoog.net.XhrIo.prototype.formatMsg_ = function(msg) {\n 'use strict';\n return msg + ' [' + this.lastMethod_ + ' ' + this.lastUri_ + ' ' +\n this.getStatus() + ']';\n};\n\n\n// Register the xhr handler as an entry point, so that\n// it can be monitored for exception handling, etc.\ngoog.debug.entryPointRegistry.register(\n /**\n * @param {function(!Function): !Function} transformer The transforming\n * function.\n */\n function(transformer) {\n 'use strict';\n goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =\n transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);\n });\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a function to throw an error without interrupting\n * the current execution context.\n */\n\ngoog.module('goog.async.throwException');\ngoog.module.declareLegacyNamespace();\n\n/**\n * Throw an item without interrupting the current execution context. For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\nfunction throwException(exception) {\n // Each throw needs to be in its own context.\n goog.global.setTimeout(() => {\n throw exception;\n }, 0);\n}\nexports = throwException;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A timer class to which other classes and objects can listen on.\n * This is only an abstraction above `setInterval`.\n *\n * @see ../demos/timers.html\n */\n\ngoog.provide('goog.Timer');\n\ngoog.require('goog.Promise');\ngoog.require('goog.events.EventTarget');\ngoog.requireType('goog.Thenable');\n\n\n\n/**\n * Class for handling timing events.\n *\n * @param {number=} opt_interval Number of ms between ticks (default: 1ms).\n * @param {Object=} opt_timerObject An object that has `setTimeout`,\n * `setInterval`, `clearTimeout` and `clearInterval`\n * (e.g., `window`).\n * @constructor\n * @extends {goog.events.EventTarget}\n */\ngoog.Timer = function(opt_interval, opt_timerObject) {\n 'use strict';\n goog.events.EventTarget.call(this);\n\n /**\n * Number of ms between ticks\n * @private {number}\n */\n this.interval_ = opt_interval || 1;\n\n /**\n * An object that implements `setTimeout`, `setInterval`,\n * `clearTimeout` and `clearInterval`. We default to the window\n * object. Changing this on {@link goog.Timer.prototype} changes the object\n * for all timer instances which can be useful if your environment has some\n * other implementation of timers than the `window` object.\n * @private {{setTimeout:!Function, clearTimeout:!Function}}\n */\n this.timerObject_ = /** @type {{setTimeout, clearTimeout}} */ (\n opt_timerObject || goog.Timer.defaultTimerObject);\n\n /**\n * Cached `tick_` bound to the object for later use in the timer.\n * @private {Function}\n * @const\n */\n this.boundTick_ = goog.bind(this.tick_, this);\n\n /**\n * Firefox browser often fires the timer event sooner (sometimes MUCH sooner)\n * than the requested timeout. So we compare the time to when the event was\n * last fired, and reschedule if appropriate. See also\n * {@link goog.Timer.intervalScale}.\n * @private {number}\n */\n this.last_ = goog.now();\n};\ngoog.inherits(goog.Timer, goog.events.EventTarget);\n\n\n/**\n * Maximum timeout value.\n *\n * Timeout values too big to fit into a signed 32-bit integer may cause overflow\n * in FF, Safari, and Chrome, resulting in the timeout being scheduled\n * immediately. It makes more sense simply not to schedule these timeouts, since\n * 24.8 days is beyond a reasonable expectation for the browser to stay open.\n *\n * @private {number}\n * @const\n */\ngoog.Timer.MAX_TIMEOUT_ = 2147483647;\n\n\n/**\n * A timer ID that cannot be returned by any known implementation of\n * `window.setTimeout`. Passing this value to `window.clearTimeout`\n * should therefore be a no-op.\n *\n * @private {number}\n * @const\n */\ngoog.Timer.INVALID_TIMEOUT_ID_ = -1;\n\n\n/**\n * Whether this timer is enabled\n * @type {boolean}\n */\ngoog.Timer.prototype.enabled = false;\n\n\n/**\n * An object that implements `setTimeout`, `setInterval`,\n * `clearTimeout` and `clearInterval`. We default to the global\n * object. Changing `goog.Timer.defaultTimerObject` changes the object for\n * all timer instances which can be useful if your environment has some other\n * implementation of timers you'd like to use.\n * @type {{setTimeout, clearTimeout}}\n */\ngoog.Timer.defaultTimerObject = goog.global;\n\n\n/**\n * Variable that controls the timer error correction. If the timer is called\n * before the requested interval times `intervalScale`, which often\n * happens on Mozilla, the timer is rescheduled.\n * @see {@link #last_}\n * @type {number}\n */\ngoog.Timer.intervalScale = 0.8;\n\n\n/**\n * Variable for storing the result of `setInterval`.\n * @private {?number}\n */\ngoog.Timer.prototype.timer_ = null;\n\n\n/**\n * Gets the interval of the timer.\n * @return {number} interval Number of ms between ticks.\n */\ngoog.Timer.prototype.getInterval = function() {\n 'use strict';\n return this.interval_;\n};\n\n\n/**\n * Sets the interval of the timer.\n * @param {number} interval Number of ms between ticks.\n */\ngoog.Timer.prototype.setInterval = function(interval) {\n 'use strict';\n this.interval_ = interval;\n if (this.timer_ && this.enabled) {\n // Stop and then start the timer to reset the interval.\n this.stop();\n this.start();\n } else if (this.timer_) {\n this.stop();\n }\n};\n\n\n/**\n * Callback for the `setTimeout` used by the timer.\n * @private\n */\ngoog.Timer.prototype.tick_ = function() {\n 'use strict';\n if (this.enabled) {\n var elapsed = goog.now() - this.last_;\n if (elapsed > 0 && elapsed < this.interval_ * goog.Timer.intervalScale) {\n this.timer_ = this.timerObject_.setTimeout(\n this.boundTick_, this.interval_ - elapsed);\n return;\n }\n\n // Prevents setInterval from registering a duplicate timeout when called\n // in the timer event handler.\n if (this.timer_) {\n this.timerObject_.clearTimeout(this.timer_);\n this.timer_ = null;\n }\n\n this.dispatchTick();\n // The timer could be stopped in the timer event handler.\n if (this.enabled) {\n // Stop and start to ensure there is always only one timeout even if\n // start is called in the timer event handler.\n this.stop();\n this.start();\n }\n }\n};\n\n\n/**\n * Dispatches the TICK event. This is its own method so subclasses can override.\n */\ngoog.Timer.prototype.dispatchTick = function() {\n 'use strict';\n this.dispatchEvent(goog.Timer.TICK);\n};\n\n\n/**\n * Starts the timer.\n */\ngoog.Timer.prototype.start = function() {\n 'use strict';\n this.enabled = true;\n\n // If there is no interval already registered, start it now\n if (!this.timer_) {\n // IMPORTANT!\n // window.setInterval in FireFox has a bug - it fires based on\n // absolute time, rather than on relative time. What this means\n // is that if a computer is sleeping/hibernating for 24 hours\n // and the timer interval was configured to fire every 1000ms,\n // then after the PC wakes up the timer will fire, in rapid\n // succession, 3600*24 times.\n // This bug is described here and is already fixed, but it will\n // take time to propagate, so for now I am switching this over\n // to setTimeout logic.\n // https://bugzilla.mozilla.org/show_bug.cgi?id=376643\n //\n this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_);\n this.last_ = goog.now();\n }\n};\n\n\n/**\n * Stops the timer.\n */\ngoog.Timer.prototype.stop = function() {\n 'use strict';\n this.enabled = false;\n if (this.timer_) {\n this.timerObject_.clearTimeout(this.timer_);\n this.timer_ = null;\n }\n};\n\n\n/** @override */\ngoog.Timer.prototype.disposeInternal = function() {\n 'use strict';\n goog.Timer.superClass_.disposeInternal.call(this);\n this.stop();\n delete this.timerObject_;\n};\n\n\n/**\n * Constant for the timer's event type.\n * @const\n */\ngoog.Timer.TICK = 'tick';\n\n\n/**\n * Calls the given function once, after the optional pause.\n * <p>\n * The function is always called asynchronously, even if the delay is 0. This\n * is a common trick to schedule a function to run after a batch of browser\n * event processing.\n *\n * @param {function(this:SCOPE)|{handleEvent:function()}|null} listener Function\n * or object that has a handleEvent method.\n * @param {number=} opt_delay Milliseconds to wait; default is 0.\n * @param {SCOPE=} opt_handler Object in whose scope to call the listener.\n * @return {number} A handle to the timer ID.\n * @template SCOPE\n */\ngoog.Timer.callOnce = function(listener, opt_delay, opt_handler) {\n 'use strict';\n if (typeof listener === 'function') {\n if (opt_handler) {\n listener = goog.bind(listener, opt_handler);\n }\n } else if (listener && typeof listener.handleEvent == 'function') {\n // using typeof to prevent strict js warning\n listener = goog.bind(listener.handleEvent, listener);\n } else {\n throw new Error('Invalid listener argument');\n }\n\n if (Number(opt_delay) > goog.Timer.MAX_TIMEOUT_) {\n // Timeouts greater than MAX_INT return immediately due to integer\n // overflow in many browsers. Since MAX_INT is 24.8 days, just don't\n // schedule anything at all.\n return goog.Timer.INVALID_TIMEOUT_ID_;\n } else {\n return goog.Timer.defaultTimerObject.setTimeout(listener, opt_delay || 0);\n }\n};\n\n\n/**\n * Clears a timeout initiated by {@link #callOnce}.\n * @param {?number} timerId A timer ID.\n */\ngoog.Timer.clear = function(timerId) {\n 'use strict';\n goog.Timer.defaultTimerObject.clearTimeout(timerId);\n};\n\n\n/**\n * @param {number} delay Milliseconds to wait.\n * @param {(RESULT|goog.Thenable<RESULT>|Thenable)=} opt_result The value\n * with which the promise will be resolved.\n * @return {!goog.Promise<RESULT>} A promise that will be resolved after\n * the specified delay, unless it is canceled first.\n * @template RESULT\n */\ngoog.Timer.promise = function(delay, opt_result) {\n 'use strict';\n var timerKey = null;\n return new goog\n .Promise(function(resolve, reject) {\n 'use strict';\n timerKey = goog.Timer.callOnce(function() {\n 'use strict';\n resolve(opt_result);\n }, delay);\n if (timerKey == goog.Timer.INVALID_TIMEOUT_ID_) {\n reject(new Error('Failed to schedule timer.'));\n }\n })\n .thenCatch(function(error) {\n 'use strict';\n // Clear the timer. The most likely reason is \"cancel\" signal.\n goog.Timer.clear(timerKey);\n throw error;\n });\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the goog.async.Throttle class.\n *\n * @see ../demos/timers.html\n */\n\ngoog.module('goog.async.Throttle');\ngoog.module.declareLegacyNamespace();\n\nconst Disposable = goog.require('goog.Disposable');\nconst Timer = goog.require('goog.Timer');\n\n\n/**\n * Throttle will perform an action that is passed in no more than once\n * per interval (specified in milliseconds). If it gets multiple signals\n * to perform the action while it is waiting, it will only perform the action\n * once at the end of the interval.\n * @final\n * @template T\n */\nclass Throttle extends Disposable {\n /**\n * @param {function(this: T, ...?)} listener Function to callback when the\n * action is triggered.\n * @param {number} interval Interval over which to throttle. The listener can\n * only be called once per interval.\n * @param {T=} handler Object in whose scope to call the listener.\n */\n constructor(listener, interval, handler) {\n super();\n /**\n * Function to callback\n * @type {function(this: T, ...?)}\n * @private\n */\n this.listener_ = handler != null ? listener.bind(handler) : listener;\n\n /**\n * Interval for the throttle time\n * @type {number}\n * @private\n */\n this.interval_ = interval;\n\n /**\n * The last arguments passed into `fire`, or null if there is no pending\n * call.\n * @private {?IArrayLike}\n */\n this.args_ = null;\n\n /**\n * Indicates that the action is pending and needs to be fired.\n * @type {boolean}\n * @private\n */\n this.shouldFire_ = false;\n\n /**\n * Indicates the count of nested pauses currently in effect on the throttle.\n * When this count is not zero, fired actions will be postponed until the\n * throttle is resumed enough times to drop the pause count to zero.\n * @type {number}\n * @private\n */\n this.pauseCount_ = 0;\n\n /**\n * Timer for scheduling the next callback\n * @type {?number}\n * @private\n */\n this.timer_ = null;\n }\n\n /**\n * Notifies the throttle that the action has happened. It will throttle\n * the call so that the callback is not called too often according to the\n * interval parameter passed to the constructor, passing the arguments\n * from the last call of this function into the throttled function.\n * @param {...?} var_args Arguments to pass on to the throttled function.\n */\n fire(var_args) {\n this.args_ = arguments;\n if (!this.timer_ && !this.pauseCount_) {\n this.doAction_();\n } else {\n this.shouldFire_ = true;\n }\n }\n\n /**\n * Cancels any pending action callback. The throttle can be restarted by\n * calling {@link #fire}.\n */\n stop() {\n if (this.timer_) {\n Timer.clear(this.timer_);\n this.timer_ = null;\n this.shouldFire_ = false;\n this.args_ = null;\n }\n }\n\n /**\n * Pauses the throttle. All pending and future action callbacks will be\n * delayed until the throttle is resumed. Pauses can be nested.\n */\n pause() {\n this.pauseCount_++;\n }\n\n /**\n * Resumes the throttle. If doing so drops the pausing count to zero,\n * pending action callbacks will be executed as soon as possible, but\n * still no sooner than an interval's delay after the previous call.\n * Future action callbacks will be executed as normal.\n */\n resume() {\n this.pauseCount_--;\n if (!this.pauseCount_ && this.shouldFire_ && !this.timer_) {\n this.shouldFire_ = false;\n this.doAction_();\n }\n }\n\n /** @override */\n disposeInternal() {\n super.disposeInternal();\n this.stop();\n }\n\n /**\n * Handler for the timer to fire the throttle\n * @private\n */\n onTimer_() {\n this.timer_ = null;\n\n if (this.shouldFire_ && !this.pauseCount_) {\n this.shouldFire_ = false;\n this.doAction_();\n }\n }\n\n /**\n * Calls the callback\n * @private\n */\n doAction_() {\n this.timer_ = Timer.callOnce(() => this.onTimer_(), this.interval_);\n const args = this.args_;\n // release memory first so it always happens even if listener throws\n this.args_ = null;\n this.listener_.apply(null, args);\n }\n}\n\nexports = Throttle;\n",null,"/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Class to create objects which want to handle multiple events\n * and have their listeners easily cleaned up via a dispose method.\n *\n * Example:\n * <pre>\n * function Something() {\n * Something.base(this);\n *\n * ... set up object ...\n *\n * // Add event listeners\n * this.listen(this.starEl, goog.events.EventType.CLICK, this.handleStar);\n * this.listen(this.headerEl, goog.events.EventType.CLICK, this.expand);\n * this.listen(this.collapseEl, goog.events.EventType.CLICK, this.collapse);\n * this.listen(this.infoEl, goog.events.EventType.MOUSEOVER, this.showHover);\n * this.listen(this.infoEl, goog.events.EventType.MOUSEOUT, this.hideHover);\n * }\n * goog.inherits(Something, goog.events.EventHandler);\n *\n * Something.prototype.disposeInternal = function() {\n * Something.base(this, 'disposeInternal');\n * goog.dom.removeNode(this.container);\n * };\n *\n *\n * // Then elsewhere:\n *\n * var activeSomething = null;\n * function openSomething() {\n * activeSomething = new Something();\n * }\n *\n * function closeSomething() {\n * if (activeSomething) {\n * activeSomething.dispose(); // Remove event listeners\n * activeSomething = null;\n * }\n * }\n * </pre>\n */\n\ngoog.provide('goog.events.EventHandler');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.events');\ngoog.require('goog.object');\ngoog.requireType('goog.events.Event');\ngoog.requireType('goog.events.EventId');\ngoog.requireType('goog.events.EventTarget');\ngoog.requireType('goog.events.EventWrapper');\n\n\n\n/**\n * Super class for objects that want to easily manage a number of event\n * listeners. It allows a short cut to listen and also provides a quick way\n * to remove all events listeners belonging to this object.\n * @param {SCOPE=} opt_scope Object in whose scope to call the listeners.\n * @constructor\n * @extends {goog.Disposable}\n * @template SCOPE\n */\ngoog.events.EventHandler = function(opt_scope) {\n 'use strict';\n goog.Disposable.call(this);\n // TODO(mknichel): Rename this to this.scope_ and fix the classes in google3\n // that access this private variable. :(\n this.handler_ = opt_scope;\n\n /**\n * Keys for events that are being listened to.\n * @type {!Object<!goog.events.Key>}\n * @private\n */\n this.keys_ = {};\n};\ngoog.inherits(goog.events.EventHandler, goog.Disposable);\n\n\n/**\n * Utility array used to unify the cases of listening for an array of types\n * and listening for a single event, without using recursion or allocating\n * an array each time.\n * @type {!Array<string>}\n * @const\n * @private\n */\ngoog.events.EventHandler.typeArray_ = [];\n\n\n/**\n * Listen to an event on a Listenable. If the function is omitted then the\n * EventHandler's handleEvent method will be used.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type to listen for or array of event types.\n * @param {function(this:SCOPE, EVENTOBJ):?|{handleEvent:function(?):?}|null=}\n * opt_fn Optional callback function to be used as the listener or an object\n * with handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listen = function(\n src, type, opt_fn, opt_options) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n return self.listen_(src, type, opt_fn, opt_options);\n};\n\n\n/**\n * Listen to an event on a Listenable. If the function is omitted then the\n * EventHandler's handleEvent method will be used.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type to listen for or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(this:T, ?):?}|\n * null|undefined} fn Optional callback function to be used as the\n * listener or an object with handleEvent function.\n * @param {boolean|!AddEventListenerOptions|undefined} options\n * @param {T} scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template T, EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listenWithScope = function(\n src, type, fn, options, scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n // TODO(mknichel): Deprecate this function.\n return self.listen_(src, type, fn, options, scope);\n};\n\n\n/**\n * Listen to an event on a Listenable. If the function is omitted then the\n * EventHandler's handleEvent method will be used.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type to listen for or array of event types.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn\n * Optional callback function to be used as the listener or an object with\n * handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n * @private\n */\ngoog.events.EventHandler.prototype.listen_ = function(\n src, type, opt_fn, opt_options, opt_scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n if (!Array.isArray(type)) {\n if (type) {\n goog.events.EventHandler.typeArray_[0] = type.toString();\n }\n type = goog.events.EventHandler.typeArray_;\n }\n for (var i = 0; i < type.length; i++) {\n var listenerObj = goog.events.listen(\n src, type[i], opt_fn || self.handleEvent, opt_options || false,\n opt_scope || self.handler_ || self);\n\n if (!listenerObj) {\n // When goog.events.listen run on OFF_AND_FAIL or OFF_AND_SILENT\n // (goog.events.CaptureSimulationMode) in IE8-, it will return null\n // value.\n return self;\n }\n\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n var key = listenerObj.key;\n self.keys_[key] = listenerObj;\n }\n\n return self;\n};\n\n\n/**\n * Listen to an event on a Listenable. If the function is omitted, then the\n * EventHandler's handleEvent method will be used. After the event has fired the\n * event listener is removed from the target. If an array of event types is\n * provided, each event type will be listened to once.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type to listen for or array of event types.\n * @param {function(this:SCOPE, EVENTOBJ):?|{handleEvent:function(?):?}|null=}\n * opt_fn\n * Optional callback function to be used as the listener or an object with\n * handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listenOnce = function(\n src, type, opt_fn, opt_options) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n return self.listenOnce_(src, type, opt_fn, opt_options);\n};\n\n\n/**\n * Listen to an event on a Listenable. If the function is omitted, then the\n * EventHandler's handleEvent method will be used. After the event has fired the\n * event listener is removed from the target. If an array of event types is\n * provided, each event type will be listened to once.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type to listen for or array of event types.\n * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(this:T, ?):?}|\n * null|undefined} fn Optional callback function to be used as the\n * listener or an object with handleEvent function.\n * @param {boolean|undefined} capture Optional whether to use capture phase.\n * @param {T} scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template T, EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.listenOnceWithScope = function(\n src, type, fn, capture, scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n // TODO(mknichel): Deprecate this function.\n return self.listenOnce_(src, type, fn, capture, scope);\n};\n\n\n/**\n * Listen to an event on a Listenable. If the function is omitted, then the\n * EventHandler's handleEvent method will be used. After the event has fired\n * the event listener is removed from the target. If an array of event types is\n * provided, each event type will be listened to once.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type to listen for or array of event types.\n * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn\n * Optional callback function to be used as the listener or an object with\n * handleEvent function.\n * @param {(boolean|!AddEventListenerOptions)=} opt_options\n * @param {Object=} opt_scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n * @private\n */\ngoog.events.EventHandler.prototype.listenOnce_ = function(\n src, type, opt_fn, opt_options, opt_scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n if (Array.isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n self.listenOnce_(src, type[i], opt_fn, opt_options, opt_scope);\n }\n } else {\n var listenerObj = goog.events.listenOnce(\n src, type, opt_fn || self.handleEvent, opt_options,\n opt_scope || self.handler_ || self);\n if (!listenerObj) {\n // When goog.events.listen run on OFF_AND_FAIL or OFF_AND_SILENT\n // (goog.events.CaptureSimulationMode) in IE8-, it will return null\n // value.\n return self;\n }\n\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n var key = listenerObj.key;\n self.keys_[key] = listenerObj;\n }\n\n return self;\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.EventTarget}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.EventTarget} src The node to listen to\n * events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:SCOPE, ?):?|{handleEvent:function(?):?}|null} listener\n * Callback method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n * false).\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template THIS\n */\ngoog.events.EventHandler.prototype.listenWithWrapper = function(\n src, wrapper, listener, opt_capt) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n // TODO(mknichel): Remove the opt_scope from this function and then\n // templatize it.\n return self.listenWithWrapper_(src, wrapper, listener, opt_capt);\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.EventTarget}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.EventTarget} src The node to listen to\n * events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(this:T, ?):?|{handleEvent:function(this:T, ?):?}|null}\n * listener Optional callback function to be used as the\n * listener or an object with handleEvent function.\n * @param {boolean|undefined} capture Optional whether to use capture phase.\n * @param {T} scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template T, THIS\n */\ngoog.events.EventHandler.prototype.listenWithWrapperAndScope = function(\n src, wrapper, listener, capture, scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n // TODO(mknichel): Deprecate this function.\n return self.listenWithWrapper_(src, wrapper, listener, capture, scope);\n};\n\n\n/**\n * Adds an event listener with a specific event wrapper on a DOM Node or an\n * object that has implemented {@link goog.events.EventTarget}. A listener can\n * only be added once to an object.\n *\n * @param {EventTarget|goog.events.EventTarget} src The node to listen to\n * events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback\n * method, or an object with a handleEvent function.\n * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to\n * false).\n * @param {Object=} opt_scope Element in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template THIS\n * @private\n */\ngoog.events.EventHandler.prototype.listenWithWrapper_ = function(\n src, wrapper, listener, opt_capt, opt_scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n wrapper.listen(\n src, listener, opt_capt, opt_scope || self.handler_ || self, self);\n return self;\n};\n\n\n/**\n * @return {number} Number of listeners registered by this handler.\n */\ngoog.events.EventHandler.prototype.getListenerCount = function() {\n 'use strict';\n var count = 0;\n for (var key in this.keys_) {\n if (Object.prototype.hasOwnProperty.call(this.keys_, key)) {\n count++;\n }\n }\n return count;\n};\n\n\n/**\n * Unlistens on an event.\n * @param {goog.events.ListenableType} src Event source.\n * @param {string|Array<string>|\n * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}\n * type Event type or array of event types to unlisten to.\n * @param {function(this:?, EVENTOBJ):?|{handleEvent:function(?):?}|null=}\n * opt_fn Optional callback function to be used as the listener or an object\n * with handleEvent function.\n * @param {(boolean|!EventListenerOptions)=} opt_options\n * @param {Object=} opt_scope Object in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template EVENTOBJ, THIS\n */\ngoog.events.EventHandler.prototype.unlisten = function(\n src, type, opt_fn, opt_options, opt_scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n if (Array.isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n self.unlisten(src, type[i], opt_fn, opt_options, opt_scope);\n }\n } else {\n var capture =\n goog.isObject(opt_options) ? !!opt_options.capture : !!opt_options;\n var listener = goog.events.getListener(\n src, type, opt_fn || self.handleEvent, capture,\n opt_scope || self.handler_ || self);\n\n if (listener) {\n goog.events.unlistenByKey(listener);\n delete self.keys_[listener.key];\n }\n }\n\n return self;\n};\n\n\n/**\n * Removes an event listener which was added with listenWithWrapper().\n *\n * @param {EventTarget|goog.events.EventTarget} src The target to stop\n * listening to events on.\n * @param {goog.events.EventWrapper} wrapper Event wrapper to use.\n * @param {function(?):?|{handleEvent:function(?):?}|null} listener The\n * listener function to remove.\n * @param {boolean=} opt_capt In DOM-compliant browsers, this determines\n * whether the listener is fired during the capture or bubble phase of the\n * event.\n * @param {Object=} opt_scope Element in whose scope to call the listener.\n * @return {THIS} This object, allowing for chaining of calls.\n * @this {THIS}\n * @template THIS\n */\ngoog.events.EventHandler.prototype.unlistenWithWrapper = function(\n src, wrapper, listener, opt_capt, opt_scope) {\n 'use strict';\n var self = /** @type {!goog.events.EventHandler} */ (this);\n wrapper.unlisten(\n src, listener, opt_capt, opt_scope || self.handler_ || self, self);\n return self;\n};\n\n\n/**\n * Unlistens to all events.\n */\ngoog.events.EventHandler.prototype.removeAll = function() {\n 'use strict';\n goog.object.forEach(this.keys_, function(listenerObj, key) {\n 'use strict';\n if (this.keys_.hasOwnProperty(key)) {\n goog.events.unlistenByKey(listenerObj);\n }\n }, this);\n\n this.keys_ = {};\n};\n\n\n/**\n * Disposes of this EventHandler and removes all listeners that it registered.\n * @override\n * @protected\n */\ngoog.events.EventHandler.prototype.disposeInternal = function() {\n 'use strict';\n goog.events.EventHandler.superClass_.disposeInternal.call(this);\n this.removeAll();\n};\n\n\n/**\n * Default event handler\n * @param {goog.events.Event} e Event object.\n */\ngoog.events.EventHandler.prototype.handleEvent = function(e) {\n 'use strict';\n throw new Error('EventHandler.handleEvent not implemented');\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a utility for tracing and debugging WebChannel\n * requests.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.WebChannelDebug');\n\ngoog.require('goog.json');\ngoog.require('goog.log');\ngoog.requireType('goog.Uri');\ngoog.requireType('goog.net.XmlHttp.ReadyState');\n\n\n\n/**\n * Logs and keeps a buffer of debugging info for the Channel.\n *\n * @constructor\n * @struct\n * @final\n */\ngoog.labs.net.webChannel.WebChannelDebug = function() {\n 'use strict';\n /**\n * The logger instance.\n * @const\n * @private {?goog.log.Logger}\n */\n this.logger_ = goog.log.getLogger('goog.labs.net.webChannel.WebChannelDebug');\n\n /**\n * Whether to enable redact. Defaults to true.\n * @private {boolean}\n */\n this.redactEnabled_ = true;\n};\n\n\ngoog.scope(function() {\n'use strict';\nvar WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\n\n\n/**\n * Turns off redact.\n */\nWebChannelDebug.prototype.disableRedact = function() {\n 'use strict';\n this.redactEnabled_ = false;\n};\n\n\n/**\n * Logs that the browser went offline during the lifetime of a request.\n * @param {goog.Uri} url The URL being requested.\n */\nWebChannelDebug.prototype.browserOfflineResponse = function(url) {\n 'use strict';\n this.info(function() {\n 'use strict';\n return 'BROWSER_OFFLINE: ' + url;\n });\n};\n\n\n/**\n * Logs an XmlHttp request..\n * @param {string} verb The request type (GET/POST).\n * @param {goog.Uri} uri The request destination.\n * @param {string|number|undefined} id The request id.\n * @param {number} attempt Which attempt # the request was.\n * @param {?string} postData The data posted in the request.\n */\nWebChannelDebug.prototype.xmlHttpChannelRequest = function(\n verb, uri, id, attempt, postData) {\n 'use strict';\n var self = this;\n this.info(function() {\n 'use strict';\n return 'XMLHTTP REQ (' + id + ') [attempt ' + attempt + ']: ' + verb +\n '\\n' + uri + '\\n' + self.maybeRedactPostData_(postData);\n });\n};\n\n\n/**\n * Logs the meta data received from an XmlHttp request.\n * @param {string} verb The request type (GET/POST).\n * @param {goog.Uri} uri The request destination.\n * @param {string|number|undefined} id The request id.\n * @param {number} attempt Which attempt # the request was.\n * @param {goog.net.XmlHttp.ReadyState} readyState The ready state.\n * @param {number} statusCode The HTTP status code.\n */\nWebChannelDebug.prototype.xmlHttpChannelResponseMetaData = function(\n verb, uri, id, attempt, readyState, statusCode) {\n 'use strict';\n this.info(function() {\n 'use strict';\n return 'XMLHTTP RESP (' + id + ') [ attempt ' + attempt + ']: ' + verb +\n '\\n' + uri + '\\n' + readyState + ' ' + statusCode;\n });\n};\n\n\n/**\n * Logs the response data received from an XmlHttp request.\n * @param {string|number|undefined} id The request id.\n * @param {?string} responseText The response text.\n * @param {?string=} opt_desc Optional request description.\n */\nWebChannelDebug.prototype.xmlHttpChannelResponseText = function(\n id, responseText, opt_desc) {\n 'use strict';\n var self = this;\n this.info(function() {\n 'use strict';\n return 'XMLHTTP TEXT (' + id + '): ' + self.redactResponse_(responseText) +\n (opt_desc ? ' ' + opt_desc : '');\n });\n};\n\n\n/**\n * Logs a request timeout.\n * @param {goog.Uri} uri The uri that timed out.\n */\nWebChannelDebug.prototype.timeoutResponse = function(uri) {\n 'use strict';\n this.info(function() {\n 'use strict';\n return 'TIMEOUT: ' + uri;\n });\n};\n\n\n/**\n * Logs a debug message.\n * @param {!goog.log.Loggable} text The message.\n */\nWebChannelDebug.prototype.debug = function(text) {\n 'use strict';\n goog.log.fine(this.logger_, text);\n};\n\n\n/**\n * Logs an exception\n * @param {Error} e The error or error event.\n * @param {goog.log.Loggable=} opt_msg The optional message,\n * defaults to 'Exception'.\n */\nWebChannelDebug.prototype.dumpException = function(e, opt_msg) {\n 'use strict';\n goog.log.error(this.logger_, opt_msg || 'Exception', e);\n};\n\n\n/**\n * Logs an info message.\n * @param {!goog.log.Loggable} text The message.\n */\nWebChannelDebug.prototype.info = function(text) {\n 'use strict';\n goog.log.info(this.logger_, text);\n};\n\n\n/**\n * Logs a warning message.\n * @param {!goog.log.Loggable} text The message.\n */\nWebChannelDebug.prototype.warning = function(text) {\n 'use strict';\n goog.log.warning(this.logger_, text);\n};\n\n\n/**\n * Logs a severe message.\n * @param {!goog.log.Loggable} text The message.\n */\nWebChannelDebug.prototype.severe = function(text) {\n 'use strict';\n goog.log.error(this.logger_, text);\n};\n\n\n/**\n * Removes potentially private data from a response so that we don't\n * accidentally save private and personal data to the server logs.\n * @param {?string} responseText A JSON response to clean.\n * @return {?string} The cleaned response.\n * @private\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\nWebChannelDebug.prototype.redactResponse_ = function(responseText) {\n 'use strict';\n if (!this.redactEnabled_) {\n return responseText;\n }\n\n if (!responseText) {\n return null;\n }\n\n try {\n var responseArray = JSON.parse(responseText);\n if (responseArray) {\n for (var i = 0; i < responseArray.length; i++) {\n if (Array.isArray(responseArray[i])) {\n this.maybeRedactArray_(responseArray[i]);\n }\n }\n }\n\n return goog.json.serialize(responseArray);\n } catch (e) {\n this.debug('Exception parsing expected JS array - probably was not JS');\n return responseText;\n }\n};\n\n\n/**\n * Removes data from a response array that may be sensitive.\n * @param {!Array<?>} array The array to clean.\n * @private\n */\nWebChannelDebug.prototype.maybeRedactArray_ = function(array) {\n 'use strict';\n if (array.length < 2) {\n return;\n }\n var dataPart = array[1];\n if (!Array.isArray(dataPart)) {\n return;\n }\n if (dataPart.length < 1) {\n return;\n }\n\n var type = dataPart[0];\n if (type != 'noop' && type != 'stop' && type != 'close') {\n // redact all fields in the array\n for (var i = 1; i < dataPart.length; i++) {\n dataPart[i] = '';\n }\n }\n};\n\n\n/**\n * Removes potentially private data from a request POST body so that we don't\n * accidentally save private and personal data to the server logs.\n * @param {?string} data The data string to clean.\n * @return {?string} The data string with sensitive data replaced by 'redacted'.\n * @private\n */\nWebChannelDebug.prototype.maybeRedactPostData_ = function(data) {\n 'use strict';\n if (!this.redactEnabled_) {\n return data;\n }\n\n if (!data) {\n return null;\n }\n var out = '';\n var params = data.split('&');\n for (var i = 0; i < params.length; i++) {\n var param = params[i];\n var keyValue = param.split('=');\n if (keyValue.length > 1) {\n var key = keyValue[0];\n var value = keyValue[1];\n\n var keyParts = key.split('_');\n if (keyParts.length >= 2 && keyParts[1] == 'type') {\n out += key + '=' + value + '&';\n } else {\n out += key + '=' +\n 'redacted' +\n '&';\n }\n }\n }\n return out;\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Static utilities for collecting stats associated with\n * ChannelRequest.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.requestStats');\ngoog.provide('goog.labs.net.webChannel.requestStats.Event');\ngoog.provide('goog.labs.net.webChannel.requestStats.ServerReachability');\ngoog.provide('goog.labs.net.webChannel.requestStats.ServerReachabilityEvent');\ngoog.provide('goog.labs.net.webChannel.requestStats.Stat');\ngoog.provide('goog.labs.net.webChannel.requestStats.StatEvent');\ngoog.provide('goog.labs.net.webChannel.requestStats.TimingEvent');\n\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventTarget');\n\n\ngoog.scope(function() {\n'use strict';\nconst requestStats = goog.labs.net.webChannel.requestStats;\n\n\n/**\n * Events fired.\n * @const\n */\nrequestStats.Event = {};\n\n\n/**\n * Singleton event target for firing stat events\n * @type {?goog.events.EventTarget}\n * @private\n */\nrequestStats.eventTarget_ = null;\n\n/**\n * Singleton event target for firing stat events\n * @return {!goog.events.EventTarget}\n * @private\n */\nrequestStats.getStatEventTarget_ = function() {\n 'use strict';\n requestStats.eventTarget_ =\n requestStats.eventTarget_ || new goog.events.EventTarget();\n return requestStats.eventTarget_;\n};\n\n/**\n * The type of event that occurs every time some information about how reachable\n * the server is is discovered.\n */\nrequestStats.Event.SERVER_REACHABILITY_EVENT = 'serverreachability';\n\n\n/**\n * Types of events which reveal information about the reachability of the\n * server.\n * @enum {number}\n */\nrequestStats.ServerReachability = {\n REQUEST_MADE: 1,\n REQUEST_SUCCEEDED: 2,\n REQUEST_FAILED: 3,\n BACK_CHANNEL_ACTIVITY: 4 // any response data received\n};\n\n\n\n/**\n * Event class for SERVER_REACHABILITY_EVENT.\n *\n * @param {goog.events.EventTarget} target The stat event target for\n the channel.\n * @param {requestStats.ServerReachability} reachabilityType\n * The reachability event type.\n * @constructor\n * @extends {goog.events.Event}\n */\nrequestStats.ServerReachabilityEvent = function(target, reachabilityType) {\n 'use strict';\n goog.events.Event.call(\n this, requestStats.Event.SERVER_REACHABILITY_EVENT, target);\n\n /**\n * @type {requestStats.ServerReachability}\n */\n this.reachabilityType = reachabilityType;\n};\ngoog.inherits(requestStats.ServerReachabilityEvent, goog.events.Event);\n\n\n/**\n * Notify the channel that a particular fine grained network event has occurred.\n * Should be considered package-private.\n * @param {requestStats.ServerReachability} reachabilityType\n * The reachability event type.\n */\nrequestStats.notifyServerReachabilityEvent = function(reachabilityType) {\n 'use strict';\n const target = requestStats.getStatEventTarget_();\n target.dispatchEvent(\n new requestStats.ServerReachabilityEvent(target, reachabilityType));\n};\n\n\n/**\n * Stat Event that fires when things of interest happen that may be useful for\n * applications to know about for stats or debugging purposes.\n */\nrequestStats.Event.STAT_EVENT = 'statevent';\n\n\n/**\n * Enum that identifies events for statistics that are interesting to track.\n * @enum {number}\n */\nrequestStats.Stat = {\n /** Event indicating a new connection attempt. */\n CONNECT_ATTEMPT: 0,\n\n /** Event indicating a connection error due to a general network problem. */\n ERROR_NETWORK: 1,\n\n /**\n * Event indicating a connection error that isn't due to a general network\n * problem.\n */\n ERROR_OTHER: 2,\n\n /** Event indicating the start of test stage one. */\n TEST_STAGE_ONE_START: 3,\n\n /** Event indicating the start of test stage two. */\n TEST_STAGE_TWO_START: 4,\n\n /** Event indicating the first piece of test data was received. */\n TEST_STAGE_TWO_DATA_ONE: 5,\n\n /**\n * Event indicating that the second piece of test data was received and it was\n * received separately from the first.\n */\n TEST_STAGE_TWO_DATA_TWO: 6,\n\n /** Event indicating both pieces of test data were received simultaneously. */\n TEST_STAGE_TWO_DATA_BOTH: 7,\n\n /** Event indicating stage one of the test request failed. */\n TEST_STAGE_ONE_FAILED: 8,\n\n /** Event indicating stage two of the test request failed. */\n TEST_STAGE_TWO_FAILED: 9,\n\n /**\n * Event indicating that a buffering proxy is likely between the client and\n * the server.\n */\n PROXY: 10,\n\n /**\n * Event indicating that no buffering proxy is likely between the client and\n * the server.\n */\n NOPROXY: 11,\n\n /** Event indicating an unknown SID error. */\n REQUEST_UNKNOWN_SESSION_ID: 12,\n\n /** Event indicating a bad status code was received. */\n REQUEST_BAD_STATUS: 13,\n\n /** Event indicating incomplete data was received */\n REQUEST_INCOMPLETE_DATA: 14,\n\n /** Event indicating bad data was received */\n REQUEST_BAD_DATA: 15,\n\n /** Event indicating no data was received when data was expected. */\n REQUEST_NO_DATA: 16,\n\n /** Event indicating a request timeout. */\n REQUEST_TIMEOUT: 17,\n\n /**\n * Event indicating that the server never received our hanging GET and so it\n * is being retried.\n */\n BACKCHANNEL_MISSING: 18,\n\n /**\n * Event indicating that we have determined that our hanging GET is not\n * receiving data when it should be. Thus it is dead dead and will be retried.\n */\n BACKCHANNEL_DEAD: 19,\n\n /**\n * The browser declared itself offline during the lifetime of a request, or\n * was offline when a request was initially made.\n */\n BROWSER_OFFLINE: 20\n};\n\n\n\n/**\n * Event class for STAT_EVENT.\n *\n * @param {goog.events.EventTarget} eventTarget The stat event target for\n the channel.\n * @param {requestStats.Stat} stat The stat.\n * @constructor\n * @extends {goog.events.Event}\n */\nrequestStats.StatEvent = function(eventTarget, stat) {\n 'use strict';\n goog.events.Event.call(this, requestStats.Event.STAT_EVENT, eventTarget);\n\n /**\n * The stat\n * @type {requestStats.Stat}\n */\n this.stat = stat;\n};\ngoog.inherits(requestStats.StatEvent, goog.events.Event);\n\n\n/**\n * Returns the singleton event target for stat events.\n * @return {!goog.events.EventTarget} The event target for stat events.\n */\nrequestStats.getStatEventTarget = function() {\n 'use strict';\n return requestStats.getStatEventTarget_();\n};\n\n\n/**\n * Helper function to call the stat event callback.\n * @param {requestStats.Stat} stat The stat.\n */\nrequestStats.notifyStatEvent = function(stat) {\n 'use strict';\n const target = requestStats.getStatEventTarget_();\n target.dispatchEvent(new requestStats.StatEvent(target, stat));\n};\n\n\n/**\n * An event that fires when POST requests complete successfully, indicating\n * the size of the POST and the round trip time.\n */\nrequestStats.Event.TIMING_EVENT = 'timingevent';\n\n\n\n/**\n * Event class for requestStats.Event.TIMING_EVENT\n *\n * @param {goog.events.EventTarget} target The stat event target for\n the channel.\n * @param {number} size The number of characters in the POST data.\n * @param {number} rtt The total round trip time from POST to response in MS.\n * @param {number} retries The number of times the POST had to be retried.\n * @constructor\n * @extends {goog.events.Event}\n */\nrequestStats.TimingEvent = function(target, size, rtt, retries) {\n 'use strict';\n goog.events.Event.call(this, requestStats.Event.TIMING_EVENT, target);\n\n /**\n * @type {number}\n */\n this.size = size;\n\n /**\n * @type {number}\n */\n this.rtt = rtt;\n\n /**\n * @type {number}\n */\n this.retries = retries;\n};\ngoog.inherits(requestStats.TimingEvent, goog.events.Event);\n\n\n/**\n * Helper function to notify listeners about POST request performance.\n *\n * @param {number} size Number of characters in the POST data.\n * @param {number} rtt The amount of time from POST start to response.\n * @param {number} retries The number of times the POST had to be retried.\n */\nrequestStats.notifyTimingEvent = function(size, rtt, retries) {\n 'use strict';\n const target = requestStats.getStatEventTarget_();\n target.dispatchEvent(\n new requestStats.TimingEvent(target, size, rtt, retries));\n};\n\n\n/**\n * Allows the application to set an execution hooks for when a channel\n * starts processing requests. This is useful to track timing or logging\n * special information. The function takes no parameters and return void.\n * @param {Function} startHook The function for the start hook.\n */\nrequestStats.setStartThreadExecutionHook = function(startHook) {\n 'use strict';\n requestStats.startExecutionHook_ = startHook;\n};\n\n\n/**\n * Allows the application to set an execution hooks for when a channel\n * stops processing requests. This is useful to track timing or logging\n * special information. The function takes no parameters and return void.\n * @param {Function} endHook The function for the end hook.\n */\nrequestStats.setEndThreadExecutionHook = function(endHook) {\n 'use strict';\n requestStats.endExecutionHook_ = endHook;\n};\n\n\n/**\n * Application provided execution hook for the start hook.\n *\n * @type {Function}\n * @private\n */\nrequestStats.startExecutionHook_ = function() {};\n\n\n/**\n * Application provided execution hook for the end hook.\n *\n * @type {Function}\n * @private\n */\nrequestStats.endExecutionHook_ = function() {};\n\n\n/**\n * Helper function to call the start hook\n */\nrequestStats.onStartExecution = function() {\n 'use strict';\n requestStats.startExecutionHook_();\n};\n\n\n/**\n * Helper function to call the end hook\n */\nrequestStats.onEndExecution = function() {\n 'use strict';\n requestStats.endExecutionHook_();\n};\n\n\n/**\n * Wrapper around SafeTimeout which calls the start and end execution hooks\n * with a try...finally block.\n * @param {Function} fn The callback function.\n * @param {number} ms The time in MS for the timer.\n * @return {number} The ID of the timer.\n */\nrequestStats.setTimeout = function(fn, ms) {\n 'use strict';\n if (typeof fn !== 'function') {\n throw new Error('Fn must not be null and must be a function');\n }\n return goog.global.setTimeout(function() {\n 'use strict';\n requestStats.onStartExecution();\n try {\n fn();\n } finally {\n requestStats.onEndExecution();\n }\n }, ms);\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Error codes shared between goog.net.IframeIo and\n * goog.net.XhrIo.\n */\n\ngoog.provide('goog.net.ErrorCode');\n\n\n/**\n * Error codes\n * @enum {number}\n */\ngoog.net.ErrorCode = {\n\n /**\n * There is no error condition.\n */\n NO_ERROR: 0,\n\n /**\n * The most common error from iframeio, unfortunately, is that the browser\n * responded with an error page that is classed as a different domain. The\n * situations, are when a browser error page is shown -- 404, access denied,\n * DNS failure, connection reset etc.)\n *\n */\n ACCESS_DENIED: 1,\n\n /**\n * Currently the only case where file not found will be caused is when the\n * code is running on the local file system and a non-IE browser makes a\n * request to a file that doesn't exist.\n */\n FILE_NOT_FOUND: 2,\n\n /**\n * If Firefox shows a browser error page, such as a connection reset by\n * server or access denied, then it will fail silently without the error or\n * load handlers firing.\n */\n FF_SILENT_ERROR: 3,\n\n /**\n * Custom error provided by the client through the error check hook.\n */\n CUSTOM_ERROR: 4,\n\n /**\n * Exception was thrown while processing the request.\n */\n EXCEPTION: 5,\n\n /**\n * The Http response returned a non-successful http status code.\n */\n HTTP_ERROR: 6,\n\n /**\n * The request was aborted.\n */\n ABORT: 7,\n\n /**\n * The request timed out.\n */\n TIMEOUT: 8,\n\n /**\n * The resource is not available offline.\n */\n OFFLINE: 9,\n};\n\n\n/**\n * Returns a friendly error message for an error code. These messages are for\n * debugging and are not localized.\n * @param {goog.net.ErrorCode} errorCode An error code.\n * @return {string} A message for debugging.\n */\ngoog.net.ErrorCode.getDebugMessage = function(errorCode) {\n 'use strict';\n switch (errorCode) {\n case goog.net.ErrorCode.NO_ERROR:\n return 'No Error';\n\n case goog.net.ErrorCode.ACCESS_DENIED:\n return 'Access denied to content document';\n\n case goog.net.ErrorCode.FILE_NOT_FOUND:\n return 'File not found';\n\n case goog.net.ErrorCode.FF_SILENT_ERROR:\n return 'Firefox silently errored';\n\n case goog.net.ErrorCode.CUSTOM_ERROR:\n return 'Application custom error';\n\n case goog.net.ErrorCode.EXCEPTION:\n return 'An exception occurred';\n\n case goog.net.ErrorCode.HTTP_ERROR:\n return 'Http response at 400 or 500 level';\n\n case goog.net.ErrorCode.ABORT:\n return 'Request was aborted';\n\n case goog.net.ErrorCode.TIMEOUT:\n return 'Request timed out';\n\n case goog.net.ErrorCode.OFFLINE:\n return 'The resource is not available offline';\n\n default:\n return 'Unrecognized error code';\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Common events for the network classes.\n */\n\n\ngoog.provide('goog.net.EventType');\n\n\n/**\n * Event names for network events\n * @enum {string}\n */\ngoog.net.EventType = {\n COMPLETE: 'complete',\n SUCCESS: 'success',\n ERROR: 'error',\n ABORT: 'abort',\n READY: 'ready',\n READY_STATE_CHANGE: 'readystatechange',\n TIMEOUT: 'timeout',\n INCREMENTAL_DATA: 'incrementaldata',\n PROGRESS: 'progress',\n // DOWNLOAD_PROGRESS and UPLOAD_PROGRESS are special events dispatched by\n // goog.net.XhrIo to allow binding listeners specific to each type of\n // progress.\n DOWNLOAD_PROGRESS: 'downloadprogress',\n UPLOAD_PROGRESS: 'uploadprogress',\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Interface for a factory for creating XMLHttpRequest objects\n * and metadata about them.\n */\n\ngoog.provide('goog.net.XmlHttpFactory');\n\n/** @suppress {extraRequire} Typedef. */\ngoog.require('goog.net.XhrLike');\n\n\n\n/**\n * Abstract base class for an XmlHttpRequest factory.\n * @constructor\n */\ngoog.net.XmlHttpFactory = function() {};\n\n\n/**\n * Cache of options - we only actually call internalGetOptions once.\n * @type {?Object}\n * @private\n */\ngoog.net.XmlHttpFactory.prototype.cachedOptions_ = null;\n\n\n/**\n * @return {!goog.net.XhrLike.OrNative} A new XhrLike instance.\n */\ngoog.net.XmlHttpFactory.prototype.createInstance = goog.abstractMethod;\n\n\n/**\n * @return {Object} Options describing how xhr objects obtained from this\n * factory should be used.\n */\ngoog.net.XmlHttpFactory.prototype.getOptions = function() {\n 'use strict';\n return this.cachedOptions_ ||\n (this.cachedOptions_ = this.internalGetOptions());\n};\n\n\n/**\n * Override this method in subclasses to preserve the caching offered by\n * getOptions().\n * @return {Object} Options describing how xhr objects obtained from this\n * factory should be used.\n * @protected\n */\ngoog.net.XmlHttpFactory.prototype.internalGetOptions = goog.abstractMethod;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The API spec for the WebChannel messaging library.\n *\n * Similar to HTML5 WebSocket, WebChannel offers an abstraction for\n * point-to-point socket-like communication between a browser client and\n * a remote origin.\n *\n * WebChannels are created via <code>WebChannel</code>. Multiple WebChannels\n * may be multiplexed over the same WebChannelTransport, which encapsulates\n * the underlying physical connectivity over standard wire protocols\n * such as HTTP.\n *\n * A WebChannel in turn represents a logical communication channel between\n * the client and server endpoint. A WebChannel remains open for as long\n * as the client or server endpoint allows.\n *\n * Messages are delivered in-order and reliably over the same WebChannel,\n * and the choice of the underlying wire protocols is completely transparent\n * to the API users.\n *\n * Note that we have no immediate plan to move this API out of labs. While\n * the implementation is production ready, the API is subject to change.\n */\n\ngoog.provide('goog.net.WebChannel');\ngoog.provide('goog.net.WebChannel.Options');\n\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.Listenable');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n\n/**\n * A WebChannel represents a logical bi-directional channel over which the\n * client communicates with a remote server that holds the other endpoint\n * of the channel. A WebChannel is always created in the context of a shared\n * {@link WebChannelTransport} instance. It is up to the underlying client-side\n * and server-side implementations to decide how or when multiplexing is\n * to be enabled.\n *\n * @interface\n * @extends {goog.events.Listenable}\n */\ngoog.net.WebChannel = function() {};\n\n\n\n/**\n * This interface defines a pluggable API to allow WebChannel runtime to support\n * customized algorithms in order to recover from transient failures such as\n * those failures caused by network or proxies (intermediaries).\n *\n * The algorithm may also choose to fail-fast, e.g. switch the client to some\n * offline mode.\n *\n * Extra measurements and logging could also be implemented in the custom\n * module, which has the full knowledge of all the state transitions\n * (due to failures).\n *\n * A default algorithm will be provided by the webchannel library itself. Custom\n * algorithms are expected to be tailored to specific client platforms or\n * networking environments, e.g. mobile, cellular network.\n *\n * @interface\n */\ngoog.net.WebChannel.FailureRecovery = function() {};\n\n\n/**\n * Configuration spec for newly created WebChannel instances.\n *\n * WebChannels are configured in the context of the containing\n * {@link WebChannelTransport}. The configuration parameters are specified\n * when a new instance of WebChannel is created via {@link WebChannelTransport}.\n * @record\n */\ngoog.net.WebChannel.Options = function() {};\n\n/**\n * Transport-metadata support.\n *\n * Custom HTTP headers to be added to every message sent to the server. This\n * object is mutable, and custom headers may be changed, removed, or added\n * during the runtime after a channel has been opened.\n *\n * Custom headers may trigger CORS preflight. See other related options.\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.messageHeaders;\n\n/**\n * Transport-metadata support.\n *\n * Similar to messageHeaders, but any custom HTTP headers will be sent only once\n * when the channel is opened as part of the handshake request. Typical usage is\n * to send an auth header to the server, which only checks the auth header at\n * the time during the handshake when the channel is opened.\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.initMessageHeaders;\n\n/**\n * Sent as initMessageHeaders via X-WebChannel-Content-Type,\n * to inform the server the MIME type of WebChannel messages.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.messageContentType;\n\n/**\n * Transport-metadata support.\n *\n * Custom url query parameters to be added to every message sent to the server.\n * This object is mutable, and custom parameters may be changed, removed or\n * added during the runtime after a channel has been opened.\n *\n * TODO: initMessageUrlParams\n * TODO: closeMessageUrlParams (custom url query params to be added to the\n * channel-close message. Custom headers are not supported due to the use of\n * SendBeacon)\n *\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.messageUrlParams;\n\n/**\n * Whether a special header should be added to\n * each message so that the server can dispatch webchannel messages without\n * knowing the URL path prefix. Defaults to false.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.clientProtocolHeaderRequired;\n\n/**\n * The maximum number of in-flight HTTP requests allowed\n * when SPDY is enabled. Currently we only detect SPDY in Chrome.\n * This parameter defaults to 10. When SPDY is not enabled, this parameter\n * will have no effect.\n * @type {number|undefined}\n */\ngoog.net.WebChannel.Options.prototype.concurrentRequestLimit;\n\n/**\n * Setting this to true to allow the use of sub-domains\n * (as configured by the server) to send XHRs with the CORS withCredentials\n * bit set to true.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.supportsCrossDomainXhr;\n\n/**\n * Whether to bypass v8 encoding of client-sent messages.\n * This defaults to false now due to legacy servers. New applications should\n * always configure this option to true.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.sendRawJson;\n\n/**\n * The URL parameter name that contains the session id (for sticky routing of\n * HTTP requests). When this param is specified, a server that supports this\n * option will respond with an opaque session id as part of the initial\n * handshake (via the X-HTTP-Session-Id header); and all the subsequent requests\n * will contain the httpSessionIdParam. This option will take precedence over\n * any duplicated parameter specified with messageUrlParams, whose value will be\n * ignored.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.httpSessionIdParam;\n\n/**\n * The URL parameter name to allow custom HTTP\n * headers to be overwritten as a URL param to bypass CORS preflight.\n *\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.httpHeadersOverwriteParam;\n\n/**\n * Whether to encode Options.initMessageHeaders in the HTTP request body.\n * This option defaults to false. If true, Options.httpHeadersOverwriteParam\n * will be ignored.\n *\n * This option should not be set if Options.fastHandshake is set (which\n * uses GET for handshake).\n *\n * Web-only feature.\n *\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.encodeInitMessageHeaders;\n\n/**\n * Whether to force long-polling from client to server.\n * This defaults to false. Long-polling may be necessary when a (MITM) proxy\n * is buffering data sent by the server.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.forceLongPolling;\n\n/**\n * Whether to enable automatic detection of buffering proxies. In the presence\n * of any buffering proxy, webchannel will use long-polling to send messages\n * from the server to the client. This option defaults to false.\n * Currently when fastHandshake is enabled, this option will be ignored.\n * Compared to \"forceLongPolling\", this option may introduce up to 2-RTT\n * extra latency for delivering messages generated immediately after the\n * handshake.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.detectBufferingProxy;\n\n/**\n * This option informs the server the desired maximum timeout interval (in\n * Milliseconds) to complete a long-polling GET response, e.g. to accommodate\n * the timeout enforced by a proxy. The WebChannel server may adjust the\n * specified timeout or may ignore this client-configured timeout.\n * @type {number|undefined}\n */\ngoog.net.WebChannel.Options.prototype.longPollingTimeout;\n\n/**\n * Enable true 0-RTT message delivery, including\n * leveraging QUIC 0-RTT (which requires GET to be used). This option\n * defaults to false. Note it is allowed to send messages before Open event is\n * received, after a channel has been opened. In order to enable 0-RTT,\n * messages will be encoded as part of URL and therefore there needs be a size\n * limit for those initial messages that are sent immediately as part of the\n * GET handshake request. With sendRawJson=true, this limit is currently set\n * to 4K chars and data beyond this limit will be buffered till the handshake\n * (1-RTT) finishes. With sendRawJson=false, it's up to the application\n * to limit the amount of data that is sent as part of the handshake.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.fastHandshake;\n\n/**\n * Enable the blocking RPC semantics for the handshake:\n * 1) the completion of handshake is blocked by the server-side application\n * logic for handling the handshake (HTTP) request; 2) the client application\n * will inspect the handshake (HTTP) response headers as generated\n * by the server application (v.s. by only the webchannel runtime). This option\n * defaults to false.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.blockingHandshake;\n\n/**\n * Whether to disable logging redact. By default, redact is\n * enabled to remove any message payload or user-provided info\n * from closure logs.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.disableRedact;\n\n/**\n * Inform the server about the client profile to enable\n * customized configs that are optimized for certain clients or environments.\n * Currently this information is sent via X-WebChannel-Client-Profile header.\n * @type {string|undefined}\n */\ngoog.net.WebChannel.Options.prototype.clientProfile;\n\n/**\n * The internal channel parameter name to allow\n * experimental channel configurations. Supported options include fastfail,\n * baseRetryDelayMs, retryDelaySeedMs, forwardChannelMaxRetries and\n * forwardChannelRequestTimeoutMs. Note that these options are subject to\n * change.\n * @type {!Object<string, boolean|number>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.internalChannelParams;\n\n/**\n * Allows the caller to override the factory used to create\n * XMLHttpRequest objects. This is introduced to disable CORS on firefox OS.\n * @type {!goog.net.XmlHttpFactory|undefined}\n */\ngoog.net.WebChannel.Options.prototype.xmlHttpFactory;\n\n/**\n * Client-side thresholds that decide when to refresh\n * an underlying HTTP request, to limit memory consumption due to XHR buffering\n * or compression context. The client-side thresholds should be significantly\n * smaller than the server-side thresholds. This allows the client to eliminate\n * any latency introduced by request refreshing, i.e. an RTT window during which\n * messages may be buffered on the server-side. Supported params include\n * totalBytesReceived, totalDurationMs.\n * @type {!Object<string, number>|undefined}\n */\ngoog.net.WebChannel.Options.prototype.requestRefreshThresholds;\n\n/**\n * This is an experimental feature to use WHATWG Fetch/streams (when supported).\n * If a custom 'xmlHttpFactory' is speficied, this option will not be effective.\n * This option defaults to false now and will eventually be turned on by\n * default.\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.useFetchStreams;\n\n/**\n * Opt-in to enable Chrome origin trials from the WebChannel client. See\n * https://github.com/GoogleChrome/OriginTrials\n *\n * Origin trial history:\n * - fetch upload (11/2020 - 07/2021)\n * https://developers.chrome.com/origintrials/#/view_trial/3524066708417413121\n *\n * Participating in the origin trials will help Chrome to release new Web\n * platform features sooner, which will in turn help improve WebChannel\n * performance.\n *\n * Origin trials are not expected to interfere with WebChannel wire messages\n * and should not introduce any noticeable overhead.\n *\n * This is enabled by default with any on-going origin-trial.\n *\n * @type {boolean|undefined}\n */\ngoog.net.WebChannel.Options.prototype.enableOriginTrials;\n\n\n/**\n * Types that are allowed as message data.\n *\n * Note that JS objects (sent by the client) can only have string encoded\n * values due to the limitation of the current wire protocol.\n *\n * Unicode strings (sent by the server) may or may not need be escaped, as\n * decided by the server.\n *\n * @typedef {(!ArrayBuffer|!Blob|!Object<string, !Object|string>|!Array|string)}\n */\ngoog.net.WebChannel.MessageData;\n\n\n/**\n * Open the WebChannel against the URI specified in the constructor.\n */\ngoog.net.WebChannel.prototype.open = goog.abstractMethod;\n\n\n/**\n * Close the WebChannel.\n *\n * This is a full close (shutdown) with no guarantee of FIFO delivery in respect\n * to any in-flight messages sent to the server.\n *\n * If you need such a guarantee, see the Half the halfClose() method.\n */\ngoog.net.WebChannel.prototype.close = goog.abstractMethod;\n\n\n/**\n * Half-close the WebChannel.\n *\n * Half-close semantics:\n * 1. delivered as a regular message in FIFO programming order\n * 2. the server is expected to return a half-close too (with or without\n * application involved), which will trigger a full close (shutdown)\n * on the client side\n * 3. for now, the half-close event defined for server-initiated\n * half-close is not exposed to the client application\n * 4. a client-side half-close may be triggered internally when the client\n * receives a half-close from the server; and the client is expected to\n * do a full close after the half-close is acked and delivered\n * on the server-side.\n * 5. Full close is always a forced one. See the close() method.\n *\n * New messages sent after halfClose() will be dropped.\n *\n * NOTE: This is not yet implemented, and will throw an exception if called.\n */\ngoog.net.WebChannel.prototype.halfClose = goog.abstractMethod;\n\n\n/**\n * Sends a message to the server that maintains the other endpoint of\n * the WebChannel.\n *\n * O-RTT behavior:\n * 1. messages sent before open() is called will always be delivered as\n * part of the handshake, i.e. with 0-RTT\n * 2. messages sent after open() is called but before the OPEN event\n * is received will be delivered as part of the handshake if\n * send() is called from the same execution context as open().\n * 3. otherwise, those messages will be buffered till the handshake\n * is completed (which will fire the OPEN event).\n *\n * @param {!goog.net.WebChannel.MessageData} message The message to send.\n */\ngoog.net.WebChannel.prototype.send = goog.abstractMethod;\n\n\n/**\n * Common events fired by WebChannels.\n * @enum {string}\n */\ngoog.net.WebChannel.EventType = {\n /** Dispatched when the channel is opened. */\n OPEN: goog.events.getUniqueId('open'),\n\n /** Dispatched when the channel is closed. */\n CLOSE: goog.events.getUniqueId('close'),\n\n /**\n * Dispatched when the channel is aborted due to errors.\n *\n * For backward compatibility reasons, a CLOSE event will also be\n * dispatched, following the ERROR event, which indicates that the channel\n * has been completely shutdown .\n */\n ERROR: goog.events.getUniqueId('error'),\n\n /** Dispatched when the channel has received a new message. */\n MESSAGE: goog.events.getUniqueId('message')\n};\n\n\n\n/**\n * The event interface for the MESSAGE event.\n *\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.net.WebChannel.MessageEvent = function() {\n 'use strict';\n goog.net.WebChannel.MessageEvent.base(\n this, 'constructor', goog.net.WebChannel.EventType.MESSAGE);\n};\ngoog.inherits(goog.net.WebChannel.MessageEvent, goog.events.Event);\n\n\n/**\n * The content of the message received from the server.\n *\n * @type {!goog.net.WebChannel.MessageData}\n */\ngoog.net.WebChannel.MessageEvent.prototype.data;\n\n\n/**\n * The metadata key when the MESSAGE event represents a metadata message.\n *\n * @type {string|undefined}\n */\ngoog.net.WebChannel.MessageEvent.prototype.metadataKey;\n\n\n/**\n * Metadata as HTTP status code. Typically sent before the channel is\n * half-closed by the server.\n *\n * @type {number|undefined}\n */\ngoog.net.WebChannel.MessageEvent.prototype.statusCode;\n\n\n/**\n * Metadata as HTTP headers. Typically sent before the channel is\n * half-closed by the server.\n *\n * @type {!Object<string, string>|undefined}\n */\ngoog.net.WebChannel.MessageEvent.prototype.headers;\n\n\n/**\n * WebChannel level error conditions.\n *\n * Summary of error debugging and reporting in WebChannel:\n *\n * Network Error\n * 1. By default the webchannel library will set the error status to\n * NETWORK_ERROR when a channel has to be aborted or closed. NETWORK_ERROR\n * may be recovered by the application by retrying and opening a new channel.\n * 2. There may be lost messages (not acked by the server) when a channel is\n * aborted. Currently we don't have a public API to retrieve messages that\n * are waiting to be acked on the client side. File a bug if you think it\n * is useful to expose such an API.\n * 3. Details of why a channel fails are available via closure debug logs,\n * and stats events (see webchannel/requeststats.js). Those are internal\n * stats and are subject to change. File a bug if you think it's useful to\n * version and expose such stats as part of the WebChannel API.\n *\n * Server Error\n * 1. SERVER_ERROR is intended to indicate a non-recoverable condition, e.g.\n * when auth fails.\n * 2. We don't currently generate any such errors, because most of the time\n * it's the responsibility of upper-layer frameworks or the application\n * itself to indicate to the client why a webchannel has been failed\n * by the server.\n * 3. When a channel is failed by the server explicitly, we still signal\n * NETWORK_ERROR to the client. Explicit server failure may happen when the\n * server does a fail-over, or becomes overloaded, or conducts a forced\n * shutdown etc.\n * 4. We use some heuristic to decide if the network (aka cloud) is down\n * v.s. the actual server is down.\n *\n * RuntimeProperties.getLastStatusCode is a useful state that we expose to\n * the client to indicate the HTTP response status code of the last HTTP\n * request initiated by the WebChannel client library, for debugging\n * purposes only.\n *\n * See WebChannel.Options.backChannelFailureRecovery and\n * WebChannel.FailureRecovery to install a custom failure-recovery algorithm.\n *\n * @enum {number}\n */\ngoog.net.WebChannel.ErrorStatus = {\n /** No error has occurred. */\n OK: 0,\n\n /** Communication to the server has failed. */\n NETWORK_ERROR: 1,\n\n /** The server fails to accept or process the WebChannel. */\n SERVER_ERROR: 2\n};\n\n\n\n/**\n * The event interface for the ERROR event.\n *\n * @constructor\n * @extends {goog.events.Event}\n */\ngoog.net.WebChannel.ErrorEvent = function() {\n 'use strict';\n goog.net.WebChannel.ErrorEvent.base(\n this, 'constructor', goog.net.WebChannel.EventType.ERROR);\n};\ngoog.inherits(goog.net.WebChannel.ErrorEvent, goog.events.Event);\n\n\n/**\n * The error status.\n *\n * @type {!goog.net.WebChannel.ErrorStatus}\n */\ngoog.net.WebChannel.ErrorEvent.prototype.status;\n\n\n/**\n * @return {!goog.net.WebChannel.RuntimeProperties} The runtime properties\n * of the WebChannel instance.\n */\ngoog.net.WebChannel.prototype.getRuntimeProperties = goog.abstractMethod;\n\n\n\n/**\n * The runtime properties of the WebChannel instance.\n *\n * This class is defined for debugging and monitoring purposes, as well as for\n * runtime functions that the application may choose to manage by itself.\n *\n * @interface\n */\ngoog.net.WebChannel.RuntimeProperties = function() {};\n\n\n/**\n * @return {number} The effective limit for the number of concurrent HTTP\n * requests that are allowed to be made for sending messages from the client\n * to the server. When SPDY is not enabled, this limit will be one.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getConcurrentRequestLimit =\n goog.abstractMethod;\n\n\n/**\n * For applications that need support multiple channels (e.g. from\n * different tabs) to the same origin, use this method to decide if SPDY is\n * enabled and therefore it is safe to open multiple channels.\n *\n * If SPDY is disabled, the application may choose to limit the number of active\n * channels to one or use other means such as sub-domains to work around\n * the browser connection limit.\n *\n * @return {boolean} Whether SPDY is enabled for the origin against which\n * the channel is created.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.isSpdyEnabled =\n goog.abstractMethod;\n\n\n/**\n * @return {number} The number of requests (for sending messages to the server)\n * that are pending. If this number is approaching the value of\n * getConcurrentRequestLimit(), client-to-server message delivery may experience\n * a higher latency.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getPendingRequestCount =\n goog.abstractMethod;\n\n\n/**\n * For applications to query the current HTTP session id, sent by the server\n * during the initial handshake.\n *\n * @return {?string} the HTTP session id or null if no HTTP session is in use.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getHttpSessionId =\n goog.abstractMethod;\n\n\n/**\n * Experimental API.\n *\n * This method generates an in-band commit request to the server, which will\n * ack the commit request as soon as all messages sent prior to this commit\n * request have been committed by the application.\n *\n * Committing a message has a stronger semantics than delivering a message\n * to the application. Detail spec:\n * https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * Timeout or cancellation is not supported and the application is expected to\n * abort the channel if the commit-ack fails to arrive in time.\n *\n * ===\n *\n * This is currently implemented only in the client layer and the commit\n * callback will be invoked after all the pending client-sent messages have been\n * delivered by the server-side webchannel endpoint. This semantics is\n * different and weaker than what's required for end-to-end ack which requires\n * the server application to ack the in-order delivery of messages that are sent\n * before the commit request is issued.\n *\n * Commit should only be called after the channel open event is received.\n * Duplicated commits are allowed and only the last callback is guaranteed.\n * Commit called after the channel has been closed will be ignored.\n *\n * @param {function()} callback The callback will be invoked once an\n * ack has been received for the current commit or any newly issued commit.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.commit = goog.abstractMethod;\n\n\n/**\n * This method may be used by the application to recover from a peer failure\n * or to enable sender-initiated flow-control.\n *\n * Detail spec: https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * Note that the caller should NOT modify the list of returned messages.\n *\n * @return {!Array<!goog.net.WebChannel.MessageData>} The list of messages that\n * have not received commit-ack from the server; or if no commit has been\n * issued, the list of messages that have not been delivered to the server\n * application.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getNonAckedMessages =\n goog.abstractMethod;\n\n\n/**\n * A low water-mark message count to notify the application when the\n * flow-control condition is cleared, that is, when the application is\n * able to send more messages.\n *\n * We expect the application to configure a high water-mark message count,\n * which is checked via getNonAckedMessageCount(). When the high water-mark\n * is exceeded, the application should install a callback via this method\n * to be notified when to start to send new messages.\n *\n * This is not yet implemented.\n *\n * @param {number} count The low water-mark count. It is an error to pass\n * a non-positive value.\n * @param {function()} callback The call back to notify the application\n * when NonAckedMessageCount is below the specified low water-mark count.\n * Any previously registered callback is cleared. This new callback will\n * be cleared once it has been fired, or when the channel is closed or aborted.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.notifyNonAckedMessageCount =\n goog.abstractMethod;\n\n\n/**\n * Experimental API.\n *\n * This method registers a callback to handle the commit request sent\n * by the server. Commit protocol spec:\n * https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * This is not yet implemented.\n *\n * @param {function(!Object)} callback The callback will take an opaque\n * commitId which needs be passed back to the server when an ack-commit\n * response is generated by the client application, via ackCommit().\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.onCommit = goog.abstractMethod;\n\n\n/**\n * Experimental API.\n *\n * This method is used by the application to generate an ack-commit response\n * for the given commitId. Commit protocol spec:\n * https://github.com/bidiweb/webchannel/blob/master/commit.md\n *\n * This is not yet implemented.\n *\n * @param {!Object} commitId The commitId which denotes the commit request\n * from the server that needs be ack'ed.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.ackCommit = goog.abstractMethod;\n\n\n/**\n * Transport-metadata support.\n *\n * Responses from the channel-close (abort) message are not available.\n *\n * In future when client-side half-close is supported, its response headers\n * will be available via this API too.\n * @return {!Object<string, string>|undefined} The response headers received\n * with the non-200 HTTP status code that causes the channel to be aborted.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getLastResponseHeaders =\n goog.abstractMethod;\n\n/**\n * Transport-metadata support.\n *\n * TODO: getInitStatusCode (handshake)\n * TODO: getInitResponseHeaders (handshake)\n *\n * Note that response headers from client-initiated close (abort) are not\n * available.\n *\n * In future when client-initiated half-close is supported, its response status\n * will be available via this API.\n *\n * @return {number} The non-200 HTTP status code received that causes the\n * channel to be aborted.\n */\ngoog.net.WebChannel.RuntimeProperties.prototype.getLastStatusCode =\n goog.abstractMethod;\n\n\n/**\n * Enum to indicate the current recovery state.\n *\n * @enum {string}\n */\ngoog.net.WebChannel.FailureRecovery.State = {\n /** Initial state. */\n INIT: 'init',\n\n /** Once a failure has been detected. */\n FAILED: 'failed',\n\n /**\n * Once a recovery operation has been issued, e.g. a new request to resume\n * communication.\n */\n RECOVERING: 'recovering',\n\n /** The channel has been closed. */\n CLOSED: 'closed'\n};\n\n\n/**\n * Enum to indicate different failure conditions as detected by the webchannel\n * runtime.\n *\n * This enum is to be used only between the runtime and FailureRecovery module,\n * and new states are expected to be introduced in future.\n *\n * @enum {string}\n */\ngoog.net.WebChannel.FailureRecovery.FailureCondition = {\n /**\n * The HTTP response returned a non-successful http status code.\n */\n HTTP_ERROR: 'http_error',\n\n /**\n * The request was aborted.\n */\n ABORT: 'abort',\n\n /**\n * The request timed out.\n */\n TIMEOUT: 'timeout',\n\n /**\n * Exception was thrown while processing the request/response.\n */\n EXCEPTION: 'exception'\n};\n\n\n/**\n * @return {!goog.net.WebChannel.FailureRecovery.State} the current state,\n * mainly for debugging use.\n */\ngoog.net.WebChannel.FailureRecovery.prototype.getState = goog.abstractMethod;\n\n\n/**\n * This method is for WebChannel runtime to set the current failure condition\n * and to provide a callback for the algorithm to signal to the runtime\n * when it is time to issue a recovery operation, e.g. a new request to the\n * server.\n *\n * Supported transitions include:\n * INIT->FAILED\n * FAILED->FAILED (re-entry ok)\n * RECOVERY->FAILED.\n *\n * Ignored if state == CLOSED.\n *\n * Advanced implementations are expected to track all the state transitions\n * and their timestamps for monitoring purposes.\n *\n * @param {!goog.net.WebChannel.FailureRecovery.FailureCondition} failure The\n * new failure condition generated by the WebChannel runtime.\n * @param {!Function} operation The callback function to the WebChannel\n * runtime to issue a recovery operation, e.g. a new request. E.g. the default\n * recovery algorithm will issue timeout-based recovery operations.\n * Post-condition for the callback: state transition to RECOVERING.\n *\n * @return {!goog.net.WebChannel.FailureRecovery.State} The updated state\n * as decided by the failure recovery module. Upon a recoverable failure event,\n * the state is transitioned to RECOVERING; or the state is transitioned to\n * FAILED which indicates a fail-fast decision for the runtime to execute.\n */\ngoog.net.WebChannel.FailureRecovery.prototype.setFailure = goog.abstractMethod;\n\n\n/**\n * The Webchannel runtime needs call this method when webchannel is closed or\n * aborted.\n *\n * Once the instance is closed, any access to the instance will be a no-op.\n */\ngoog.net.WebChannel.FailureRecovery.prototype.close = goog.abstractMethod;\n\n\n/**\n * A request header to indicate to the server the messaging protocol\n * each HTTP message is speaking.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_CLIENT_PROTOCOL = 'X-Client-Protocol';\n\n\n/**\n * The value for x-client-protocol when the messaging protocol is WebChannel.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL = 'webchannel';\n\n\n/**\n * A response header for the server to signal the wire-protocol that\n * the browser establishes with the server (or proxy), e.g. \"spdy\" (aka http/2)\n * \"quic\". This information avoids the need to use private APIs to decide if\n * HTTP requests are multiplexed etc.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_CLIENT_WIRE_PROTOCOL = 'X-Client-Wire-Protocol';\n\n\n/**\n * A response header for the server to send back the HTTP session id as part of\n * the initial handshake. The value of the HTTP session id is opaque to the\n * WebChannel protocol.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_HTTP_SESSION_ID = 'X-HTTP-Session-Id';\n\n\n/**\n * A response header for the server to send back any initial response data as a\n * header to avoid any possible buffering by an intermediary, which may\n * be undesired during the handshake.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_HTTP_INITIAL_RESPONSE = 'X-HTTP-Initial-Response';\n\n\n/**\n * A request header for specifying the content-type of WebChannel messages,\n * e.g. application-defined JSON encoding styles. Currently this header\n * is sent by the client via initMessageHeaders when the channel is opened.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE = 'X-WebChannel-Content-Type';\n\n\n/**\n * A request header for specifying the client profile in order to apply\n * customized config params on the server side, e.g. timeouts.\n *\n * @type {string}\n */\ngoog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE = 'X-WebChannel-Client-Profile';\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Low level handling of XMLHttpRequest.\n */\n\ngoog.provide('goog.net.DefaultXmlHttpFactory');\ngoog.provide('goog.net.XmlHttp');\ngoog.provide('goog.net.XmlHttp.OptionType');\ngoog.provide('goog.net.XmlHttp.ReadyState');\ngoog.provide('goog.net.XmlHttpDefines');\n\ngoog.require('goog.asserts');\ngoog.require('goog.net.WrapperXmlHttpFactory');\ngoog.require('goog.net.XmlHttpFactory');\ngoog.requireType('goog.net.XhrLike');\n\n\n/**\n * Static class for creating XMLHttpRequest objects.\n * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object.\n */\ngoog.net.XmlHttp = function() {\n 'use strict';\n return goog.net.XmlHttp.factory_.createInstance();\n};\n\n\n/**\n * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to\n * true bypasses the ActiveX probing code.\n * NOTE(ruilopes): Due to the way JSCompiler works, this define *will not* strip\n * out the ActiveX probing code from binaries. To achieve this, use\n * `goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR` instead.\n * TODO(ruilopes): Collapse both defines.\n */\ngoog.net.XmlHttp.ASSUME_NATIVE_XHR =\n goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false);\n\n\n/** @const */\ngoog.net.XmlHttpDefines = {};\n\n\n/**\n * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to\n * true eliminates the ActiveX probing code.\n */\ngoog.net.XmlHttpDefines.ASSUME_NATIVE_XHR =\n goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false);\n\n\n/**\n * Gets the options to use with the XMLHttpRequest objects obtained using\n * the static methods.\n * @return {Object} The options.\n */\ngoog.net.XmlHttp.getOptions = function() {\n 'use strict';\n return goog.net.XmlHttp.factory_.getOptions();\n};\n\n\n/**\n * Type of options that an XmlHttp object can have.\n * @enum {number}\n */\ngoog.net.XmlHttp.OptionType = {\n /**\n * Whether a no-op function should be used to clear the onreadystatechange\n * handler instead of null.\n */\n USE_NULL_FUNCTION: 0,\n\n /**\n * NOTE(user): In IE if send() errors on a *local* request the readystate\n * is still changed to COMPLETE. We need to ignore it and allow the\n * try/catch around send() to pick up the error.\n */\n LOCAL_REQUEST_ERROR: 1,\n};\n\n\n/**\n * Status constants for XMLHTTP, matches:\n * https://msdn.microsoft.com/en-us/library/ms534361(v=vs.85).aspx\n * @enum {number}\n */\ngoog.net.XmlHttp.ReadyState = {\n /**\n * Constant for when xmlhttprequest.readyState is uninitialized\n */\n UNINITIALIZED: 0,\n\n /**\n * Constant for when xmlhttprequest.readyState is loading.\n */\n LOADING: 1,\n\n /**\n * Constant for when xmlhttprequest.readyState is loaded.\n */\n LOADED: 2,\n\n /**\n * Constant for when xmlhttprequest.readyState is in an interactive state.\n */\n INTERACTIVE: 3,\n\n /**\n * Constant for when xmlhttprequest.readyState is completed\n */\n COMPLETE: 4,\n};\n\n\n/**\n * The global factory instance for creating XMLHttpRequest objects.\n * @type {goog.net.XmlHttpFactory}\n * @private\n */\ngoog.net.XmlHttp.factory_;\n\n\n/**\n * Sets the factories for creating XMLHttpRequest objects and their options.\n * @param {Function} factory The factory for XMLHttpRequest objects.\n * @param {Function} optionsFactory The factory for options.\n * @deprecated Use setGlobalFactory instead.\n */\ngoog.net.XmlHttp.setFactory = function(factory, optionsFactory) {\n 'use strict';\n goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(\n goog.asserts.assert(factory), goog.asserts.assert(optionsFactory)));\n};\n\n\n/**\n * Sets the global factory object.\n * @param {!goog.net.XmlHttpFactory} factory New global factory object.\n */\ngoog.net.XmlHttp.setGlobalFactory = function(factory) {\n 'use strict';\n goog.net.XmlHttp.factory_ = factory;\n};\n\n\n\n/**\n * Default factory to use when creating xhr objects. You probably shouldn't be\n * instantiating this directly, but rather using it via goog.net.XmlHttp.\n * @extends {goog.net.XmlHttpFactory}\n * @constructor\n */\ngoog.net.DefaultXmlHttpFactory = function() {\n 'use strict';\n goog.net.XmlHttpFactory.call(this);\n};\ngoog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.DefaultXmlHttpFactory.prototype.createInstance = function() {\n 'use strict';\n const progId = this.getProgId_();\n if (progId) {\n return new ActiveXObject(progId);\n } else {\n return new XMLHttpRequest();\n }\n};\n\n\n/** @override */\ngoog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {\n 'use strict';\n const progId = this.getProgId_();\n const options = {};\n if (progId) {\n options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true;\n options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true;\n }\n return options;\n};\n\n\n/**\n * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.\n * @type {string|undefined}\n * @private\n */\ngoog.net.DefaultXmlHttpFactory.prototype.ieProgId_;\n\n\n/**\n * Initialize the private state used by other functions.\n * @return {string} The ActiveX PROG ID string to use to create xhr's in IE.\n * @private\n */\ngoog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {\n 'use strict';\n if (goog.net.XmlHttp.ASSUME_NATIVE_XHR ||\n goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) {\n return '';\n }\n\n // The following blog post describes what PROG IDs to use to create the\n // XMLHTTP object in Internet Explorer:\n // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx\n // However we do not (yet) fully trust that this will be OK for old versions\n // of IE on Win9x so we therefore keep the last 2.\n if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' &&\n typeof ActiveXObject != 'undefined') {\n // Candidate Active X types.\n const ACTIVE_X_IDENTS = [\n 'MSXML2.XMLHTTP.6.0',\n 'MSXML2.XMLHTTP.3.0',\n 'MSXML2.XMLHTTP',\n 'Microsoft.XMLHTTP',\n ];\n for (let i = 0; i < ACTIVE_X_IDENTS.length; i++) {\n const candidate = ACTIVE_X_IDENTS[i];\n\n try {\n new ActiveXObject(candidate);\n // NOTE(user): cannot assign progid and return candidate in one line\n // because JSCompiler complaings: BUG 658126\n this.ieProgId_ = candidate;\n return candidate;\n } catch (e) {\n // do nothing; try next choice\n }\n }\n\n // couldn't find any matches\n throw new Error(\n 'Could not create ActiveXObject. ActiveX might be disabled,' +\n ' or MSXML might not be installed');\n }\n\n return /** @type {string} */ (this.ieProgId_);\n};\n\n\n// Set the global factory to an instance of the default factory.\ngoog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory());\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the ChannelRequest class. The request\n * object encapsulates the logic for making a single request, either for the\n * forward channel, back channel, or test channel, to the server. It contains\n * the logic for the two types of transports we use:\n * XMLHTTP and Image request. It provides timeout detection. More transports\n * to be added in future, such as Fetch, WebSocket.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.ChannelRequest');\n\ngoog.require('goog.Timer');\ngoog.require('goog.asserts');\ngoog.require('goog.async.Throttle');\ngoog.require('goog.dispose');\ngoog.require('goog.events.EventHandler');\ngoog.require('goog.labs.net.webChannel.Channel');\ngoog.require('goog.labs.net.webChannel.WebChannelDebug');\ngoog.require('goog.labs.net.webChannel.environment');\ngoog.require('goog.labs.net.webChannel.requestStats');\ngoog.require('goog.net.ErrorCode');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.Uri');\ngoog.requireType('goog.events.Event');\ngoog.requireType('goog.labs.net.webChannel.Wire.QueuedMap');\ngoog.requireType('goog.net.XhrIo');\n\n\n\n/**\n * A new ChannelRequest is created for each request to the server.\n *\n * @param {goog.labs.net.webChannel.Channel} channel\n * The channel that owns this request.\n * @param {goog.labs.net.webChannel.WebChannelDebug} channelDebug A\n * WebChannelDebug to use for logging.\n * @param {string=} opt_sessionId The session id for the channel.\n * @param {string|number=} opt_requestId The request id for this request.\n * @param {number=} opt_retryId The retry id for this request.\n * @constructor\n * @struct\n * @final\n */\ngoog.labs.net.webChannel.ChannelRequest = function(\n channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {\n 'use strict';\n /**\n * The channel object that owns the request.\n * @private {goog.labs.net.webChannel.Channel}\n */\n this.channel_ = channel;\n\n /**\n * The channel debug to use for logging\n * @private {goog.labs.net.webChannel.WebChannelDebug}\n */\n this.channelDebug_ = channelDebug;\n\n /**\n * The Session ID for the channel.\n * @private {string|undefined}\n */\n this.sid_ = opt_sessionId;\n\n /**\n * The RID (request ID) for the request.\n * @private {string|number|undefined}\n */\n this.rid_ = opt_requestId;\n\n /**\n * The attempt number of the current request.\n * @private {number}\n */\n this.retryId_ = opt_retryId || 1;\n\n /**\n * An object to keep track of the channel request event listeners.\n * @private {!goog.events.EventHandler<\n * !goog.labs.net.webChannel.ChannelRequest>}\n */\n this.eventHandler_ = new goog.events.EventHandler(this);\n\n /**\n * The timeout in ms before failing the request.\n * @private {number}\n */\n this.timeout_ = goog.labs.net.webChannel.ChannelRequest.TIMEOUT_MS_;\n\n /**\n * A timer for polling responseText in browsers that don't fire\n * onreadystatechange during incremental loading of responseText.\n * @private {goog.Timer}\n */\n this.pollingTimer_ =\n new goog.Timer(goog.labs.net.webChannel.environment.getPollingInterval());\n\n /**\n * Extra HTTP headers to add to all the requests sent to the server.\n * @private {?Object}\n */\n this.extraHeaders_ = null;\n\n\n /**\n * Whether the request was successful. This is only set to true after the\n * request successfully completes.\n * @private {boolean}\n */\n this.successful_ = false;\n\n\n /**\n * The TimerID of the timer used to detect if the request has timed-out.\n * @type {?number}\n * @private\n */\n this.watchDogTimerId_ = null;\n\n /**\n * The time in the future when the request will timeout.\n * @private {?number}\n */\n this.watchDogTimeoutTime_ = null;\n\n /**\n * The time the request started.\n * @private {?number}\n */\n this.requestStartTime_ = null;\n\n /**\n * The type of request (XMLHTTP, IMG)\n * @private {?number}\n */\n this.type_ = null;\n\n /**\n * The base Uri for the request. The includes all the parameters except the\n * one that indicates the retry number.\n * @private {?goog.Uri}\n */\n this.baseUri_ = null;\n\n /**\n * The request Uri that was actually used for the most recent request attempt.\n * @private {?goog.Uri}\n */\n this.requestUri_ = null;\n\n /**\n * The post data, if the request is a post.\n * @private {?string}\n */\n this.postData_ = null;\n\n /**\n * An array of pending messages that we have either received a non-successful\n * response for, or no response at all, and which therefore may or may not\n * have been received by the server.\n * @private {!Array<goog.labs.net.webChannel.Wire.QueuedMap>}\n */\n this.pendingMessages_ = [];\n\n /**\n * The XhrLte request if the request is using XMLHTTP\n * @private {?goog.net.XhrIo}\n */\n this.xmlHttp_ = null;\n\n /**\n * The position of where the next unprocessed chunk starts in the response\n * text.\n * @private {number}\n */\n this.xmlHttpChunkStart_ = 0;\n\n /**\n * The verb (Get or Post) for the request.\n * @private {?string}\n */\n this.verb_ = null;\n\n /**\n * The last error if the request failed.\n * @private {?goog.labs.net.webChannel.ChannelRequest.Error}\n */\n this.lastError_ = null;\n\n /**\n * The response headers received along with the non-200 status.\n *\n * @private {!Object<string, string>|undefined}\n */\n this.errorResponseHeaders_ = undefined;\n\n /**\n * The last status code received.\n * @private {number}\n */\n this.lastStatusCode_ = -1;\n\n /**\n * Whether the request has been cancelled due to a call to cancel.\n * @private {boolean}\n */\n this.cancelled_ = false;\n\n /**\n * A throttle time in ms for readystatechange events for the backchannel.\n * Useful for throttling when ready state is INTERACTIVE (partial data).\n * If set to zero no throttle is used.\n *\n * See WebChannelBase.prototype.readyStateChangeThrottleMs_\n *\n * @private {number}\n */\n this.readyStateChangeThrottleMs_ = 0;\n\n /**\n * The throttle for readystatechange events for the current request, or null\n * if there is none.\n * @private {?goog.async.Throttle}\n */\n this.readyStateChangeThrottle_ = null;\n\n /**\n * Whether to the result is expected to be encoded for chunking and thus\n * requires decoding.\n * @private {boolean}\n */\n this.decodeChunks_ = false;\n\n /**\n * Whether to decode x-http-initial-response.\n * @private {boolean}\n */\n this.decodeInitialResponse_ = false;\n\n /**\n * Whether x-http-initial-response has been decoded (dispatched).\n * @private {boolean}\n */\n this.initialResponseDecoded_ = false;\n\n /**\n * Whether the first byte of response body has arrived, for a successful\n * response.\n * @private {boolean}\n */\n this.firstByteReceived_ = false;\n\n /**\n * The current state of fetch responses if webchannel is using WHATWG\n * fetch/streams.\n * @private {!goog.labs.net.webChannel.FetchResponseState}\n */\n this.fetchResponseState_ = new goog.labs.net.webChannel.FetchResponseState();\n};\n\n/**\n * A collection of fetch/stream properties.\n * @struct\n * @constructor\n */\ngoog.labs.net.webChannel.FetchResponseState = function() {\n 'use strict';\n /**\n * The TextDecoder for decoding Uint8Array responses from fetch request.\n * @type {?goog.global.TextDecoder}\n */\n this.textDecoder = null;\n\n /**\n * The unconsumed response text from the fetch requests.\n * @type {string}\n */\n this.responseBuffer = '';\n\n /**\n * Whether or not the response body has arrived.\n * @type {boolean}\n */\n this.responseArrivedForFetch = false;\n};\n\n\ngoog.scope(function() {\n'use strict';\nconst WebChannel = goog.net.WebChannel;\nconst Channel = goog.labs.net.webChannel.Channel;\nconst ChannelRequest = goog.labs.net.webChannel.ChannelRequest;\nconst FetchResponseState = goog.labs.net.webChannel.FetchResponseState;\nconst requestStats = goog.labs.net.webChannel.requestStats;\nconst WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\nconst environment = goog.labs.net.webChannel.environment;\n\n/**\n * Default timeout in MS for a request. The server must return data within this\n * time limit for the request to not timeout.\n * @private {number}\n */\nChannelRequest.TIMEOUT_MS_ = 45 * 1000;\n\n\n/**\n * Enum for channel requests type\n * @enum {number}\n * @private\n */\nChannelRequest.Type_ = {\n /**\n * XMLHTTP requests.\n */\n XML_HTTP: 1,\n\n /**\n * IMG requests.\n */\n CLOSE_REQUEST: 2\n};\n\n\n/**\n * Enum type for identifying an error.\n * @enum {number}\n */\nChannelRequest.Error = {\n /**\n * Errors due to a non-200 status code.\n */\n STATUS: 0,\n\n /**\n * Errors due to no data being returned.\n */\n NO_DATA: 1,\n\n /**\n * Errors due to a timeout.\n */\n TIMEOUT: 2,\n\n /**\n * Errors due to the server returning an unknown.\n */\n UNKNOWN_SESSION_ID: 3,\n\n /**\n * Errors due to bad data being received.\n */\n BAD_DATA: 4,\n\n /**\n * Errors due to the handler throwing an exception.\n */\n HANDLER_EXCEPTION: 5,\n\n /**\n * The browser declared itself offline during the request.\n */\n BROWSER_OFFLINE: 6\n};\n\n\n/**\n * Returns a useful error string for debugging based on the specified error\n * code.\n * @param {?ChannelRequest.Error} errorCode The error code.\n * @param {number} statusCode The HTTP status code.\n * @return {string} The error string for the given code combination.\n */\nChannelRequest.errorStringFromCode = function(errorCode, statusCode) {\n 'use strict';\n switch (errorCode) {\n case ChannelRequest.Error.STATUS:\n return 'Non-200 return code (' + statusCode + ')';\n case ChannelRequest.Error.NO_DATA:\n return 'XMLHTTP failure (no data)';\n case ChannelRequest.Error.TIMEOUT:\n return 'HttpConnection timeout';\n default:\n return 'Unknown error';\n }\n};\n\n\n/**\n * Sentinel value used to indicate an invalid chunk in a multi-chunk response.\n * @private {!Object}\n */\nChannelRequest.INVALID_CHUNK_ = {};\n\n\n/**\n * Sentinel value used to indicate an incomplete chunk in a multi-chunk\n * response.\n * @private {!Object}\n */\nChannelRequest.INCOMPLETE_CHUNK_ = {};\n\n\n/**\n * Returns whether XHR streaming is supported on this browser.\n *\n * @return {boolean} Whether XHR streaming is supported.\n * @see http://code.google.com/p/closure-library/issues/detail?id=346\n */\nChannelRequest.supportsXhrStreaming = function() {\n 'use strict';\n return !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(10);\n};\n\n\n/**\n * Sets extra HTTP headers to add to all the requests sent to the server.\n *\n * @param {Object} extraHeaders The HTTP headers.\n */\nChannelRequest.prototype.setExtraHeaders = function(extraHeaders) {\n 'use strict';\n this.extraHeaders_ = extraHeaders;\n};\n\n\n/**\n * Overrides the default HTTP method.\n *\n * @param {string} verb The HTTP method\n */\nChannelRequest.prototype.setVerb = function(verb) {\n 'use strict';\n this.verb_ = verb;\n};\n\n\n/**\n * Sets the timeout for a request\n *\n * @param {number} timeout The timeout in MS for when we fail the request.\n */\nChannelRequest.prototype.setTimeout = function(timeout) {\n 'use strict';\n this.timeout_ = timeout;\n};\n\n\n/**\n * Sets the throttle for handling onreadystatechange events for the request.\n *\n * @param {number} throttle The throttle in ms. A value of zero indicates\n * no throttle.\n */\nChannelRequest.prototype.setReadyStateChangeThrottle = function(throttle) {\n 'use strict';\n this.readyStateChangeThrottleMs_ = throttle;\n};\n\n\n/**\n * Sets the pending messages that this request is handling.\n *\n * @param {!Array<goog.labs.net.webChannel.Wire.QueuedMap>} pendingMessages\n * The pending messages for this request.\n */\nChannelRequest.prototype.setPendingMessages = function(pendingMessages) {\n 'use strict';\n this.pendingMessages_ = pendingMessages;\n};\n\n\n/**\n * Gets the pending messages that this request is handling, in case of a retry.\n *\n * @return {!Array<goog.labs.net.webChannel.Wire.QueuedMap>} The pending\n * messages for this request.\n */\nChannelRequest.prototype.getPendingMessages = function() {\n 'use strict';\n return this.pendingMessages_;\n};\n\n\n/**\n * Uses XMLHTTP to send an HTTP POST to the server.\n *\n * @param {goog.Uri} uri The uri of the request.\n * @param {?string} postData The data for the post body.\n * @param {boolean} decodeChunks Whether to the result is expected to be\n * encoded for chunking and thus requires decoding.\n */\nChannelRequest.prototype.xmlHttpPost = function(uri, postData, decodeChunks) {\n 'use strict';\n this.type_ = ChannelRequest.Type_.XML_HTTP;\n this.baseUri_ = uri.clone().makeUnique();\n this.postData_ = postData;\n this.decodeChunks_ = decodeChunks;\n this.sendXmlHttp_(null /* hostPrefix */);\n};\n\n\n/**\n * Uses XMLHTTP to send an HTTP GET to the server.\n *\n * @param {goog.Uri} uri The uri of the request.\n * @param {boolean} decodeChunks Whether to the result is expected to be\n * encoded for chunking and thus requires decoding.\n * @param {?string} hostPrefix The host prefix, if we might be using a\n * secondary domain. Note that it should also be in the URL, adding this\n * won't cause it to be added to the URL.\n */\nChannelRequest.prototype.xmlHttpGet = function(uri, decodeChunks, hostPrefix) {\n 'use strict';\n this.type_ = ChannelRequest.Type_.XML_HTTP;\n this.baseUri_ = uri.clone().makeUnique();\n this.postData_ = null;\n this.decodeChunks_ = decodeChunks;\n\n this.sendXmlHttp_(hostPrefix);\n};\n\n\n/**\n * Sends a request via XMLHTTP according to the current state of the request\n * object.\n *\n * @param {?string} hostPrefix The host prefix, if we might be using a secondary\n * domain.\n * @private\n */\nChannelRequest.prototype.sendXmlHttp_ = function(hostPrefix) {\n 'use strict';\n this.requestStartTime_ = Date.now();\n this.ensureWatchDogTimer_();\n\n // clone the base URI to create the request URI. The request uri has the\n // attempt number as a parameter which helps in debugging.\n this.requestUri_ = this.baseUri_.clone();\n this.requestUri_.setParameterValues('t', this.retryId_);\n\n // send the request either as a POST or GET\n this.xmlHttpChunkStart_ = 0;\n const useSecondaryDomains = this.channel_.shouldUseSecondaryDomains();\n this.fetchResponseState_ = new FetchResponseState();\n // If the request is a GET request, start a backchannel to transfer streaming\n // data. Note that WebChannel GET request can also be used for closing the\n // channel as in method ChannelRequest#sendCloseRequest.\n // The second parameter of Channel#createXhrIo is JS only.\n this.xmlHttp_ = this.channel_.createXhrIo(\n useSecondaryDomains ? hostPrefix : null, !this.postData_);\n\n if (this.readyStateChangeThrottleMs_ > 0) {\n this.readyStateChangeThrottle_ = new goog.async.Throttle(\n goog.bind(this.xmlHttpHandler_, this, this.xmlHttp_),\n this.readyStateChangeThrottleMs_);\n }\n\n this.eventHandler_.listen(\n this.xmlHttp_, goog.net.EventType.READY_STATE_CHANGE,\n this.readyStateChangeHandler_);\n\n const headers =\n this.extraHeaders_ ? goog.object.clone(this.extraHeaders_) : {};\n if (this.postData_) {\n if (!this.verb_) {\n this.verb_ = 'POST';\n }\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n this.xmlHttp_.send(this.requestUri_, this.verb_, this.postData_, headers);\n } else {\n this.verb_ = 'GET';\n this.xmlHttp_.send(this.requestUri_, this.verb_, null, headers);\n }\n requestStats.notifyServerReachabilityEvent(\n requestStats.ServerReachability.REQUEST_MADE);\n this.channelDebug_.xmlHttpChannelRequest(\n this.verb_, this.requestUri_, this.rid_, this.retryId_, this.postData_);\n};\n\n\n/**\n * Handles a readystatechange event.\n * @param {goog.events.Event} evt The event.\n * @private\n */\nChannelRequest.prototype.readyStateChangeHandler_ = function(evt) {\n 'use strict';\n const xhr = /** @type {goog.net.XhrIo} */ (evt.target);\n const throttle = this.readyStateChangeThrottle_;\n if (throttle &&\n xhr.getReadyState() == goog.net.XmlHttp.ReadyState.INTERACTIVE) {\n // Only throttle in the partial data case.\n this.channelDebug_.debug('Throttling readystatechange.');\n throttle.fire();\n } else {\n // If we haven't throttled, just handle response directly.\n this.xmlHttpHandler_(xhr);\n }\n};\n\n\n/**\n * XmlHttp handler\n * @param {goog.net.XhrIo} xmlhttp The XhrIo object for the current request.\n * @private\n */\nChannelRequest.prototype.xmlHttpHandler_ = function(xmlhttp) {\n 'use strict';\n requestStats.onStartExecution();\n\n try {\n if (xmlhttp == this.xmlHttp_) {\n this.onXmlHttpReadyStateChanged_();\n } else {\n this.channelDebug_.warning(\n 'Called back with an ' +\n 'unexpected xmlhttp');\n }\n } catch (ex) {\n this.channelDebug_.debug('Failed call to OnXmlHttpReadyStateChanged_');\n if (this.hasResponseBody_()) {\n const channelRequest = this;\n this.channelDebug_.dumpException(ex, function() {\n 'use strict';\n return 'ResponseText: ' + channelRequest.xmlHttp_.getResponseText();\n });\n } else {\n this.channelDebug_.dumpException(ex, 'No response text');\n }\n } finally {\n requestStats.onEndExecution();\n }\n};\n\n\n/**\n * Called by the readystate handler for XMLHTTP requests.\n *\n * @private\n */\nChannelRequest.prototype.onXmlHttpReadyStateChanged_ = function() {\n 'use strict';\n const readyState = this.xmlHttp_.getReadyState();\n const errorCode = this.xmlHttp_.getLastErrorCode();\n const statusCode = this.xmlHttp_.getStatus();\n\n // we get partial results in browsers that support ready state interactive.\n // We also make sure that getResponseText is not null in interactive mode\n // before we continue.\n if (readyState < goog.net.XmlHttp.ReadyState.INTERACTIVE ||\n (readyState == goog.net.XmlHttp.ReadyState.INTERACTIVE &&\n !environment.isPollingRequired() && // otherwise, go on to startPolling\n !this.hasResponseBody_())) {\n return; // not yet ready\n }\n\n // Dispatch any appropriate network events.\n if (!this.cancelled_ && readyState == goog.net.XmlHttp.ReadyState.COMPLETE &&\n errorCode != goog.net.ErrorCode.ABORT) {\n // Pretty conservative, these are the only known scenarios which we'd\n // consider indicative of a truly non-functional network connection.\n if (errorCode == goog.net.ErrorCode.TIMEOUT || statusCode <= 0) {\n requestStats.notifyServerReachabilityEvent(\n requestStats.ServerReachability.REQUEST_FAILED);\n } else {\n requestStats.notifyServerReachabilityEvent(\n requestStats.ServerReachability.REQUEST_SUCCEEDED);\n }\n }\n\n // got some data so cancel the watchdog timer\n this.cancelWatchDogTimer_();\n\n const status = this.xmlHttp_.getStatus();\n this.lastStatusCode_ = status;\n const responseText = this.decodeXmlHttpResponse_();\n\n if (!this.hasResponseBody_()) {\n const channelRequest = this;\n this.channelDebug_.debug(function() {\n 'use strict';\n return 'No response text for uri ' + channelRequest.requestUri_ +\n ' status ' + status;\n });\n }\n this.successful_ = (status == 200);\n\n this.channelDebug_.xmlHttpChannelResponseMetaData(\n /** @type {string} */ (this.verb_), this.requestUri_, this.rid_,\n this.retryId_, readyState, status);\n\n if (!this.successful_) {\n this.errorResponseHeaders_ = this.xmlHttp_.getResponseHeaders();\n if (status == 400 && responseText.indexOf('Unknown SID') > 0) {\n // the server error string will include 'Unknown SID' which indicates the\n // server doesn't know about the session (maybe it got restarted, maybe\n // the user got moved to another server, etc.,). Handlers can special\n // case this error\n this.lastError_ = ChannelRequest.Error.UNKNOWN_SESSION_ID;\n requestStats.notifyStatEvent(\n requestStats.Stat.REQUEST_UNKNOWN_SESSION_ID);\n this.channelDebug_.warning('XMLHTTP Unknown SID (' + this.rid_ + ')');\n } else {\n this.lastError_ = ChannelRequest.Error.STATUS;\n requestStats.notifyStatEvent(requestStats.Stat.REQUEST_BAD_STATUS);\n this.channelDebug_.warning(\n 'XMLHTTP Bad status ' + status + ' (' + this.rid_ + ')');\n }\n this.cleanup_();\n this.dispatchFailure_();\n return;\n }\n\n if (this.shouldCheckInitialResponse_()) {\n const initialResponse = this.getInitialResponse_();\n if (initialResponse) {\n this.channelDebug_.xmlHttpChannelResponseText(\n this.rid_, initialResponse,\n 'Initial handshake response via ' +\n WebChannel.X_HTTP_INITIAL_RESPONSE);\n this.initialResponseDecoded_ = true;\n this.safeOnRequestData_(initialResponse);\n } else {\n this.successful_ = false;\n this.lastError_ = ChannelRequest.Error.UNKNOWN_SESSION_ID; // fail-fast\n requestStats.notifyStatEvent(\n requestStats.Stat.REQUEST_UNKNOWN_SESSION_ID);\n this.channelDebug_.warning(\n 'XMLHTTP Missing X_HTTP_INITIAL_RESPONSE' +\n ' (' + this.rid_ + ')');\n this.cleanup_();\n this.dispatchFailure_();\n return;\n }\n }\n\n if (this.decodeChunks_) {\n this.decodeNextChunks_(readyState, responseText);\n if (environment.isPollingRequired() && this.successful_ &&\n readyState == goog.net.XmlHttp.ReadyState.INTERACTIVE) {\n this.startPolling_();\n }\n } else {\n this.channelDebug_.xmlHttpChannelResponseText(\n this.rid_, responseText, null);\n this.safeOnRequestData_(responseText);\n }\n\n if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {\n this.cleanup_();\n }\n\n if (!this.successful_) {\n return;\n }\n\n if (!this.cancelled_) {\n if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {\n this.channel_.onRequestComplete(this);\n } else {\n // The default is false, the result from this callback shouldn't carry\n // over to the next callback, otherwise the request looks successful if\n // the watchdog timer gets called\n this.successful_ = false;\n this.ensureWatchDogTimer_();\n }\n }\n};\n\n\n/**\n * Whether we need check the initial-response header that is sent during the\n * fast handshake.\n *\n * @return {boolean} true if the initial-response header is yet to be processed.\n * @private\n */\nChannelRequest.prototype.shouldCheckInitialResponse_ = function() {\n 'use strict';\n return this.decodeInitialResponse_ && !this.initialResponseDecoded_;\n};\n\n\n/**\n * Queries the initial response header that is sent during the handshake.\n *\n * @return {?string} The non-empty header value or null.\n * @private\n */\nChannelRequest.prototype.getInitialResponse_ = function() {\n 'use strict';\n if (this.xmlHttp_) {\n const value = this.xmlHttp_.getStreamingResponseHeader(\n WebChannel.X_HTTP_INITIAL_RESPONSE);\n if (value && !goog.string.isEmptyOrWhitespace(value)) {\n return value;\n }\n }\n\n return null;\n};\n\n\n/**\n * Check if the initial response header has been handled.\n *\n * @return {boolean} true if X_HTTP_INITIAL_RESPONSE has been handled.\n */\nChannelRequest.prototype.isInitialResponseDecoded = function() {\n 'use strict';\n return this.initialResponseDecoded_;\n};\n\n\n/**\n * Decodes X_HTTP_INITIAL_RESPONSE if present.\n */\nChannelRequest.prototype.setDecodeInitialResponse = function() {\n 'use strict';\n this.decodeInitialResponse_ = true;\n};\n\n\n\n/**\n * Decodes the responses from XhrIo object.\n * @returns {string} responseText\n * @private\n */\nChannelRequest.prototype.decodeXmlHttpResponse_ = function() {\n 'use strict';\n if (!this.useFetchStreamsForResponse_()) {\n return this.xmlHttp_.getResponseText();\n }\n const responseChunks =\n /** @type {!Array<!Uint8Array>} */ (this.xmlHttp_.getResponse());\n let responseText = '';\n const responseLength = responseChunks.length;\n const requestCompleted =\n this.xmlHttp_.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE;\n if (!this.fetchResponseState_.textDecoder) {\n if (typeof TextDecoder === 'undefined') {\n this.channelDebug_.severe(\n 'TextDecoder is not supported by this browser.');\n this.cleanup_();\n this.dispatchFailure_();\n return '';\n }\n this.fetchResponseState_.textDecoder = new goog.global.TextDecoder();\n }\n for (let i = 0; i < responseLength; i++) {\n this.fetchResponseState_.responseArrivedForFetch = true;\n const isLastChunk = requestCompleted && i == responseLength - 1;\n responseText += this.fetchResponseState_.textDecoder.decode(\n responseChunks[i], {stream: isLastChunk});\n }\n responseChunks.length = 0; // Empty the `responseChunks` array.\n this.fetchResponseState_.responseBuffer += responseText;\n this.xmlHttpChunkStart_ = 0;\n return this.fetchResponseState_.responseBuffer;\n};\n\n\n/**\n * Whether or not the response has response body.\n * @private\n * @returns {boolean}\n */\nChannelRequest.prototype.hasResponseBody_ = function() {\n 'use strict';\n if (!this.xmlHttp_) {\n return false;\n }\n if (this.fetchResponseState_.responseArrivedForFetch) {\n return true;\n }\n return !(!this.xmlHttp_.getResponseText() && !this.xmlHttp_.getResponse());\n};\n\n/**\n * Whether or not the response body is streamed.\n * @private\n * @returns {boolean}\n */\nChannelRequest.prototype.useFetchStreamsForResponse_ = function() {\n 'use strict';\n if (!this.xmlHttp_) {\n return false;\n }\n return (\n this.verb_ == 'GET' && this.type_ != ChannelRequest.Type_.CLOSE_REQUEST &&\n this.channel_.usesFetchStreams());\n};\n\n\n/**\n * Decodes the next set of available chunks in the response.\n * @param {number} readyState The value of readyState.\n * @param {string} responseText The value of responseText.\n * @private\n */\nChannelRequest.prototype.decodeNextChunks_ = function(\n readyState, responseText) {\n 'use strict';\n let decodeNextChunksSuccessful = true;\n\n let chunkText;\n while (!this.cancelled_ && this.xmlHttpChunkStart_ < responseText.length) {\n chunkText = this.getNextChunk_(responseText);\n if (chunkText == ChannelRequest.INCOMPLETE_CHUNK_) {\n if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {\n // should have consumed entire response when the request is done\n this.lastError_ = ChannelRequest.Error.BAD_DATA;\n requestStats.notifyStatEvent(requestStats.Stat.REQUEST_INCOMPLETE_DATA);\n decodeNextChunksSuccessful = false;\n }\n this.channelDebug_.xmlHttpChannelResponseText(\n this.rid_, null, '[Incomplete Response]');\n break;\n } else if (chunkText == ChannelRequest.INVALID_CHUNK_) {\n this.lastError_ = ChannelRequest.Error.BAD_DATA;\n requestStats.notifyStatEvent(requestStats.Stat.REQUEST_BAD_DATA);\n this.channelDebug_.xmlHttpChannelResponseText(\n this.rid_, responseText, '[Invalid Chunk]');\n decodeNextChunksSuccessful = false;\n break;\n } else {\n this.channelDebug_.xmlHttpChannelResponseText(\n this.rid_, /** @type {string} */ (chunkText), null);\n this.safeOnRequestData_(/** @type {string} */ (chunkText));\n }\n }\n\n if (this.useFetchStreamsForResponse_() && this.xmlHttpChunkStart_ != 0) {\n // Remove processed chunk text from response buffer.\n this.fetchResponseState_.responseBuffer =\n this.fetchResponseState_.responseBuffer.slice(this.xmlHttpChunkStart_);\n this.xmlHttpChunkStart_ = 0;\n }\n\n if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE &&\n responseText.length == 0 &&\n !this.fetchResponseState_.responseArrivedForFetch) {\n // also an error if we didn't get any response\n this.lastError_ = ChannelRequest.Error.NO_DATA;\n requestStats.notifyStatEvent(requestStats.Stat.REQUEST_NO_DATA);\n decodeNextChunksSuccessful = false;\n }\n\n this.successful_ = this.successful_ && decodeNextChunksSuccessful;\n\n if (!decodeNextChunksSuccessful) {\n // malformed response - we make this trigger retry logic\n this.channelDebug_.xmlHttpChannelResponseText(\n this.rid_, responseText, '[Invalid Chunked Response]');\n this.cleanup_();\n this.dispatchFailure_();\n } else {\n if (responseText.length > 0 && !this.firstByteReceived_) {\n this.firstByteReceived_ = true;\n this.channel_.onFirstByteReceived(this, responseText);\n }\n }\n};\n\n\n/**\n * Polls the response for new data.\n * @private\n */\nChannelRequest.prototype.pollResponse_ = function() {\n 'use strict';\n if (!this.xmlHttp_) {\n return; // already closed\n }\n const readyState = this.xmlHttp_.getReadyState();\n const responseText = this.xmlHttp_.getResponseText();\n if (this.xmlHttpChunkStart_ < responseText.length) {\n this.cancelWatchDogTimer_();\n this.decodeNextChunks_(readyState, responseText);\n if (this.successful_ &&\n readyState != goog.net.XmlHttp.ReadyState.COMPLETE) {\n this.ensureWatchDogTimer_();\n }\n }\n};\n\n\n/**\n * Starts a polling interval for changes to responseText of the\n * XMLHttpRequest, for browsers that don't fire onreadystatechange\n * as data comes in incrementally. This timer is disabled in\n * cleanup_().\n * @private\n */\nChannelRequest.prototype.startPolling_ = function() {\n 'use strict';\n this.eventHandler_.listen(\n this.pollingTimer_, goog.Timer.TICK, this.pollResponse_);\n this.pollingTimer_.start();\n};\n\n\n/**\n * Returns the next chunk of a chunk-encoded response. This is not standard\n * HTTP chunked encoding because browsers don't expose the chunk boundaries to\n * the application through XMLHTTP. So we have an additional chunk encoding at\n * the application level that lets us tell where the beginning and end of\n * individual responses are so that we can only try to eval a complete JS array.\n *\n * The encoding is the size of the chunk encoded as a decimal string followed\n * by a newline followed by the data.\n *\n * @param {string} responseText The response text from the XMLHTTP response.\n * @return {string|!Object} The next chunk string or a sentinel object\n * indicating a special condition.\n * @private\n */\nChannelRequest.prototype.getNextChunk_ = function(responseText) {\n 'use strict';\n const sizeStartIndex = this.xmlHttpChunkStart_;\n const sizeEndIndex = responseText.indexOf('\\n', sizeStartIndex);\n if (sizeEndIndex == -1) {\n return ChannelRequest.INCOMPLETE_CHUNK_;\n }\n\n const sizeAsString = responseText.substring(sizeStartIndex, sizeEndIndex);\n const size = Number(sizeAsString);\n if (isNaN(size)) {\n return ChannelRequest.INVALID_CHUNK_;\n }\n\n const chunkStartIndex = sizeEndIndex + 1;\n if (chunkStartIndex + size > responseText.length) {\n return ChannelRequest.INCOMPLETE_CHUNK_;\n }\n\n const chunkText = responseText.slice(chunkStartIndex, chunkStartIndex + size);\n this.xmlHttpChunkStart_ = chunkStartIndex + size;\n return chunkText;\n};\n\n\n/**\n * Uses an IMG tag or navigator.sendBeacon to send an HTTP get to the server.\n *\n * This is only currently used to terminate the connection, as an IMG tag is\n * the most reliable way to send something to the server while the page\n * is getting torn down.\n *\n * Navigator.sendBeacon is available on Chrome and Firefox as a formal\n * solution to ensure delivery without blocking window close. See\n * https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon\n *\n * For Chrome Apps, sendBeacon is always necessary due to Content Security\n * Policy (CSP) violation of using an IMG tag.\n *\n * For react-native, we use xhr to send the actual close request, and assume\n * there is no page-close issue with react-native.\n *\n * @param {goog.Uri} uri The uri to send a request to.\n */\nChannelRequest.prototype.sendCloseRequest = function(uri) {\n 'use strict';\n this.type_ = ChannelRequest.Type_.CLOSE_REQUEST;\n this.baseUri_ = uri.clone().makeUnique();\n\n let requestSent = false;\n\n if (goog.global.navigator && goog.global.navigator.sendBeacon) {\n try {\n // empty string body to avoid 413 error on chrome < 41\n requestSent =\n goog.global.navigator.sendBeacon(this.baseUri_.toString(), '');\n } catch {\n // Intentionally left empty; sendBeacon might throw TypeError in certain\n // unexpected cases.\n }\n }\n\n if (!requestSent && goog.global.Image) {\n const eltImg = new Image();\n eltImg.src = this.baseUri_;\n requestSent = true;\n }\n\n if (!requestSent) {\n // no handler is set to match the sendBeacon/Image behavior\n this.xmlHttp_ = this.channel_.createXhrIo(null);\n this.xmlHttp_.send(this.baseUri_);\n }\n\n this.requestStartTime_ = Date.now();\n this.ensureWatchDogTimer_();\n};\n\n\n/**\n * Cancels the request no matter what the underlying transport is.\n */\nChannelRequest.prototype.cancel = function() {\n 'use strict';\n this.cancelled_ = true;\n this.cleanup_();\n};\n\n\n/**\n * Resets the timeout.\n *\n * @param {number=} opt_timeout The new timeout\n */\nChannelRequest.prototype.resetTimeout = function(opt_timeout) {\n 'use strict';\n if (opt_timeout) {\n this.setTimeout(opt_timeout);\n }\n // restart only if a timer is currently set\n if (this.watchDogTimerId_) {\n this.cancelWatchDogTimer_();\n this.ensureWatchDogTimer_();\n }\n};\n\n\n/**\n * Ensures that there is watchdog timeout which is used to ensure that\n * the connection completes in time.\n *\n * @private\n */\nChannelRequest.prototype.ensureWatchDogTimer_ = function() {\n 'use strict';\n this.watchDogTimeoutTime_ = Date.now() + this.timeout_;\n this.startWatchDogTimer_(this.timeout_);\n};\n\n\n/**\n * Starts the watchdog timer which is used to ensure that the connection\n * completes in time.\n * @param {number} time The number of milliseconds to wait.\n * @private\n */\nChannelRequest.prototype.startWatchDogTimer_ = function(time) {\n 'use strict';\n if (this.watchDogTimerId_ != null) {\n // assertion\n throw new Error('WatchDog timer not null');\n }\n this.watchDogTimerId_ =\n requestStats.setTimeout(goog.bind(this.onWatchDogTimeout_, this), time);\n};\n\n\n/**\n * Cancels the watchdog timer if it has been started.\n *\n * @private\n */\nChannelRequest.prototype.cancelWatchDogTimer_ = function() {\n 'use strict';\n if (this.watchDogTimerId_) {\n goog.global.clearTimeout(this.watchDogTimerId_);\n this.watchDogTimerId_ = null;\n }\n};\n\n\n/**\n * Called when the watchdog timer is triggered. It also handles a case where it\n * is called too early which we suspect may be happening sometimes\n * (not sure why)\n *\n * @private\n */\nChannelRequest.prototype.onWatchDogTimeout_ = function() {\n 'use strict';\n this.watchDogTimerId_ = null;\n const now = Date.now();\n goog.asserts.assert(\n this.watchDogTimeoutTime_, 'WatchDog timeout time missing?');\n if (now - this.watchDogTimeoutTime_ >= 0) {\n this.handleTimeout_();\n } else {\n // got called too early for some reason\n this.channelDebug_.warning('WatchDog timer called too early');\n this.startWatchDogTimer_(this.watchDogTimeoutTime_ - now);\n }\n};\n\n\n/**\n * Called when the request has actually timed out. Will cleanup and notify the\n * channel of the failure.\n *\n * @private\n */\nChannelRequest.prototype.handleTimeout_ = function() {\n 'use strict';\n if (this.successful_) {\n // Should never happen.\n this.channelDebug_.severe(\n 'Received watchdog timeout even though request loaded successfully');\n }\n\n this.channelDebug_.timeoutResponse(this.requestUri_);\n\n // IMG or SendBeacon requests never notice if they were successful,\n // and always 'time out'. This fact says nothing about reachability.\n if (this.type_ != ChannelRequest.Type_.CLOSE_REQUEST) {\n requestStats.notifyServerReachabilityEvent(\n requestStats.ServerReachability.REQUEST_FAILED);\n requestStats.notifyStatEvent(requestStats.Stat.REQUEST_TIMEOUT);\n }\n\n this.cleanup_();\n\n // Set error and dispatch failure.\n // This is called for CLOSE_REQUEST too to ensure channel_.onRequestComplete.\n this.lastError_ = ChannelRequest.Error.TIMEOUT;\n this.dispatchFailure_();\n};\n\n\n/**\n * Notifies the channel that this request failed.\n * @private\n */\nChannelRequest.prototype.dispatchFailure_ = function() {\n 'use strict';\n if (this.channel_.isClosed() || this.cancelled_) {\n return;\n }\n\n this.channel_.onRequestComplete(this);\n};\n\n\n/**\n * Cleans up the objects used to make the request. This function is\n * idempotent.\n *\n * @private\n */\nChannelRequest.prototype.cleanup_ = function() {\n 'use strict';\n this.cancelWatchDogTimer_();\n\n goog.dispose(this.readyStateChangeThrottle_);\n this.readyStateChangeThrottle_ = null;\n\n // Stop the polling timer, if necessary.\n this.pollingTimer_.stop();\n\n // Unhook all event handlers.\n this.eventHandler_.removeAll();\n\n if (this.xmlHttp_) {\n // clear out this.xmlHttp_ before aborting so we handle getting reentered\n // inside abort\n const xmlhttp = this.xmlHttp_;\n this.xmlHttp_ = null;\n xmlhttp.abort();\n xmlhttp.dispose();\n }\n};\n\n\n/**\n * Indicates whether the request was successful. Only valid after the handler\n * is called to indicate completion of the request.\n *\n * @return {boolean} True if the request succeeded.\n */\nChannelRequest.prototype.getSuccess = function() {\n 'use strict';\n return this.successful_;\n};\n\n\n/**\n * If the request was not successful, returns the reason.\n *\n * @return {?ChannelRequest.Error} The last error.\n */\nChannelRequest.prototype.getLastError = function() {\n 'use strict';\n return this.lastError_;\n};\n\n\n/**\n * @return {!Object<string, string>|undefined} Response headers received\n * along with the non-200 status, as a key-value map.\n */\nChannelRequest.prototype.getErrorResponseHeaders = function() {\n 'use strict';\n return this.errorResponseHeaders_;\n};\n\n\n/**\n * Returns the status code of the last request.\n *\n * @return {number} The status code of the last request.\n */\nChannelRequest.prototype.getLastStatusCode = function() {\n 'use strict';\n return this.lastStatusCode_;\n};\n\n\n/**\n * Returns the session id for this channel.\n *\n * @return {string|undefined} The session ID.\n */\nChannelRequest.prototype.getSessionId = function() {\n 'use strict';\n return this.sid_;\n};\n\n\n/**\n * Returns the request id for this request. Each request has a unique request\n * id and the request IDs are a sequential increasing count.\n *\n * @return {string|number|undefined} The request ID.\n */\nChannelRequest.prototype.getRequestId = function() {\n 'use strict';\n return this.rid_;\n};\n\n\n/**\n * Returns the data for a post, if this request is a post.\n *\n * @return {?string} The POST data provided by the request initiator.\n */\nChannelRequest.prototype.getPostData = function() {\n 'use strict';\n return this.postData_;\n};\n\n\n/**\n * Returns the XhrIo request object.\n *\n * @return {?goog.net.XhrIo} Any XhrIo request created for this object.\n */\nChannelRequest.prototype.getXhr = function() {\n 'use strict';\n return this.xmlHttp_;\n};\n\n\n/**\n * Returns the time that the request started, if it has started.\n *\n * @return {?number} The time the request started, as returned by Date.now().\n */\nChannelRequest.prototype.getRequestStartTime = function() {\n 'use strict';\n return this.requestStartTime_;\n};\n\n\n/**\n * Helper to call the callback's onRequestData, which catches any\n * exception.\n * @param {string} data The request data.\n * @private\n */\nChannelRequest.prototype.safeOnRequestData_ = function(data) {\n 'use strict';\n try {\n this.channel_.onRequestData(this, data);\n const stats = requestStats.ServerReachability;\n requestStats.notifyServerReachabilityEvent(stats.BACK_CHANNEL_ACTIVITY);\n } catch (e) {\n // Dump debug info, but keep going without closing the channel.\n this.channelDebug_.dumpException(e, 'Error in httprequest callback');\n }\n};\n\n\n/**\n * Convenience factory method.\n *\n * @param {Channel} channel The channel object that owns this request.\n * @param {WebChannelDebug} channelDebug A WebChannelDebug to use for logging.\n * @param {string=} opt_sessionId The session id for the channel.\n * @param {string|number=} opt_requestId The request id for this request.\n * @param {number=} opt_retryId The retry id for this request.\n * @return {!ChannelRequest} The created channel request.\n */\nChannelRequest.createChannelRequest = function(\n channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {\n 'use strict';\n return new ChannelRequest(\n channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId);\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A single module to define user-agent specific environment\n * details.\n *\n */\n\ngoog.module('goog.labs.net.webChannel.environment');\n\ngoog.module.declareLegacyNamespace();\n\nvar userAgent = goog.require('goog.userAgent');\n\n\n/**\n * The default polling interval in millis for Edge.\n *\n * Currently on edge, new-chunk events may be not be fired (at all) if a new\n * chunk arrives within 50ms following the previous chunk. This may be fixed\n * in future, which requires changes to the whatwg spec too.\n *\n * @private @const {number}\n */\nvar EDGE_POLLING_INTERVAL_ = 125;\n\n\n/**\n * History:\n *\n * IE11 is still using Trident, the traditional engine for IE.\n * Edge is using EdgeHTML, a fork of Trident. We are seeing the same issue\n * on IE-11 (reported in 2017), so treat IE the same as Edge for now.\n *\n * We used to do polling for Opera (only) with an 250ms interval, because Opera\n * only fires readyState == INTERACTIVE once. Opera switched to WebKit in 2013,\n * and then to Blink (chrome).\n *\n * TODO(user): check the raw UA string to keep polling for old, mobile operas\n * that may still be affected. For old Opera, double the polling interval\n * to 250ms.\n *\n * @return {boolean} True if polling is required with XHR.\n */\nexports.isPollingRequired = function() {\n return userAgent.EDGE_OR_IE;\n};\n\n\n/**\n * How often to poll (in MS) for changes to responseText in browsers that don't\n * fire onreadystatechange during incremental loading of the response body.\n *\n * @return {number|undefined} The polling interval (MS) for the current U-A;\n * or undefined if polling is not supposed to be enabled.\n */\nexports.getPollingInterval = function() {\n if (userAgent.EDGE_OR_IE) {\n return EDGE_POLLING_INTERVAL_;\n }\n\n return undefined;\n};\n\n/**\n * Origin trial token for google.com\n *\n * https://developers.chrome.com/origintrials/#/trials\n *\n * http://googlechrome.github.io/OriginTrials/check-token.html\n * Origin: https://google.com:443\n * Matches Subdomains? Yes\n * Matches Third-party? Yes\n * Feature: FetchUploadStreaming\n * Up to Chrome 95 (ends with the rollout of next Chrome release), no later\n * than Nov 9, 2021\n *\n * Token for googleapis.com will be registered after google.com's is deployed.\n *\n */\nconst OT_TOKEN_GOOGLE_COM =\n 'A0eNbltY1nd4MP7XTHXnTxWogDL6mWTdgIIKfKOTJoUHNbFFMZQBoiHHjJ9UK9lgYndWFaxOWR7ld8uUjcWmcwIAAAB/eyJvcmlnaW4iOiJodHRwczovL2dvb2dsZS5jb206NDQzIiwiZmVhdHVyZSI6IkZldGNoVXBsb2FkU3RyZWFtaW5nIiwiZXhwaXJ5IjoxNjM2NTAyMzk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ==';\n\n\n/**\n * Creates ReadableStream to upload\n * @return {!ReadableStream} ReadableStream to upload\n */\nfunction createStream() {\n const encoder = new goog.global.TextEncoder();\n return new goog.global.ReadableStream({\n start: controller => {\n for (const obj of ['test\\r\\n', 'test\\r\\n']) {\n controller.enqueue(encoder.encode(obj));\n }\n controller.close();\n }\n });\n}\n\n/**\n * Detect the user agent is chrome and its version is higher than M90.\n * This code is hard-coded from goog.labs.userAgent.browser to avoid file size\n * increasing.\n * @return {boolean} Whether the above is true.\n */\nfunction isChromeM90OrHigher() {\n const userAgentStr = function() {\n const navigator = goog.global.navigator;\n if (navigator) {\n const userAgent = navigator.userAgent;\n if (userAgent) {\n return userAgent;\n }\n }\n return '';\n }();\n\n const matchUserAgent = function(str) {\n return userAgentStr.indexOf(str) != -1;\n };\n\n if (!matchUserAgent('Chrome') || matchUserAgent('Edg')) {\n return false;\n }\n\n const match = /Chrome\\/(\\d+)/.exec(userAgentStr);\n const chromeVersion = parseInt(match[1], 10);\n return chromeVersion >= 90;\n}\n\n/**\n * Detect the URL origin is *.google.com.\n * @param {string} url The target URL.\n * @return {boolean} Whether the above is true.\n */\nfunction isUrlGoogle(url) {\n const match = /\\/\\/([^\\/]+)\\//.exec(url);\n if (!match) {\n return false;\n }\n const origin = match[1];\n return origin.endsWith('google.com');\n}\n\n/**\n * The flag to run the origin trials code only once.\n */\nlet isStartOriginTrialsCalled = false;\n\n/**\n * For Fetch/upload OT, make three requests against the server endpoint.\n * POST requests contain only dummy payload.\n *\n * https://developers.chrome.com/origintrials/#/view_trial/3524066708417413121\n *\n * This function is expected to be called from background during the handshake.\n * Exceptions will be logged by the caller.\n *\n * No stats or logs are collected on the client-side. To be disabled once the\n * OT is expired.\n *\n * @param {string} path The base URL path for the requests\n * @param {function(*)} logError A function to execute when exceptions are\n * caught.\n */\nexports.startOriginTrials = function(path, logError) {\n if (isStartOriginTrialsCalled) {\n return;\n }\n isStartOriginTrialsCalled = true;\n // NE: may need check if path has already contains query params?\n\n // Accept only Chrome M90 or later due to service worker support.\n if (!isChromeM90OrHigher()) {\n return;\n }\n\n // Accept only only google.com and subdoamins.\n if (!isUrlGoogle(path)) {\n return;\n }\n // Since 3P OT is not supported yet, we should check the current page matches\n // the path (absolute one?) to disable this OT for cross-origin calls\n if (!window || !window.document || !isUrlGoogle(window.document.URL)) {\n return;\n }\n\n // Enable origin trial by injecting OT <meta> tag\n const tokenElement =\n /** @type {! HTMLMetaElement} */ (document.createElement('meta'));\n tokenElement.httpEquiv = 'origin-trial';\n tokenElement.content = OT_TOKEN_GOOGLE_COM;\n // appendChild() synchronously enables OT.\n document.head.appendChild(tokenElement);\n\n // Check if fetch upload stream is actually enabled.\n // By the spec, Streaming request doesn't has the Content-Type header:\n // https://fetch.spec.whatwg.org/#concept-bodyinit-extract\n // If Chrome doesn't support Streaming, the body stream is converted to a\n // string \"[object ReadableStream]\" for fallback then it has \"Content-Type:\n // text/plain;charset=UTF-8\".\n const supportsRequestStreams = !new Request('', {\n body: new ReadableStream(),\n method: 'POST',\n }).headers.has('Content-Type');\n\n if (supportsRequestStreams) {\n logError('OriginTrial unexpected.');\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Base WebChannel implementation.\n */\n\n\ngoog.provide('goog.labs.net.webChannel.WebChannelBase');\n\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.async.run');\ngoog.require('goog.collections.maps');\ngoog.require('goog.json');\ngoog.require('goog.labs.net.webChannel.Channel');\ngoog.require('goog.labs.net.webChannel.ChannelRequest');\ngoog.require('goog.labs.net.webChannel.ConnectionState');\ngoog.require('goog.labs.net.webChannel.ForwardChannelRequestPool');\ngoog.require('goog.labs.net.webChannel.WebChannelDebug');\ngoog.require('goog.labs.net.webChannel.Wire');\ngoog.require('goog.labs.net.webChannel.WireV8');\ngoog.require('goog.labs.net.webChannel.environment');\ngoog.require('goog.labs.net.webChannel.netUtils');\ngoog.require('goog.labs.net.webChannel.requestStats');\ngoog.require('goog.net.FetchXmlHttpFactory');\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.net.XhrIo');\ngoog.require('goog.net.XmlHttpFactory');\ngoog.require('goog.net.rpc.HttpCors');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.structs');\n\ngoog.scope(function() {\n'use strict';\nconst WebChannel = goog.net.WebChannel;\nconst ChannelRequest = goog.labs.net.webChannel.ChannelRequest;\nconst ConnectionState = goog.labs.net.webChannel.ConnectionState;\nconst ForwardChannelRequestPool =\n goog.labs.net.webChannel.ForwardChannelRequestPool;\nconst WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\nconst Wire = goog.labs.net.webChannel.Wire;\nconst WireV8 = goog.labs.net.webChannel.WireV8;\nconst environment = goog.labs.net.webChannel.environment;\nconst netUtils = goog.labs.net.webChannel.netUtils;\nconst requestStats = goog.labs.net.webChannel.requestStats;\n\nconst httpCors = goog.module.get('goog.net.rpc.HttpCors');\n\n/**\n * @define {boolean} If WebChannel should compile with Origin Trial features.\n */\nconst ALLOW_ORIGIN_TRIAL_FEATURES =\n goog.define('goog.net.webChannel.ALLOW_ORIGIN_TRIAL_FEATURES', false);\n\n/**\n * @define {boolean} If webchannel should ping google.com for debugging\n * connectivity issues (that may have caused the channel to abort).\n */\nconst ENABLE_GOOGLE_COM_PING =\n goog.define('goog.net.webChannel.ENABLE_GOOGLE_COM_PING', true);\n\n/**\n * Gets an internal channel parameter in a type-safe way.\n *\n * @param {string} paramName the key of the parameter to fetch.\n * @param {!T} defaultValue the default value to return\n * @param {!goog.net.WebChannel.Options=} options Configuration for the\n * WebChannel instance.\n * @return {T}\n * @template T\n */\nfunction getInternalChannelParam(paramName, defaultValue, options) {\n if (!options || !options.internalChannelParams) {\n return defaultValue;\n }\n return /** @type {T} */ (options.internalChannelParams[paramName]) ||\n defaultValue;\n}\n\n/**\n * This WebChannel implementation is branched off goog.net.BrowserChannel\n * for now. Ongoing changes to goog.net.BrowserChannel will be back\n * ported to this implementation as needed.\n *\n * @param {!goog.net.WebChannel.Options=} opt_options Configuration for the\n * WebChannel instance.\n * @param {number=} opt_clientVersion An application-specific version number\n * that is sent to the server when connected.\n * @param {!ConnectionState=} opt_conn Previously determined connection\n * conditions.\n * @constructor\n * @struct\n * @implements {goog.labs.net.webChannel.Channel}\n */\ngoog.labs.net.webChannel.WebChannelBase = function(\n opt_options, opt_clientVersion, opt_conn) {\n 'use strict';\n /**\n * The client library version (capabilities).\n * @private {number}\n */\n this.clientVersion_ = opt_clientVersion || 0;\n\n /**\n * The server library version (capabilities).\n * @private {number}\n */\n this.serverVersion_ = 0;\n\n\n /**\n * An array of queued maps that need to be sent to the server.\n * @private {!Array<Wire.QueuedMap>}\n */\n this.outgoingMaps_ = [];\n\n /**\n * The channel debug used for logging\n * @private {!WebChannelDebug}\n */\n this.channelDebug_ = new WebChannelDebug();\n\n /**\n * Connectivity state.\n * @private {!ConnectionState}\n */\n this.connState_ = opt_conn || new ConnectionState();\n\n /**\n * Extra HTTP headers to add to all the requests sent to the server.\n * @private {?Object}\n */\n this.extraHeaders_ = null;\n\n /**\n * Extra HTTP headers to add to the init request(s) sent to the server.\n * @private {?Object}\n */\n this.initHeaders_ = null;\n\n /**\n * @private {?string} The URL param name to overwrite custom HTTP headers\n * to bypass CORS preflight.\n */\n this.httpHeadersOverwriteParam_ = null;\n\n /**\n * Extra parameters to add to all the requests sent to the server.\n * @private {?Object}\n */\n this.extraParams_ = null;\n\n /**\n * Parameter name for the http session id.\n * @private {?string}\n */\n this.httpSessionIdParam_ = null;\n\n /**\n * The http session id, to be sent with httpSessionIdParam_ with each\n * request after the initial handshake.\n * @private {?string}\n */\n this.httpSessionId_ = null;\n\n /**\n * The ChannelRequest object for the backchannel.\n * @private {?ChannelRequest}\n */\n this.backChannelRequest_ = null;\n\n /**\n * The relative path (in the context of the page hosting the browser channel)\n * for making requests to the server.\n * @private {?string}\n */\n this.path_ = null;\n\n /**\n * The absolute URI for the forwardchannel request.\n * @private {?goog.Uri}\n */\n this.forwardChannelUri_ = null;\n\n /**\n * The absolute URI for the backchannel request.\n * @private {?goog.Uri}\n */\n this.backChannelUri_ = null;\n\n /**\n * A subdomain prefix for using a subdomain in IE for the backchannel\n * requests.\n * @private {?string}\n */\n this.hostPrefix_ = null;\n\n /**\n * Whether we allow the use of a subdomain in IE for the backchannel requests.\n * @private {boolean}\n */\n this.allowHostPrefix_ = true;\n\n /**\n * The next id to use for the RID (request identifier) parameter. This\n * identifier uniquely identifies the forward channel request.\n * @private {number}\n */\n this.nextRid_ = 0;\n\n /**\n * The id to use for the next outgoing map. This identifier uniquely\n * identifies a sent map.\n * @private {number}\n */\n this.nextMapId_ = 0;\n\n /**\n * Whether to fail forward-channel requests after one try or a few tries.\n * @private {boolean}\n */\n this.failFast_ = getInternalChannelParam('failFast', false, opt_options);\n\n /**\n * The handler that receive callbacks for state changes and data.\n * @private {?goog.labs.net.webChannel.WebChannelBase.Handler}\n */\n this.handler_ = null;\n\n /**\n * Timer identifier for asynchronously making a forward channel request.\n * This is set to true if the func is scheduled with async.run, which\n * is equivalent to setTimeout(0).\n * @private {?number|?boolean}\n */\n this.forwardChannelTimerId_ = null;\n\n /**\n * Timer identifier for asynchronously making a back channel request.\n * @private {?number}\n */\n this.backChannelTimerId_ = null;\n\n /**\n * Timer identifier for the timer that waits for us to retry the backchannel\n * in the case where it is dead and no longer receiving data.\n * @private {?number}\n */\n this.deadBackChannelTimerId_ = null;\n\n /**\n * Whether the client's network conditions can support streamed responses.\n * @private {?boolean}\n */\n this.enableStreaming_ = null;\n\n /**\n * Whether streaming mode is allowed. In certain debugging situations, it's\n * useful to disable this.\n * @private {boolean}\n */\n this.allowStreamingMode_ = true;\n\n /**\n * The array identifier of the last array received from the server for the\n * backchannel request.\n * @private {number}\n */\n this.lastArrayId_ = -1;\n\n /**\n * The array id of the last array sent by the server that we know about.\n * @private {number}\n */\n this.lastPostResponseArrayId_ = -1;\n\n /**\n * The non-200 status code received that causes the channel to be aborted.\n * @private {number}\n */\n this.errorResponseStatusCode_ = -1;\n\n /**\n * The response headers received along with the non-200 status.\n * @private {!Object<string, string>|undefined}\n */\n this.errorResponseHeaders_ = undefined;\n\n /**\n * Number of times we have retried the current forward channel request.\n * @private {number}\n */\n this.forwardChannelRetryCount_ = 0;\n\n /**\n * Number of times in a row that we have retried the current back channel\n * request and received no data.\n * @private {number}\n */\n this.backChannelRetryCount_ = 0;\n\n /**\n * The attempt id for the current back channel request. Starts at 1 and\n * increments for each reconnect. The server uses this to log if our\n * connection is flaky or not.\n * @private {number}\n */\n this.backChannelAttemptId_ = 0;\n\n /**\n * The base part of the time before firing next retry request. Default is 5\n * seconds. Note that a random delay is added (see {@link retryDelaySeedMs_})\n * for all retries, and linear backoff is applied to the sum for subsequent\n * retries.\n * @private {number}\n */\n this.baseRetryDelayMs_ =\n getInternalChannelParam('baseRetryDelayMs', 5 * 1000, opt_options);\n\n /**\n * A random time between 0 and this number of MS is added to the\n * {@link baseRetryDelayMs_}. Default is 10 seconds.\n * @private {number}\n */\n this.retryDelaySeedMs_ =\n getInternalChannelParam('retryDelaySeedMs', 10 * 1000, opt_options);\n\n /**\n * Maximum number of attempts to connect to the server for forward channel\n * requests. Defaults to 2.\n * @private {number}\n */\n this.forwardChannelMaxRetries_ =\n getInternalChannelParam('forwardChannelMaxRetries', 2, opt_options);\n\n /**\n * The timeout in milliseconds for a forward channel request. Defaults to 20\n * seconds. Note that part of this timeout can be randomized.\n * @private {number}\n */\n this.forwardChannelRequestTimeoutMs_ = getInternalChannelParam(\n 'forwardChannelRequestTimeoutMs', 20 * 1000, opt_options);\n\n /**\n * The custom factory used to create XMLHttpRequest objects.\n * @private {!goog.net.XmlHttpFactory | undefined}\n */\n this.xmlHttpFactory_ =\n (opt_options && opt_options.xmlHttpFactory) || undefined;\n\n /**\n * Whether or not this channel uses WHATWG Fetch/streams.\n * @private {boolean}\n */\n this.usesFetchStreams_ =\n (opt_options && opt_options.useFetchStreams) || false;\n\n /**\n * The timeout in milliseconds for a back channel request. Defaults to using\n * the timeout configured in ChannelRequest (45s). If server-side\n * keepaliveInterval is known to the client, set the backchannel request\n * timeout to 1.5 * keepaliveInterval (ms).\n *\n * @private {number|undefined}\n */\n this.backChannelRequestTimeoutMs_ = undefined;\n\n /**\n * A throttle time in ms for readystatechange events for the backchannel.\n * Useful for throttling when ready state is INTERACTIVE (partial data).\n *\n * This throttle is useful if the server sends large data chunks down the\n * backchannel. It prevents examining XHR partial data on every readystate\n * change event. This is useful because large chunks can trigger hundreds\n * of readystatechange events, each of which takes ~5ms or so to handle,\n * in turn making the UI unresponsive for a significant period.\n *\n * If set to zero no throttle is used.\n * @private {number}\n */\n this.readyStateChangeThrottleMs_ = 0;\n\n /**\n * Whether cross origin requests are supported for the channel.\n *\n * See {@link goog.net.XhrIo#setWithCredentials}.\n * @private {boolean}\n */\n this.supportsCrossDomainXhrs_ =\n (opt_options && opt_options.supportsCrossDomainXhr) || false;\n\n /**\n * The current session id.\n * @private {string}\n */\n this.sid_ = '';\n\n /**\n * The current ChannelRequest pool for the forward channel.\n * @private {!ForwardChannelRequestPool}\n */\n this.forwardChannelRequestPool_ = new ForwardChannelRequestPool(\n opt_options && opt_options.concurrentRequestLimit);\n\n /**\n * The V8 codec.\n * @private {!WireV8}\n */\n this.wireCodec_ = new WireV8();\n\n /**\n * Whether to turn on the fast handshake behavior.\n *\n * @private {boolean}\n */\n this.fastHandshake_ = (opt_options && opt_options.fastHandshake) || false;\n\n /**\n * Whether to encode initMessageHeaders in the body.\n *\n * @private {boolean}\n */\n this.encodeInitMessageHeaders_ =\n (opt_options && opt_options.encodeInitMessageHeaders) || false;\n\n if (this.fastHandshake_ && this.encodeInitMessageHeaders_) {\n this.channelDebug_.warning(\n 'Ignore encodeInitMessageHeaders because fastHandshake is set.');\n this.encodeInitMessageHeaders_ = false;\n }\n\n /**\n * Whether to signal to the server to enable blocking handshake.\n *\n * @private {boolean}\n */\n this.blockingHandshake_ =\n (opt_options && opt_options.blockingHandshake) || false;\n\n\n if (opt_options && opt_options.disableRedact) {\n this.channelDebug_.disableRedact();\n }\n\n if (opt_options && opt_options.forceLongPolling) {\n this.allowStreamingMode_ = false;\n }\n\n /**\n * Whether to detect buffering proxies.\n *\n * fastHandshake + detectBufferingProxy are yet to be implemented.\n *\n * @private {boolean}\n */\n this.detectBufferingProxy_ =\n (!this.fastHandshake_ && this.allowStreamingMode_ && opt_options &&\n opt_options.detectBufferingProxy) ||\n false;\n\n /**\n * Long polling timeout interval for the server to complete the handing GET.\n *\n * @private {number|undefined}\n */\n this.longPollingTimeout_ = undefined;\n\n if (opt_options && opt_options.longPollingTimeout &&\n opt_options.longPollingTimeout > 0) {\n this.longPollingTimeout_ = opt_options.longPollingTimeout;\n }\n\n /**\n * Callback when all the pending client-sent messages have been flushed.\n *\n * @private {function()|undefined}\n */\n this.forwardChannelFlushedCallback_ = undefined;\n\n /**\n * TODO(user): move all backchannel states to its own class similar to\n * forwardchannelrequestpool.js and log more stats.\n *\n * The estimated handshake RTT (ms) as measured from when the handshake\n * request is sent and when the handshake response headers are received.\n * If the value is 0, the RTT is unknown.\n *\n * @private {number}\n */\n this.handshakeRttMs_ = 0;\n\n /**\n * If BP detection is done or still in progress.\n * Should only be checked when detectBufferingProxy is turned on.\n * @private {boolean}\n */\n this.bpDetectionDone_ = false;\n\n /**\n * The timer for detecting buffering proxy. This needs be reset with each\n * backchannel request. If this is not null, bpDetectionDone_ == false.\n * @private {?number}\n */\n this.bpDetectionTimerId_ = null;\n\n /***\n * Whether to attempt Chrome Origin Trials as part of the handshake.\n * @private @const {boolean}\n */\n this.enableOriginTrials_ = ALLOW_ORIGIN_TRIAL_FEATURES &&\n (!opt_options || opt_options.enableOriginTrials !== false);\n\n /**\n * The array of non-acked maps at the time of channel close. Refer to\n * `getNonAckedMessagesWithClosedChannel()` API for definitions of non-acked\n * messages.\n *\n * @private {?Array<!Wire.QueuedMap>}\n */\n this.nonAckedMapsAtChannelClose_ = null;\n};\n\nconst WebChannelBase = goog.labs.net.webChannel.WebChannelBase;\n\n\n/**\n * The channel version that we negotiated with the server for this session.\n * Starts out as the version we request, and then is changed to the negotiated\n * version after the initial open.\n * @private {number}\n */\nWebChannelBase.prototype.channelVersion_ = Wire.LATEST_CHANNEL_VERSION;\n\n\n/**\n * Enum type for the channel state machine.\n * @enum {number}\n */\nWebChannelBase.State = {\n /** The channel is closed. */\n CLOSED: 0,\n\n /** The channel has been initialized but hasn't yet initiated a connection. */\n INIT: 1,\n\n /** The channel is in the process of opening a connection to the server. */\n OPENING: 2,\n\n /** The channel is open. */\n OPENED: 3\n};\n\n\n/**\n * The current state of the WebChannel.\n * @private {!WebChannelBase.State}\n */\nWebChannelBase.prototype.state_ = WebChannelBase.State.INIT;\n\n\n/**\n * The timeout in milliseconds for a forward channel request.\n * @type {number}\n */\nWebChannelBase.FORWARD_CHANNEL_RETRY_TIMEOUT = 20 * 1000;\n\n\n/**\n * Maximum number of attempts to connect to the server for back channel\n * requests.\n * @type {number}\n */\nWebChannelBase.BACK_CHANNEL_MAX_RETRIES = 3;\n\n\n/**\n * A number in MS of how long we guess the maxmium amount of time a round trip\n * to the server should take. In the future this could be substituted with a\n * real measurement of the RTT.\n * @type {number}\n */\nWebChannelBase.RTT_ESTIMATE = 3 * 1000;\n\n\n/**\n * When retrying for an inactive channel, we will multiply the total delay by\n * this number.\n * @type {number}\n */\nWebChannelBase.INACTIVE_CHANNEL_RETRY_FACTOR = 2;\n\n\n/**\n * Enum type for identifying an error.\n * @enum {number}\n */\nWebChannelBase.Error = {\n /** Value that indicates no error has occurred. */\n OK: 0,\n\n /** An error due to a request failing. */\n REQUEST_FAILED: 2,\n\n /** An error due to the user being logged out. */\n LOGGED_OUT: 4,\n\n /** An error due to server response which contains no data. */\n NO_DATA: 5,\n\n /** An error due to a server response indicating an unknown session id */\n UNKNOWN_SESSION_ID: 6,\n\n /** An error due to a server response requesting to stop the channel. */\n STOP: 7,\n\n /** A general network error. */\n NETWORK: 8,\n\n /** An error due to bad data being returned from the server. */\n BAD_DATA: 10,\n\n /** An error due to a response that is not parsable. */\n BAD_RESPONSE: 11\n};\n\n\n/**\n * Internal enum type for the two channel types.\n * @enum {number}\n * @private\n */\nWebChannelBase.ChannelType_ = {\n FORWARD_CHANNEL: 1,\n\n BACK_CHANNEL: 2\n};\n\n\n/**\n * The maximum number of maps that can be sent in one POST. Should match\n * MAX_MAPS_PER_REQUEST on the server code.\n * @type {number}\n * @private\n */\nWebChannelBase.MAX_MAPS_PER_REQUEST_ = 1000;\n\n\n/**\n * The maximum number of utf-8 chars that can be sent in one GET to enable 0-RTT\n * handshake.\n *\n * @const @private {number}\n */\nWebChannelBase.MAX_CHARS_PER_GET_ = 4 * 1024;\n\n\n/**\n * A guess at a cutoff at which to no longer assume the backchannel is dead\n * when we are slow to receive data. Number in bytes.\n *\n * Assumption: The worst bandwidth we work on is 50 kilobits/sec\n * 50kbits/sec * (1 byte / 8 bits) * 6 sec dead backchannel timeout\n * @type {number}\n */\nWebChannelBase.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF = 37500;\n\n\n/**\n * @return {number} The server version or 0 if undefined\n */\nWebChannelBase.prototype.getServerVersion = function() {\n 'use strict';\n return this.serverVersion_;\n};\n\n\n/**\n * @return {!ForwardChannelRequestPool} The forward channel request pool.\n */\nWebChannelBase.prototype.getForwardChannelRequestPool = function() {\n 'use strict';\n return this.forwardChannelRequestPool_;\n};\n\n\n/**\n * @return {!Object} The codec object.\n */\nWebChannelBase.prototype.getWireCodec = function() {\n 'use strict';\n return this.wireCodec_;\n};\n\n\n/**\n * Returns the logger.\n *\n * @return {!WebChannelDebug} The channel debug object.\n */\nWebChannelBase.prototype.getChannelDebug = function() {\n 'use strict';\n return this.channelDebug_;\n};\n\n\n/**\n * Sets the logger.\n *\n * @param {!WebChannelDebug} channelDebug The channel debug object.\n */\nWebChannelBase.prototype.setChannelDebug = function(channelDebug) {\n 'use strict';\n this.channelDebug_ = channelDebug;\n};\n\n\n/**\n * Starts the channel. This initiates connections to the server.\n *\n * @param {string} channelPath The path for the channel connection.\n * @param {!Object=} opt_extraParams Extra parameter keys and values to add to\n * the requests.\n * @param {string=} opt_oldSessionId Session ID from a previous session.\n * @param {number=} opt_oldArrayId The last array ID from a previous session.\n */\nWebChannelBase.prototype.connect = function(\n channelPath, opt_extraParams, opt_oldSessionId, opt_oldArrayId) {\n 'use strict';\n this.channelDebug_.debug('connect()');\n\n this.startOriginTrials_(channelPath);\n\n requestStats.notifyStatEvent(requestStats.Stat.CONNECT_ATTEMPT);\n\n this.path_ = channelPath;\n this.extraParams_ = opt_extraParams || {};\n\n // Attach parameters about the previous session if reconnecting.\n if (opt_oldSessionId && opt_oldArrayId !== undefined) {\n this.extraParams_['OSID'] = opt_oldSessionId;\n this.extraParams_['OAID'] = opt_oldArrayId;\n }\n\n this.enableStreaming_ = this.allowStreamingMode_;\n this.connectChannel_();\n};\n\n\n/**\n * Disconnects and closes the channel.\n */\nWebChannelBase.prototype.disconnect = function() {\n 'use strict';\n this.channelDebug_.debug('disconnect()');\n\n this.cancelRequests_();\n\n if (this.state_ == WebChannelBase.State.OPENED) {\n const rid = this.nextRid_++;\n const uri = this.forwardChannelUri_.clone();\n uri.setParameterValue('SID', this.sid_);\n uri.setParameterValue('RID', rid);\n uri.setParameterValue('TYPE', 'terminate');\n\n this.addAdditionalParams_(uri);\n\n const request = ChannelRequest.createChannelRequest(\n this, this.channelDebug_, this.sid_, rid);\n request.sendCloseRequest(uri);\n }\n\n this.onClose_();\n};\n\n\n/**\n * Returns the session id of the channel. Only available after the\n * channel has been opened.\n * @return {string} Session ID.\n */\nWebChannelBase.prototype.getSessionId = function() {\n 'use strict';\n return this.sid_;\n};\n\n\n/**\n * Starts the connection.\n * @private\n */\nWebChannelBase.prototype.connectChannel_ = function() {\n 'use strict';\n this.channelDebug_.debug('connectChannel_()');\n this.ensureInState_(WebChannelBase.State.INIT, WebChannelBase.State.CLOSED);\n this.forwardChannelUri_ =\n this.getForwardChannelUri(/** @type {string} */ (this.path_));\n this.ensureForwardChannel_();\n};\n\n\n/**\n * Starts the Origin Trials.\n * @param {string} channelPath The path for the channel connection.\n * @private\n */\nWebChannelBase.prototype.startOriginTrials_ = function(channelPath) {\n 'use strict';\n\n if (!this.enableOriginTrials_) {\n return;\n }\n\n this.channelDebug_.info('Origin Trials enabled.');\n goog.async.run(goog.bind(this.runOriginTrials_, this, channelPath));\n};\n\n\n/**\n * Runs the Origin Trials.\n * @param {string} channelPath The path for the channel connection.\n * @private\n */\nWebChannelBase.prototype.runOriginTrials_ = function(channelPath) {\n 'use strict';\n\n try {\n // Since startOriginTrials might throw exceptions asynchronously, we should\n // capture it in promise-catch.\n environment.startOriginTrials(channelPath, e => {\n this.channelDebug_.dumpException(\n /** @type {?Error} */ (e), 'Error in running origin trials');\n });\n this.channelDebug_.info('Origin Trials invoked: ' + channelPath);\n } catch (e) {\n this.channelDebug_.dumpException(e, 'Error in running origin trials');\n }\n};\n\n\n/**\n * Cancels backchannel request.\n * @private\n */\nWebChannelBase.prototype.cancelBackChannelRequest_ = function() {\n 'use strict';\n if (this.backChannelRequest_) {\n this.clearBpDetectionTimer_();\n this.backChannelRequest_.cancel();\n this.backChannelRequest_ = null;\n }\n};\n\n\n/**\n * Cancels all outstanding requests.\n * @private\n */\nWebChannelBase.prototype.cancelRequests_ = function() {\n 'use strict';\n this.cancelBackChannelRequest_();\n\n if (this.backChannelTimerId_) {\n goog.global.clearTimeout(this.backChannelTimerId_);\n this.backChannelTimerId_ = null;\n }\n\n this.clearDeadBackchannelTimer_();\n\n this.forwardChannelRequestPool_.cancel();\n\n if (this.forwardChannelTimerId_) {\n this.clearForwardChannelTimer_();\n }\n};\n\n\n/**\n * Clears the forward channel timer.\n * @private\n */\nWebChannelBase.prototype.clearForwardChannelTimer_ = function() {\n 'use strict';\n if (typeof this.forwardChannelTimerId_ === 'number') {\n goog.global.clearTimeout(this.forwardChannelTimerId_);\n }\n\n this.forwardChannelTimerId_ = null;\n};\n\n\n/**\n * Returns the extra HTTP headers to add to all the requests sent to the server.\n *\n * @return {Object} The HTTP headers, or null.\n */\nWebChannelBase.prototype.getExtraHeaders = function() {\n 'use strict';\n return this.extraHeaders_;\n};\n\n\n/**\n * Sets extra HTTP headers to add to all the requests sent to the server.\n *\n * @param {Object} extraHeaders The HTTP headers, or null.\n */\nWebChannelBase.prototype.setExtraHeaders = function(extraHeaders) {\n 'use strict';\n this.extraHeaders_ = extraHeaders;\n};\n\n\n/**\n * Returns the extra HTTP headers to add to the init requests\n * sent to the server.\n *\n * @return {Object} The HTTP headers, or null.\n */\nWebChannelBase.prototype.getInitHeaders = function() {\n 'use strict';\n return this.initHeaders_;\n};\n\n\n/**\n * Sets extra HTTP headers to add to the init requests sent to the server.\n *\n * @param {Object} initHeaders The HTTP headers, or null.\n */\nWebChannelBase.prototype.setInitHeaders = function(initHeaders) {\n 'use strict';\n this.initHeaders_ = initHeaders;\n};\n\n\n/**\n * Sets the URL param name to overwrite custom HTTP headers.\n *\n * @param {string} httpHeadersOverwriteParam The URL param name.\n */\nWebChannelBase.prototype.setHttpHeadersOverwriteParam = function(\n httpHeadersOverwriteParam) {\n 'use strict';\n this.httpHeadersOverwriteParam_ = httpHeadersOverwriteParam;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.setHttpSessionIdParam = function(httpSessionIdParam) {\n 'use strict';\n this.httpSessionIdParam_ = httpSessionIdParam;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getHttpSessionIdParam = function() {\n 'use strict';\n return this.httpSessionIdParam_;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.setHttpSessionId = function(httpSessionId) {\n 'use strict';\n this.httpSessionId_ = httpSessionId;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getHttpSessionId = function() {\n 'use strict';\n return this.httpSessionId_;\n};\n\n\n/**\n * Sets the throttle for handling onreadystatechange events for the request.\n *\n * @param {number} throttle The throttle in ms. A value of zero indicates\n * no throttle.\n */\nWebChannelBase.prototype.setReadyStateChangeThrottle = function(throttle) {\n 'use strict';\n this.readyStateChangeThrottleMs_ = throttle;\n};\n\n\n/**\n * Sets whether cross origin requests are supported for the channel.\n *\n * Setting this allows the creation of requests to secondary domains and\n * sends XHRs with the CORS withCredentials bit set to true.\n *\n * In order for cross-origin requests to work, the server will also need to set\n * CORS response headers as per:\n * https://developer.mozilla.org/en-US/docs/HTTP_access_control\n *\n * See {@link goog.net.XhrIo#setWithCredentials}.\n * @param {boolean} supportCrossDomain Whether cross domain XHRs are supported.\n */\nWebChannelBase.prototype.setSupportsCrossDomainXhrs = function(\n supportCrossDomain) {\n 'use strict';\n this.supportsCrossDomainXhrs_ = supportCrossDomain;\n};\n\n\n/**\n * Returns the handler used for channel callback events.\n *\n * @return {WebChannelBase.Handler} The handler.\n */\nWebChannelBase.prototype.getHandler = function() {\n 'use strict';\n return this.handler_;\n};\n\n\n/**\n * Sets the handler used for channel callback events.\n * @param {WebChannelBase.Handler} handler The handler to set.\n */\nWebChannelBase.prototype.setHandler = function(handler) {\n 'use strict';\n this.handler_ = handler;\n};\n\n\n/**\n * Returns whether the channel allows the use of a subdomain. There may be\n * cases where this isn't allowed.\n * @return {boolean} Whether a host prefix is allowed.\n */\nWebChannelBase.prototype.getAllowHostPrefix = function() {\n 'use strict';\n return this.allowHostPrefix_;\n};\n\n\n/**\n * Sets whether the channel allows the use of a subdomain. There may be cases\n * where this isn't allowed, for example, logging in with troutboard where\n * using a subdomain causes Apache to force the user to authenticate twice.\n * @param {boolean} allowHostPrefix Whether a host prefix is allowed.\n */\nWebChannelBase.prototype.setAllowHostPrefix = function(allowHostPrefix) {\n 'use strict';\n this.allowHostPrefix_ = allowHostPrefix;\n};\n\n\n/**\n * Returns whether the channel is buffered or not. This may be\n * queried in the WebChannelBase.okToMakeRequest() callback.\n *\n * @return {boolean} Whether the channel is buffered.\n */\nWebChannelBase.prototype.isBuffered = function() {\n 'use strict';\n return !this.enableStreaming_;\n};\n\n\n/**\n * Returns whether streaming mode is allowed. In certain debugging situations,\n * it's useful for the application to have a way to disable streaming mode for a\n * user.\n\n * @return {boolean} Whether streaming mode is allowed.\n */\nWebChannelBase.prototype.getAllowStreamingMode = function() {\n 'use strict';\n return this.allowStreamingMode_;\n};\n\n\n/**\n * Sets whether streaming mode is allowed. In certain debugging situations, it's\n * useful for the application to have a way to disable streaming mode for a\n * user.\n * @param {boolean} allowStreamingMode Whether streaming mode is allowed.\n */\nWebChannelBase.prototype.setAllowStreamingMode = function(allowStreamingMode) {\n 'use strict';\n this.allowStreamingMode_ = allowStreamingMode;\n};\n\n\n/**\n * Sends a request to the server. The format of the request is a Map data\n * structure of key/value pairs. These maps are then encoded in a format\n * suitable for the wire and then reconstituted as a Map data structure that\n * the server can process.\n * @param {!Object|!goog.collections.maps.MapLike} map The map to send.\n * @param {!Object=} opt_context The context associated with the map.\n */\nWebChannelBase.prototype.sendMap = function(map, opt_context) {\n 'use strict';\n goog.asserts.assert(\n this.state_ != WebChannelBase.State.CLOSED,\n 'Invalid operation: sending map when state is closed');\n\n // We can only send 1000 maps per POST, but typically we should never have\n // that much to send, so warn if we exceed that (we still send all the maps).\n if (this.outgoingMaps_.length == WebChannelBase.MAX_MAPS_PER_REQUEST_) {\n // severe() is temporary so that we get these uploaded and can figure out\n // what's causing them. Afterwards can change to warning().\n this.channelDebug_.severe(function() {\n 'use strict';\n return 'Already have ' + WebChannelBase.MAX_MAPS_PER_REQUEST_ +\n ' queued maps upon queueing ' + goog.json.serialize(map);\n });\n }\n\n this.outgoingMaps_.push(\n new Wire.QueuedMap(this.nextMapId_++, map, opt_context));\n\n // Messages need be buffered during OPENING to avoid server-side race\n if (this.state_ == WebChannelBase.State.OPENED) {\n this.ensureForwardChannel_();\n }\n};\n\n\n/**\n * When set to true, this changes the behavior of the forward channel so it\n * will not retry requests; it will fail after one network failure, and if\n * there was already one network failure, the request will fail immediately.\n * @param {boolean} failFast Whether or not to fail fast.\n */\nWebChannelBase.prototype.setFailFast = function(failFast) {\n 'use strict';\n this.failFast_ = failFast;\n this.channelDebug_.info('setFailFast: ' + failFast);\n if ((this.forwardChannelRequestPool_.hasPendingRequest() ||\n this.forwardChannelTimerId_) &&\n this.forwardChannelRetryCount_ > this.getForwardChannelMaxRetries()) {\n const self = this;\n this.channelDebug_.info(function() {\n 'use strict';\n return 'Retry count ' + self.forwardChannelRetryCount_ +\n ' > new maxRetries ' + self.getForwardChannelMaxRetries() +\n '. Fail immediately!';\n });\n\n if (!this.forwardChannelRequestPool_.forceComplete(\n goog.bind(this.onRequestComplete, this))) {\n // i.e., this.forwardChannelTimerId_\n this.clearForwardChannelTimer_();\n // The error code from the last failed request is gone, so just use a\n // generic one.\n this.signalError_(WebChannelBase.Error.REQUEST_FAILED);\n }\n }\n};\n\n\n/**\n * @return {number} The max number of forward-channel retries, which will be 0\n * in fail-fast mode.\n */\nWebChannelBase.prototype.getForwardChannelMaxRetries = function() {\n 'use strict';\n return this.failFast_ ? 0 : this.forwardChannelMaxRetries_;\n};\n\n\n/**\n * Sets the maximum number of attempts to connect to the server for forward\n * channel requests.\n * @param {number} retries The maximum number of attempts.\n */\nWebChannelBase.prototype.setForwardChannelMaxRetries = function(retries) {\n 'use strict';\n this.forwardChannelMaxRetries_ = retries;\n};\n\n\n/**\n * Sets the timeout for a forward channel request.\n * @param {number} timeoutMs The timeout in milliseconds.\n */\nWebChannelBase.prototype.setForwardChannelRequestTimeout = function(timeoutMs) {\n 'use strict';\n this.forwardChannelRequestTimeoutMs_ = timeoutMs;\n};\n\n\n/**\n * @return {number} The max number of back-channel retries, which is a constant.\n */\nWebChannelBase.prototype.getBackChannelMaxRetries = function() {\n 'use strict';\n // Back-channel retries is a constant.\n return WebChannelBase.BACK_CHANNEL_MAX_RETRIES;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.isClosed = function() {\n 'use strict';\n return this.state_ == WebChannelBase.State.CLOSED;\n};\n\n\n/**\n * Returns the channel state.\n * @return {WebChannelBase.State} The current state of the channel.\n */\nWebChannelBase.prototype.getState = function() {\n 'use strict';\n return this.state_;\n};\n\n\n/**\n * @return {!Object<string, string>|undefined} The response headers received\n * along with the non-200 status.\n */\nWebChannelBase.prototype.getLastResponseHeaders = function() {\n 'use strict';\n return this.errorResponseHeaders_;\n};\n\n\n/**\n * @return {number} The non-200 status code received that causes the channel to\n * be aborted.\n */\nWebChannelBase.prototype.getLastStatusCode = function() {\n 'use strict';\n return this.errorResponseStatusCode_;\n};\n\n\n/**\n * @return {number} The last array id received.\n */\nWebChannelBase.prototype.getLastArrayId = function() {\n 'use strict';\n return this.lastArrayId_;\n};\n\n\n/**\n * Returns whether there are outstanding requests servicing the channel.\n * @return {boolean} true if there are outstanding requests.\n */\nWebChannelBase.prototype.hasOutstandingRequests = function() {\n 'use strict';\n return this.getOutstandingRequests_() != 0;\n};\n\n\n/**\n * Returns the number of outstanding requests.\n * @return {number} The number of outstanding requests to the server.\n * @private\n */\nWebChannelBase.prototype.getOutstandingRequests_ = function() {\n 'use strict';\n let count = 0;\n if (this.backChannelRequest_) {\n count++;\n }\n count += this.forwardChannelRequestPool_.getRequestCount();\n return count;\n};\n\n\n/**\n * Ensures that a forward channel request is scheduled.\n * @private\n */\nWebChannelBase.prototype.ensureForwardChannel_ = function() {\n 'use strict';\n if (this.forwardChannelRequestPool_.isFull()) {\n // enough connection in process - no need to start a new request\n return;\n }\n\n if (this.forwardChannelTimerId_) {\n // no need to start a new request - one is already scheduled\n return;\n }\n\n // Use async.run instead of setTimeout(0) to avoid the 1s message delay\n // from chrome/firefox background tabs\n this.forwardChannelTimerId_ = true;\n goog.async.run(this.onStartForwardChannelTimer_, this);\n\n this.forwardChannelRetryCount_ = 0;\n};\n\n\n/**\n * Schedules a forward-channel retry for the specified request, unless the max\n * retries has been reached.\n * @param {!ChannelRequest} request The failed request to retry.\n * @return {boolean} true iff a retry was scheduled.\n * @private\n */\nWebChannelBase.prototype.maybeRetryForwardChannel_ = function(request) {\n 'use strict';\n if (this.forwardChannelRequestPool_.getRequestCount() >=\n this.forwardChannelRequestPool_.getMaxSize() -\n (this.forwardChannelTimerId_ ? 1 : 0)) {\n // Should be impossible to be called in this state.\n this.channelDebug_.severe('Unexpected retry request is scheduled.');\n return false;\n }\n\n if (this.forwardChannelTimerId_) {\n this.channelDebug_.debug(\n 'Use the retry request that is already scheduled.');\n this.outgoingMaps_ =\n request.getPendingMessages().concat(this.outgoingMaps_);\n return true;\n }\n\n // No retry for open_() and fail-fast\n if (this.state_ == WebChannelBase.State.INIT ||\n this.state_ == WebChannelBase.State.OPENING ||\n (this.forwardChannelRetryCount_ >= this.getForwardChannelMaxRetries())) {\n return false;\n }\n\n this.channelDebug_.debug('Going to retry POST');\n\n this.forwardChannelTimerId_ = requestStats.setTimeout(\n goog.bind(this.onStartForwardChannelTimer_, this, request),\n this.getRetryTime_(this.forwardChannelRetryCount_));\n this.forwardChannelRetryCount_++;\n return true;\n};\n\n\n/**\n * Timer callback for ensureForwardChannel\n * @param {ChannelRequest=} opt_retryRequest A failed request\n * to retry.\n * @private\n */\nWebChannelBase.prototype.onStartForwardChannelTimer_ = function(\n opt_retryRequest) {\n 'use strict';\n // null is possible if scheduled with async.run\n if (this.forwardChannelTimerId_) {\n this.forwardChannelTimerId_ = null;\n this.startForwardChannel_(opt_retryRequest);\n }\n};\n\n\n/**\n * Begins a new forward channel operation to the server.\n * @param {ChannelRequest=} opt_retryRequest A failed request to retry.\n * @private\n */\nWebChannelBase.prototype.startForwardChannel_ = function(opt_retryRequest) {\n 'use strict';\n this.channelDebug_.debug('startForwardChannel_');\n if (!this.okToMakeRequest_()) {\n return; // channel is cancelled\n } else if (this.state_ == WebChannelBase.State.INIT) {\n if (opt_retryRequest) {\n this.channelDebug_.severe('Not supposed to retry the open');\n return;\n }\n this.open_();\n this.state_ = WebChannelBase.State.OPENING;\n } else if (this.state_ == WebChannelBase.State.OPENED) {\n if (opt_retryRequest) {\n this.makeForwardChannelRequest_(opt_retryRequest);\n return;\n }\n\n if (this.outgoingMaps_.length == 0) {\n this.channelDebug_.debug(\n 'startForwardChannel_ returned: ' +\n 'nothing to send');\n // no need to start a new forward channel request\n return;\n }\n\n if (this.forwardChannelRequestPool_.isFull()) {\n // Should be impossible to be called in this state.\n this.channelDebug_.severe(\n 'startForwardChannel_ returned: ' +\n 'connection already in progress');\n return;\n }\n\n this.makeForwardChannelRequest_();\n this.channelDebug_.debug('startForwardChannel_ finished, sent request');\n }\n};\n\n\n/**\n * Establishes a new channel session with the server.\n * @private\n */\nWebChannelBase.prototype.open_ = function() {\n 'use strict';\n this.channelDebug_.debug('open_()');\n this.nextRid_ = Math.floor(Math.random() * 100000);\n\n const rid = this.nextRid_++;\n const request =\n ChannelRequest.createChannelRequest(this, this.channelDebug_, '', rid);\n\n // mix the init headers\n let extraHeaders = this.extraHeaders_;\n if (this.initHeaders_) {\n if (extraHeaders) {\n extraHeaders = goog.object.clone(extraHeaders);\n goog.object.extend(extraHeaders, this.initHeaders_);\n } else {\n extraHeaders = this.initHeaders_;\n }\n }\n\n if (this.httpHeadersOverwriteParam_ === null &&\n !this.encodeInitMessageHeaders_) {\n request.setExtraHeaders(extraHeaders);\n extraHeaders = null;\n }\n\n let requestText = this.dequeueOutgoingMaps_(\n request,\n this.fastHandshake_ ? this.getMaxNumMessagesForFastHandshake_() :\n WebChannelBase.MAX_MAPS_PER_REQUEST_);\n\n const uri = this.forwardChannelUri_.clone();\n uri.setParameterValue('RID', rid);\n\n if (this.clientVersion_ > 0) {\n uri.setParameterValue('CVER', this.clientVersion_);\n }\n\n // http-session-id to be generated as the response\n if (this.getHttpSessionIdParam()) {\n uri.setParameterValue(\n WebChannel.X_HTTP_SESSION_ID, this.getHttpSessionIdParam());\n }\n\n this.addAdditionalParams_(uri);\n\n if (extraHeaders) {\n if (this.encodeInitMessageHeaders_) {\n let encodedHeaders =\n httpCors.generateEncodedHttpHeadersOverwriteParam(extraHeaders);\n requestText = 'headers=' + encodedHeaders + '&' + requestText;\n } else if (this.httpHeadersOverwriteParam_) {\n httpCors.setHttpHeadersWithOverwriteParam(\n uri, this.httpHeadersOverwriteParam_, extraHeaders);\n } // else - should not happen\n }\n\n this.forwardChannelRequestPool_.addRequest(request);\n\n if (this.blockingHandshake_) {\n uri.setParameterValue('TYPE', 'init'); // default to blocking in future\n }\n\n // Check the option and use GET to enable QUIC 0-RTT\n if (this.fastHandshake_) {\n uri.setParameterValue('$req', requestText);\n\n // enable handshake upgrade\n uri.setParameterValue('SID', 'null');\n request.setDecodeInitialResponse();\n\n request.xmlHttpPost(uri, null, true); // Send as a GET\n } else {\n request.xmlHttpPost(uri, requestText, true);\n }\n};\n\n\n/**\n * @return {number} The number of raw JSON messages to be encoded\n * with the fast-handshake (GET) request, including zero. If messages are not\n * encoded as raw JSON data, return WebChannelBase.MAX_MAPS_PER_REQUEST_\n * @private\n */\nWebChannelBase.prototype.getMaxNumMessagesForFastHandshake_ = function() {\n 'use strict';\n let total = 0;\n for (let i = 0; i < this.outgoingMaps_.length; i++) {\n const map = this.outgoingMaps_[i];\n const size = map.getRawDataSize();\n if (size === undefined) {\n break;\n }\n total += size;\n\n if (total > WebChannelBase.MAX_CHARS_PER_GET_) {\n return i;\n }\n\n if (total === WebChannelBase.MAX_CHARS_PER_GET_ ||\n i === this.outgoingMaps_.length - 1) {\n return i + 1;\n }\n }\n\n return WebChannelBase.MAX_MAPS_PER_REQUEST_;\n};\n\n\n\n/**\n * Makes a forward channel request using XMLHTTP.\n * @param {!ChannelRequest=} opt_retryRequest A failed request to retry.\n * @private\n */\nWebChannelBase.prototype.makeForwardChannelRequest_ = function(\n opt_retryRequest) {\n 'use strict';\n let rid;\n if (opt_retryRequest) {\n rid = opt_retryRequest.getRequestId(); // Reuse the same RID for a retry\n } else {\n rid = this.nextRid_++;\n }\n\n const uri = this.forwardChannelUri_.clone();\n uri.setParameterValue('SID', this.sid_);\n uri.setParameterValue('RID', rid);\n uri.setParameterValue('AID', this.lastArrayId_);\n\n this.addAdditionalParams_(uri);\n\n if (this.httpHeadersOverwriteParam_ && this.extraHeaders_) {\n httpCors.setHttpHeadersWithOverwriteParam(\n uri, this.httpHeadersOverwriteParam_, this.extraHeaders_);\n }\n\n const request = ChannelRequest.createChannelRequest(\n this, this.channelDebug_, this.sid_, rid,\n this.forwardChannelRetryCount_ + 1);\n\n if (this.httpHeadersOverwriteParam_ === null) {\n request.setExtraHeaders(this.extraHeaders_);\n }\n\n let requestText;\n if (opt_retryRequest) {\n this.requeuePendingMaps_(opt_retryRequest);\n }\n requestText =\n this.dequeueOutgoingMaps_(request, WebChannelBase.MAX_MAPS_PER_REQUEST_);\n\n // Randomize from 50%-100% of the forward channel timeout to avoid\n // a big hit if servers happen to die at once.\n request.setTimeout(\n Math.round(this.forwardChannelRequestTimeoutMs_ * 0.50) +\n Math.round(this.forwardChannelRequestTimeoutMs_ * 0.50 * Math.random()));\n this.forwardChannelRequestPool_.addRequest(request);\n request.xmlHttpPost(uri, requestText, true);\n};\n\n\n/**\n * Adds additional query parameters from `extraParams_` and `handler_` to the\n * given URI.\n * @param {!goog.Uri} uri The URI to add the parameters to.\n * @private\n */\nWebChannelBase.prototype.addAdditionalParams_ = function(uri) {\n 'use strict';\n if (this.extraParams_) {\n goog.object.forEach(this.extraParams_, function(value, key) {\n 'use strict';\n uri.setParameterValue(key, value);\n });\n }\n\n if (this.handler_) {\n const params = this.handler_.getAdditionalParams(this);\n if (params) {\n goog.structs.forEach(params, function(value, key, coll) {\n 'use strict';\n uri.setParameterValue(key, value);\n });\n }\n }\n};\n\n\n/**\n * Returns the request text from the outgoing maps and resets it.\n * @param {!ChannelRequest} request The new request for sending the messages.\n * @param {number} maxNum The maximum number of messages to be encoded\n * @return {string} The encoded request text created from all the currently\n * queued outgoing maps.\n * @private\n */\nWebChannelBase.prototype.dequeueOutgoingMaps_ = function(request, maxNum) {\n 'use strict';\n const count = Math.min(this.outgoingMaps_.length, maxNum);\n\n const badMapHandler = this.handler_ ?\n goog.bind(this.handler_.badMapError, this.handler_, this) :\n null;\n const result = this.wireCodec_.encodeMessageQueue(\n this.outgoingMaps_, count, badMapHandler);\n\n request.setPendingMessages(this.outgoingMaps_.splice(0, count));\n\n return result;\n};\n\n\n/**\n * Requeues unacknowledged sent arrays for retransmission in the next forward\n * channel request.\n * @param {!ChannelRequest} retryRequest A failed request to retry.\n * @private\n */\nWebChannelBase.prototype.requeuePendingMaps_ = function(retryRequest) {\n 'use strict';\n this.outgoingMaps_ =\n retryRequest.getPendingMessages().concat(this.outgoingMaps_);\n};\n\n\n/**\n * Ensures there is a backchannel request for receiving data from the server.\n * @private\n */\nWebChannelBase.prototype.ensureBackChannel_ = function() {\n 'use strict';\n if (this.backChannelRequest_) {\n // already have one\n return;\n }\n\n if (this.backChannelTimerId_) {\n // no need to start a new request - one is already scheduled\n return;\n }\n\n this.backChannelAttemptId_ = 1;\n\n // Use async.run instead of setTimeout(0) to avoid the 1s message delay\n // from chrome/firefox background tabs\n // backChannelTimerId_ stays unset, as with setTimeout(0)\n goog.async.run(this.onStartBackChannelTimer_, this);\n\n this.backChannelRetryCount_ = 0;\n};\n\n\n/**\n * Schedules a back-channel retry, unless the max retries has been reached.\n * @return {boolean} true iff a retry was scheduled.\n * @private\n */\nWebChannelBase.prototype.maybeRetryBackChannel_ = function() {\n 'use strict';\n if (this.backChannelRequest_ || this.backChannelTimerId_) {\n // Should be impossible to be called in this state.\n this.channelDebug_.severe('Request already in progress');\n return false;\n }\n\n if (this.backChannelRetryCount_ >= this.getBackChannelMaxRetries()) {\n return false;\n }\n\n this.channelDebug_.debug('Going to retry GET');\n\n this.backChannelAttemptId_++;\n this.backChannelTimerId_ = requestStats.setTimeout(\n goog.bind(this.onStartBackChannelTimer_, this),\n this.getRetryTime_(this.backChannelRetryCount_));\n this.backChannelRetryCount_++;\n return true;\n};\n\n\n/**\n * Timer callback for ensureBackChannel_.\n * @private\n */\nWebChannelBase.prototype.onStartBackChannelTimer_ = function() {\n 'use strict';\n this.backChannelTimerId_ = null;\n this.startBackChannel_();\n\n if (!this.detectBufferingProxy_) {\n return;\n }\n\n if (this.bpDetectionDone_) {\n return;\n }\n\n if (this.backChannelRequest_ == null || this.handshakeRttMs_ <= 0) {\n this.channelDebug_.warning(\n 'Skip bpDetectionTimerId_ ' + this.backChannelRequest_ + ' ' +\n this.handshakeRttMs_);\n return;\n }\n\n // This goes with each new request until bpDetectionDone_\n const bpDetectionTimeout = 2 * this.handshakeRttMs_;\n this.channelDebug_.info('BP detection timer enabled: ' + bpDetectionTimeout);\n\n this.bpDetectionTimerId_ = requestStats.setTimeout(\n goog.bind(this.onBpDetectionTimer_, this), bpDetectionTimeout);\n};\n\n\n/**\n * Timer callback for bpDetection.\n * @private\n */\nWebChannelBase.prototype.onBpDetectionTimer_ = function() {\n 'use strict';\n if (!this.bpDetectionTimerId_) {\n this.channelDebug_.warning('Invalid operation.');\n return;\n }\n\n this.bpDetectionTimerId_ = null;\n this.channelDebug_.info('BP detection timeout reached.');\n\n goog.asserts.assert(\n this.backChannelRequest_ != null,\n 'Invalid state: no backchannel request');\n\n // We wait for extra response payload in addition to just headers to\n // cancel the timer.\n if (this.backChannelRequest_.getXhr() != null) {\n const responseData = this.backChannelRequest_.getXhr().getResponseText();\n if (responseData) {\n this.channelDebug_.warning(\n 'Timer should have been cancelled : ' + responseData);\n }\n }\n\n // Enable long-polling\n this.channelDebug_.info(\n 'Buffering proxy detected and switch to long-polling!');\n this.enableStreaming_ = false;\n\n this.bpDetectionDone_ = true;\n requestStats.notifyStatEvent(requestStats.Stat.PROXY);\n\n // Cancel the request and start a new one immediately\n this.cancelBackChannelRequest_();\n this.startBackChannel_();\n};\n\n\n/**\n * Clears the timer for BP detection.\n * @private\n */\nWebChannelBase.prototype.clearBpDetectionTimer_ = function() {\n 'use strict';\n if (this.bpDetectionTimerId_ != null) {\n this.channelDebug_.debug('Cancel the BP detection timer.');\n goog.global.clearTimeout(this.bpDetectionTimerId_);\n this.bpDetectionTimerId_ = null;\n }\n};\n\n\n/**\n * Begins a new back channel operation to the server.\n * @private\n */\nWebChannelBase.prototype.startBackChannel_ = function() {\n 'use strict';\n if (!this.okToMakeRequest_()) {\n // channel is cancelled\n return;\n }\n\n this.channelDebug_.debug('Creating new HttpRequest');\n this.backChannelRequest_ = ChannelRequest.createChannelRequest(\n this, this.channelDebug_, this.sid_, 'rpc', this.backChannelAttemptId_);\n\n if (this.httpHeadersOverwriteParam_ === null) {\n this.backChannelRequest_.setExtraHeaders(this.extraHeaders_);\n }\n\n this.backChannelRequest_.setReadyStateChangeThrottle(\n this.readyStateChangeThrottleMs_);\n const uri = this.backChannelUri_.clone();\n uri.setParameterValue('RID', 'rpc');\n uri.setParameterValue('SID', this.sid_);\n uri.setParameterValue('AID', this.lastArrayId_);\n\n uri.setParameterValue('CI', this.enableStreaming_ ? '0' : '1');\n if (!this.enableStreaming_ && this.longPollingTimeout_) {\n uri.setParameterValue('TO', this.longPollingTimeout_);\n }\n\n uri.setParameterValue('TYPE', 'xmlhttp');\n\n this.addAdditionalParams_(uri);\n\n if (this.httpHeadersOverwriteParam_ && this.extraHeaders_) {\n httpCors.setHttpHeadersWithOverwriteParam(\n uri, this.httpHeadersOverwriteParam_, this.extraHeaders_);\n }\n\n if (this.backChannelRequestTimeoutMs_) {\n this.backChannelRequest_.setTimeout(this.backChannelRequestTimeoutMs_);\n }\n\n this.backChannelRequest_.xmlHttpGet(\n uri, true /* decodeChunks */, this.hostPrefix_);\n\n this.channelDebug_.debug('New Request created');\n};\n\n\n/**\n * Gives the handler a chance to return an error code and stop channel\n * execution. A handler might want to do this to check that the user is still\n * logged in, for example.\n * @private\n * @return {boolean} If it's OK to make a request.\n */\nWebChannelBase.prototype.okToMakeRequest_ = function() {\n 'use strict';\n if (this.handler_) {\n const result = this.handler_.okToMakeRequest(this);\n if (result != WebChannelBase.Error.OK) {\n this.channelDebug_.debug(\n 'Handler returned error code from okToMakeRequest');\n this.signalError_(result);\n return false;\n }\n }\n return true;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.onFirstByteReceived = function(request, responseText) {\n 'use strict';\n if (this.backChannelRequest_ == request && this.detectBufferingProxy_) {\n if (!this.bpDetectionDone_) {\n this.channelDebug_.info(\n 'Great, no buffering proxy detected. Bytes received: ' +\n responseText.length);\n goog.asserts.assert(\n this.bpDetectionTimerId_, 'Timer should not have been cancelled.');\n this.clearBpDetectionTimer_();\n this.bpDetectionDone_ = true;\n requestStats.notifyStatEvent(requestStats.Stat.NOPROXY);\n }\n }\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.onRequestData = function(request, responseText) {\n 'use strict';\n if (this.state_ == WebChannelBase.State.CLOSED ||\n (this.backChannelRequest_ != request &&\n !this.forwardChannelRequestPool_.hasRequest(request))) {\n // either CLOSED or a request we don't know about (perhaps an old request)\n return;\n }\n\n // first to check if request has been upgraded to backchannel\n if (!request.isInitialResponseDecoded() &&\n this.forwardChannelRequestPool_.hasRequest(request) &&\n this.state_ == WebChannelBase.State.OPENED) {\n let response;\n try {\n response = this.wireCodec_.decodeMessage(responseText);\n } catch (ex) {\n response = null;\n }\n if (Array.isArray(response) && response.length == 3) {\n this.handlePostResponse_(/** @type {!Array<?>} */ (response), request);\n this.onForwardChannelFlushed_();\n } else {\n this.channelDebug_.debug('Bad POST response data returned');\n this.signalError_(WebChannelBase.Error.BAD_RESPONSE);\n }\n } else {\n if (request.isInitialResponseDecoded() ||\n this.backChannelRequest_ == request) {\n this.clearDeadBackchannelTimer_();\n }\n\n if (!goog.string.isEmptyOrWhitespace(responseText)) {\n let response = this.wireCodec_.decodeMessage(responseText);\n this.onInput_(/** @type {!Array<?>} */ (response), request);\n }\n }\n};\n\n\n/**\n * Checks if we need call the flush callback.\n *\n * @private\n */\nWebChannelBase.prototype.onForwardChannelFlushed_ = function() {\n 'use strict';\n if (this.forwardChannelRequestPool_.getRequestCount() <= 1) {\n if (this.forwardChannelFlushedCallback_) {\n try {\n this.forwardChannelFlushedCallback_();\n } catch (ex) {\n this.channelDebug_.dumpException(\n ex, 'Exception from forwardChannelFlushedCallback_ ');\n }\n // reset\n this.forwardChannelFlushedCallback_ = undefined;\n }\n }\n};\n\n\n/**\n * Handles a POST response from the server.\n * @param {Array<number>} responseValues The key value pairs in\n * the POST response.\n * @param {!ChannelRequest} forwardReq The forward channel request that\n * triggers this function call.\n * @private\n */\nWebChannelBase.prototype.handlePostResponse_ = function(\n responseValues, forwardReq) {\n 'use strict';\n // The first response value is set to 0 if server is missing backchannel.\n if (responseValues[0] == 0) {\n this.handleBackchannelMissing_(forwardReq);\n return;\n }\n this.lastPostResponseArrayId_ = responseValues[1];\n const outstandingArrays = this.lastPostResponseArrayId_ - this.lastArrayId_;\n if (0 < outstandingArrays) {\n const numOutstandingBackchannelBytes = responseValues[2];\n this.channelDebug_.debug(\n numOutstandingBackchannelBytes + ' bytes (in ' + outstandingArrays +\n ' arrays) are outstanding on the BackChannel');\n if (!this.shouldRetryBackChannel_(numOutstandingBackchannelBytes)) {\n return;\n }\n if (!this.deadBackChannelTimerId_) {\n // We expect to receive data within 2 RTTs or we retry the backchannel.\n this.deadBackChannelTimerId_ = requestStats.setTimeout(\n goog.bind(this.onBackChannelDead_, this),\n 2 * WebChannelBase.RTT_ESTIMATE);\n }\n }\n};\n\n\n/**\n * Handles a POST response from the server telling us that it has detected that\n * we have no hanging GET connection.\n * @param {!ChannelRequest} forwardReq The forward channel request that\n * triggers this function call.\n * @private\n * @suppress {strictPrimitiveOperators}\n */\nWebChannelBase.prototype.handleBackchannelMissing_ = function(forwardReq) {\n 'use strict';\n // As long as the back channel was started before the POST was sent,\n // we should retry the backchannel. We give a slight buffer of RTT_ESTIMATE\n // so as not to excessively retry the backchannel\n this.channelDebug_.debug('Server claims our backchannel is missing.');\n if (this.backChannelTimerId_) {\n this.channelDebug_.debug('But we are currently starting the request.');\n return;\n } else if (!this.backChannelRequest_) {\n this.channelDebug_.warning('We do not have a BackChannel established');\n } else if (\n this.backChannelRequest_.getRequestStartTime() +\n WebChannelBase.RTT_ESTIMATE <\n forwardReq.getRequestStartTime()) {\n this.clearDeadBackchannelTimer_();\n this.cancelBackChannelRequest_();\n } else {\n return;\n }\n this.maybeRetryBackChannel_();\n requestStats.notifyStatEvent(requestStats.Stat.BACKCHANNEL_MISSING);\n};\n\n\n/**\n * Determines whether we should start the process of retrying a possibly\n * dead backchannel.\n * @param {number} outstandingBytes The number of bytes for which the server has\n * not yet received acknowledgement.\n * @return {boolean} Whether to start the backchannel retry timer.\n * @private\n */\nWebChannelBase.prototype.shouldRetryBackChannel_ = function(outstandingBytes) {\n 'use strict';\n // Not too many outstanding bytes, not buffered and not after a retry.\n return outstandingBytes <\n WebChannelBase.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF &&\n !this.isBuffered() && this.backChannelRetryCount_ == 0;\n};\n\n\n/**\n * Decides which host prefix should be used, if any. If there is a handler,\n * allows the handler to validate a host prefix provided by the server, and\n * optionally override it.\n * @param {?string} serverHostPrefix The host prefix provided by the server.\n * @return {?string} The host prefix to actually use, if any. Will return null\n * if the use of host prefixes was disabled via setAllowHostPrefix().\n * @override\n */\nWebChannelBase.prototype.correctHostPrefix = function(serverHostPrefix) {\n 'use strict';\n if (this.allowHostPrefix_) {\n if (this.handler_) {\n return this.handler_.correctHostPrefix(serverHostPrefix);\n }\n return serverHostPrefix;\n }\n return null;\n};\n\n\n/**\n * Handles the timer that indicates that our backchannel is no longer able to\n * successfully receive data from the server.\n * @private\n */\nWebChannelBase.prototype.onBackChannelDead_ = function() {\n 'use strict';\n if (this.deadBackChannelTimerId_ != null) {\n this.deadBackChannelTimerId_ = null;\n this.cancelBackChannelRequest_();\n this.maybeRetryBackChannel_();\n requestStats.notifyStatEvent(requestStats.Stat.BACKCHANNEL_DEAD);\n }\n};\n\n\n/**\n * Clears the timer that indicates that our backchannel is no longer able to\n * successfully receive data from the server.\n * @private\n */\nWebChannelBase.prototype.clearDeadBackchannelTimer_ = function() {\n 'use strict';\n if (this.deadBackChannelTimerId_ != null) {\n goog.global.clearTimeout(this.deadBackChannelTimerId_);\n this.deadBackChannelTimerId_ = null;\n }\n};\n\n\n/**\n * Returns whether or not the given error/status combination is fatal or not.\n * On fatal errors we immediately close the session rather than retrying the\n * failed request.\n * @param {?ChannelRequest.Error} error The error code for the\n * failed request.\n * @param {number} statusCode The last HTTP status code.\n * @return {boolean} Whether or not the error is fatal.\n * @private\n */\nWebChannelBase.isFatalError_ = function(error, statusCode) {\n 'use strict';\n return error == ChannelRequest.Error.UNKNOWN_SESSION_ID ||\n (error == ChannelRequest.Error.STATUS && statusCode > 0);\n};\n\n\n/**\n * @override\n * @suppress {strictPrimitiveOperators}\n */\nWebChannelBase.prototype.onRequestComplete = function(request) {\n 'use strict';\n this.channelDebug_.debug('Request complete');\n let type;\n let pendingMessages = null;\n if (this.backChannelRequest_ == request) {\n this.clearDeadBackchannelTimer_();\n this.clearBpDetectionTimer_();\n this.backChannelRequest_ = null;\n type = WebChannelBase.ChannelType_.BACK_CHANNEL;\n } else if (this.forwardChannelRequestPool_.hasRequest(request)) {\n pendingMessages = request.getPendingMessages();\n this.forwardChannelRequestPool_.removeRequest(request);\n type = WebChannelBase.ChannelType_.FORWARD_CHANNEL;\n } else {\n // return if it was an old request from a previous session\n return;\n }\n\n if (this.state_ == WebChannelBase.State.CLOSED) {\n return;\n }\n\n if (request.getSuccess()) {\n if (type == WebChannelBase.ChannelType_.FORWARD_CHANNEL) {\n const size = request.getPostData() ? request.getPostData().length : 0;\n requestStats.notifyTimingEvent(\n size, Date.now() - request.getRequestStartTime(),\n this.forwardChannelRetryCount_);\n this.ensureForwardChannel_();\n this.onSuccess_(request);\n } else { // i.e., back-channel\n this.ensureBackChannel_();\n }\n return;\n }\n // Else unsuccessful. Fall through.\n\n const lastStatusCode = request.getLastStatusCode();\n const lastError = request.getLastError();\n if (!WebChannelBase.isFatalError_(lastError, lastStatusCode)) {\n // Maybe retry.\n const self = this;\n this.channelDebug_.debug(function() {\n 'use strict';\n return 'Maybe retrying, last error: ' +\n ChannelRequest.errorStringFromCode(\n lastError, self.errorResponseStatusCode_);\n });\n if (type == WebChannelBase.ChannelType_.FORWARD_CHANNEL) {\n if (this.maybeRetryForwardChannel_(request)) {\n return;\n }\n }\n if (type == WebChannelBase.ChannelType_.BACK_CHANNEL) {\n if (this.maybeRetryBackChannel_()) {\n return;\n }\n }\n // Else exceeded max retries. Fall through.\n this.channelDebug_.debug('Exceeded max number of retries');\n } else {\n // Else fatal error. Fall through and mark the pending maps as failed.\n this.channelDebug_.debug('Not retrying due to error type');\n\n if (lastStatusCode > 200) {\n this.errorResponseStatusCode_ = request.getLastStatusCode();\n this.errorResponseHeaders_ = request.getErrorResponseHeaders();\n }\n }\n\n // Abort the channel now\n\n // Record pending messages from the failed request\n if (pendingMessages && pendingMessages.length > 0) {\n this.forwardChannelRequestPool_.addPendingMessages(pendingMessages);\n }\n\n this.channelDebug_.debug('Error: HTTP request failed');\n switch (lastError) {\n case ChannelRequest.Error.NO_DATA:\n this.signalError_(WebChannelBase.Error.NO_DATA);\n break;\n case ChannelRequest.Error.BAD_DATA:\n this.signalError_(WebChannelBase.Error.BAD_DATA);\n break;\n case ChannelRequest.Error.UNKNOWN_SESSION_ID:\n this.signalError_(WebChannelBase.Error.UNKNOWN_SESSION_ID);\n break;\n default:\n this.signalError_(WebChannelBase.Error.REQUEST_FAILED);\n break;\n }\n};\n\n\n/**\n * @param {number} retryCount Number of retries so far.\n * @return {number} Time in ms before firing next retry request.\n * @private\n */\nWebChannelBase.prototype.getRetryTime_ = function(retryCount) {\n 'use strict';\n let retryTime = this.baseRetryDelayMs_ +\n Math.floor(Math.random() * this.retryDelaySeedMs_);\n if (!this.isActive()) {\n this.channelDebug_.debug('Inactive channel');\n retryTime = retryTime * WebChannelBase.INACTIVE_CHANNEL_RETRY_FACTOR;\n }\n // Backoff for subsequent retries\n retryTime *= retryCount;\n return retryTime;\n};\n\n\n/**\n * @param {number} baseDelayMs The base part of the retry delay, in ms.\n * @param {number} delaySeedMs A random delay between 0 and this is added to\n * the base part.\n */\nWebChannelBase.prototype.setRetryDelay = function(baseDelayMs, delaySeedMs) {\n 'use strict';\n this.baseRetryDelayMs_ = baseDelayMs;\n this.retryDelaySeedMs_ = delaySeedMs;\n};\n\n\n/**\n * Apply any handshake control headers.\n * @param {!ChannelRequest} request The underlying request object\n * @private\n */\nWebChannelBase.prototype.applyControlHeaders_ = function(request) {\n 'use strict';\n const xhr = request.getXhr();\n if (xhr) {\n const clientProtocol =\n xhr.getStreamingResponseHeader(WebChannel.X_CLIENT_WIRE_PROTOCOL);\n if (clientProtocol) {\n this.forwardChannelRequestPool_.applyClientProtocol(clientProtocol);\n }\n\n if (this.getHttpSessionIdParam()) {\n const httpSessionIdHeader =\n xhr.getStreamingResponseHeader(WebChannel.X_HTTP_SESSION_ID);\n if (httpSessionIdHeader) {\n this.setHttpSessionId(httpSessionIdHeader);\n // update the cached uri\n const httpSessionIdParam = this.getHttpSessionIdParam();\n\n this.forwardChannelUri_.setParameterValue(\n /** @type {string} */ (httpSessionIdParam), // never null\n httpSessionIdHeader);\n } else {\n this.channelDebug_.warning(\n 'Missing X_HTTP_SESSION_ID in the handshake response');\n }\n }\n }\n};\n\n\n/**\n * Processes the data returned by the server.\n * @param {!Array<!Array<?>>} respArray The response array returned\n * by the server.\n * @param {!ChannelRequest} request The underlying request object\n * @private\n * @suppress {strictPrimitiveOperators}\n */\nWebChannelBase.prototype.onInput_ = function(respArray, request) {\n 'use strict';\n const batch =\n this.handler_ && this.handler_.channelHandleMultipleArrays ? [] : null;\n for (let i = 0; i < respArray.length; i++) {\n let nextArray = respArray[i];\n this.lastArrayId_ = nextArray[0];\n nextArray = nextArray[1];\n if (this.state_ == WebChannelBase.State.OPENING) {\n if (nextArray[0] == 'c') {\n this.sid_ = nextArray[1];\n this.hostPrefix_ = this.correctHostPrefix(nextArray[2]);\n\n const negotiatedVersion = nextArray[3];\n if (negotiatedVersion != null) {\n this.channelVersion_ = negotiatedVersion;\n this.channelDebug_.info('VER=' + this.channelVersion_);\n }\n\n const negotiatedServerVersion = nextArray[4];\n if (negotiatedServerVersion != null) {\n this.serverVersion_ = negotiatedServerVersion;\n this.channelDebug_.info('SVER=' + this.serverVersion_);\n }\n\n // CVER=22\n const serverKeepaliveMs = nextArray[5];\n if (serverKeepaliveMs != null &&\n typeof serverKeepaliveMs === 'number' && serverKeepaliveMs > 0) {\n const timeout = 1.5 * serverKeepaliveMs;\n this.backChannelRequestTimeoutMs_ = timeout;\n this.channelDebug_.info('backChannelRequestTimeoutMs_=' + timeout);\n }\n\n this.applyControlHeaders_(request);\n\n this.state_ = WebChannelBase.State.OPENED;\n if (this.handler_) {\n this.handler_.channelOpened(this);\n }\n\n if (this.detectBufferingProxy_) {\n this.handshakeRttMs_ = Date.now() - request.getRequestStartTime();\n this.channelDebug_.info(\n 'Handshake RTT: ' + this.handshakeRttMs_ + 'ms');\n }\n\n this.startBackchannelAfterHandshake_(request);\n\n if (this.outgoingMaps_.length > 0) {\n this.ensureForwardChannel_();\n }\n } else if (nextArray[0] == 'stop' || nextArray[0] == 'close') {\n // treat close also as an abort\n this.signalError_(WebChannelBase.Error.STOP);\n }\n } else if (this.state_ == WebChannelBase.State.OPENED) {\n if (nextArray[0] == 'stop' || nextArray[0] == 'close') {\n if (batch && !(batch.length === 0)) {\n this.handler_.channelHandleMultipleArrays(this, batch);\n batch.length = 0;\n }\n if (nextArray[0] == 'stop') {\n this.signalError_(WebChannelBase.Error.STOP);\n } else {\n this.disconnect();\n }\n } else if (nextArray[0] == 'noop') {\n // ignore - noop to keep connection happy\n } else {\n if (batch) {\n batch.push(nextArray);\n } else if (this.handler_) {\n this.handler_.channelHandleArray(this, nextArray);\n }\n }\n // We have received useful data on the back-channel, so clear its retry\n // count. We do this because back-channels by design do not complete\n // quickly, so on a flaky connection we could have many fail to complete\n // fully but still deliver a lot of data before they fail. We don't want\n // to count such failures towards the retry limit, because we don't want\n // to give up on a session if we can still receive data.\n this.backChannelRetryCount_ = 0;\n }\n }\n if (batch && !(batch.length === 0)) {\n this.handler_.channelHandleMultipleArrays(this, batch);\n }\n};\n\n\n/**\n * Starts the backchannel after the handshake.\n *\n * @param {!ChannelRequest} request The underlying request object\n * @private\n */\nWebChannelBase.prototype.startBackchannelAfterHandshake_ = function(request) {\n 'use strict';\n this.backChannelUri_ = this.getBackChannelUri(\n this.hostPrefix_, /** @type {string} */ (this.path_));\n\n if (request.isInitialResponseDecoded()) {\n this.channelDebug_.debug('Upgrade the handshake request to a backchannel.');\n this.forwardChannelRequestPool_.removeRequest(request);\n request.resetTimeout(this.backChannelRequestTimeoutMs_);\n this.backChannelRequest_ = request;\n } else {\n this.ensureBackChannel_();\n }\n};\n\n\n/**\n * Helper to ensure the channel is in the expected state.\n * @param {...number} var_args The channel must be in one of the indicated\n * states.\n * @private\n */\nWebChannelBase.prototype.ensureInState_ = function(var_args) {\n 'use strict';\n goog.asserts.assert(\n goog.array.contains(arguments, this.state_),\n 'Unexpected channel state: %s', this.state_);\n};\n\n\n/**\n * Signals an error has occurred.\n * @param {WebChannelBase.Error} error The error code for the failure.\n * @private\n */\nWebChannelBase.prototype.signalError_ = function(error) {\n 'use strict';\n this.channelDebug_.info('Error code ' + error);\n if (error == WebChannelBase.Error.REQUEST_FAILED) {\n if (ENABLE_GOOGLE_COM_PING) {\n // Create a separate Internet connection to check\n // if it's a server error or user's network error.\n let imageUri = null;\n if (this.handler_) {\n imageUri = this.handler_.getNetworkTestImageUri(this);\n }\n netUtils.testNetwork(\n goog.bind(this.testNetworkCallback_, this), imageUri);\n }\n } else {\n requestStats.notifyStatEvent(requestStats.Stat.ERROR_OTHER);\n }\n this.onError_(error);\n};\n\n\n/**\n * Callback for netUtils.testNetwork during error handling.\n * @param {boolean} networkUp Whether the network is up.\n * @private\n */\nWebChannelBase.prototype.testNetworkCallback_ = function(networkUp) {\n 'use strict';\n if (networkUp) {\n this.channelDebug_.info('Successfully pinged google.com');\n requestStats.notifyStatEvent(requestStats.Stat.ERROR_OTHER);\n } else {\n this.channelDebug_.info('Failed to ping google.com');\n requestStats.notifyStatEvent(requestStats.Stat.ERROR_NETWORK);\n // Do not call onError_ again to eliminate duplicated Error events.\n }\n};\n\n\n/**\n * Called when messages have been successfully sent from the queue.\n * @param {!ChannelRequest} request The request object\n * @private\n */\nWebChannelBase.prototype.onSuccess_ = function(request) {\n 'use strict';\n if (this.handler_) {\n this.handler_.channelSuccess(this, request);\n }\n};\n\n\n/**\n * Called when we've determined the final error for a channel. It closes the\n * notifiers the handler of the error and closes the channel.\n * @param {WebChannelBase.Error} error The error code for the failure.\n * @private\n */\nWebChannelBase.prototype.onError_ = function(error) {\n 'use strict';\n this.channelDebug_.debug('HttpChannel: error - ' + error);\n this.state_ = WebChannelBase.State.CLOSED;\n if (this.handler_) {\n this.handler_.channelError(this, error);\n }\n this.onClose_();\n this.cancelRequests_();\n};\n\n\n/**\n * Called when the channel has been closed. It notifiers the handler of the\n * event, and reports any pending or undelivered maps.\n * @private\n */\nWebChannelBase.prototype.onClose_ = function() {\n 'use strict';\n this.state_ = WebChannelBase.State.CLOSED;\n this.nonAckedMapsAtChannelClose_ = [];\n if (this.handler_) {\n const pendingMessages =\n this.forwardChannelRequestPool_.getPendingMessages();\n\n if (pendingMessages.length == 0 && this.outgoingMaps_.length == 0) {\n this.handler_.channelClosed(this);\n } else {\n this.channelDebug_.debug(\n () => 'Number of undelivered maps' +\n ', pending: ' + pendingMessages.length +\n ', outgoing: ' + this.outgoingMaps_.length);\n\n goog.array.extend(this.nonAckedMapsAtChannelClose_, pendingMessages);\n goog.array.extend(this.nonAckedMapsAtChannelClose_, this.outgoingMaps_);\n\n this.forwardChannelRequestPool_.clearPendingMessages();\n\n const copyOfUndeliveredMaps = goog.array.clone(this.outgoingMaps_);\n this.outgoingMaps_.length = 0;\n\n this.handler_.channelClosed(this, pendingMessages, copyOfUndeliveredMaps);\n }\n }\n};\n\n/**\n * @return {!Array<!Wire.QueuedMap>} Returns the list of non-acked maps, both\n * during an active channel or after the channel is closed. Refer to the\n * `getNonAckedMessages()` API for definitions of non-acked messages.\n */\nWebChannelBase.prototype.getNonAckedMaps = function() {\n if (this.state_ == WebChannelBase.State.CLOSED) {\n goog.asserts.assert(\n this.nonAckedMapsAtChannelClose_ != null,\n 'nonAckedMapsAtChannelClose_ is not set after channel close.');\n return this.nonAckedMapsAtChannelClose_;\n }\n\n // The underlying message objects are not cloned and thus exposes a mutability\n // risk, but is chosen to make strict equality (i.e. ===) checks possible for\n // callers.\n let unAckedMaps = [];\n goog.array.extend(\n unAckedMaps, this.forwardChannelRequestPool_.getPendingMessages());\n goog.array.extend(unAckedMaps, this.outgoingMaps_);\n\n return unAckedMaps;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getForwardChannelUri = function(path) {\n 'use strict';\n const uri = this.createDataUri(null, path);\n this.channelDebug_.debug('GetForwardChannelUri: ' + uri);\n return uri;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getConnectionState = function() {\n 'use strict';\n return this.connState_;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.getBackChannelUri = function(hostPrefix, path) {\n 'use strict';\n const uri = this.createDataUri(\n this.shouldUseSecondaryDomains() ? hostPrefix : null, path);\n this.channelDebug_.debug('GetBackChannelUri: ' + uri);\n return uri;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.createDataUri = function(\n hostPrefix, path, opt_overridePort) {\n 'use strict';\n let uri = goog.Uri.parse(path);\n const uriAbsolute = (uri.getDomain() != '');\n if (uriAbsolute) {\n if (hostPrefix) {\n uri.setDomain(hostPrefix + '.' + uri.getDomain());\n }\n\n uri.setPort(opt_overridePort || uri.getPort());\n } else {\n const locationPage = goog.global.location;\n let hostName;\n if (hostPrefix) {\n hostName = hostPrefix + '.' + locationPage.hostname;\n } else {\n hostName = locationPage.hostname;\n }\n\n const port = opt_overridePort || +locationPage.port;\n\n uri = goog.Uri.create(locationPage.protocol, null, hostName, port, path);\n }\n\n const param = this.getHttpSessionIdParam();\n const value = this.getHttpSessionId();\n if (param && value) {\n uri.setParameterValue(param, value);\n }\n\n // Add the protocol version to the URI.\n uri.setParameterValue('VER', this.channelVersion_);\n\n this.addAdditionalParams_(uri);\n\n return uri;\n};\n\n/**\n * @override\n * @param {?string} hostPrefix The host prefix, if we need an XhrIo object\n * capable of calling a secondary domain.\n * @param {boolean=} isStreaming Whether or not fetch/streams are enabled for\n * the underlying HTTP request.\n * @return {!goog.net.XhrIo} A new XhrIo object.\n */\nWebChannelBase.prototype.createXhrIo = function(hostPrefix, isStreaming) {\n 'use strict';\n if (hostPrefix && !this.supportsCrossDomainXhrs_) {\n throw new Error('Can\\'t create secondary domain capable XhrIo object.');\n }\n let xhr;\n if (this.usesFetchStreams_ && !this.xmlHttpFactory_) {\n xhr = new goog.net.XhrIo(\n new goog.net.FetchXmlHttpFactory({streamBinaryChunks: isStreaming}));\n } else {\n xhr = new goog.net.XhrIo(this.xmlHttpFactory_);\n }\n xhr.setWithCredentials(this.supportsCrossDomainXhrs_);\n return xhr;\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.isActive = function() {\n 'use strict';\n return !!this.handler_ && this.handler_.isActive(this);\n};\n\n\n/**\n * @override\n */\nWebChannelBase.prototype.shouldUseSecondaryDomains = function() {\n 'use strict';\n return this.supportsCrossDomainXhrs_;\n};\n\n\n/**\n * Sets (overwrites) the forward channel flush callback.\n *\n * @param {function()} callback The callback to be invoked.\n */\nWebChannelBase.prototype.setForwardChannelFlushCallback = function(callback) {\n 'use strict';\n this.forwardChannelFlushedCallback_ = callback;\n};\n\n\n/**\n * Abstract base class for the channel handler\n * @constructor\n * @struct\n */\nWebChannelBase.Handler = function() {};\n\n\n/**\n * Callback handler for when a batch of response arrays is received from the\n * server. When null, batched dispatching is disabled.\n * @type {?function(!WebChannelBase, !Array<!Array<?>>)}\n */\nWebChannelBase.Handler.prototype.channelHandleMultipleArrays = null;\n\n\n/**\n * Whether it's okay to make a request to the server. A handler can return\n * false if the channel should fail. For example, if the user has logged out,\n * the handler may want all requests to fail immediately.\n * @param {WebChannelBase} channel The channel.\n * @return {WebChannelBase.Error} An error code. The code should\n * return WebChannelBase.Error.OK to indicate it's okay. Any other\n * error code will cause a failure.\n */\nWebChannelBase.Handler.prototype.okToMakeRequest = function(channel) {\n 'use strict';\n return WebChannelBase.Error.OK;\n};\n\n\n/**\n * Indicates the WebChannel has successfully negotiated with the server\n * and can now send and receive data.\n * @param {WebChannelBase} channel The channel.\n */\nWebChannelBase.Handler.prototype.channelOpened = function(channel) {};\n\n\n/**\n * New input is available for the application to process.\n *\n * @param {WebChannelBase} channel The channel.\n * @param {!Array<?>|!Object} array The data array.\n */\nWebChannelBase.Handler.prototype.channelHandleArray = function(\n channel, array) {};\n\n\n/**\n * Indicates messages that have been successfully sent on the channel.\n *\n * @param {WebChannelBase} channel The channel.\n * @param {!ChannelRequest} request The request object that contains\n * the pending messages that have been successfully delivered to the server.\n */\nWebChannelBase.Handler.prototype.channelSuccess = function(channel, request) {};\n\n\n/**\n * Indicates an error occurred on the WebChannel.\n *\n * @param {WebChannelBase} channel The channel.\n * @param {WebChannelBase.Error} error The error code.\n */\nWebChannelBase.Handler.prototype.channelError = function(channel, error) {};\n\n\n/**\n * Indicates the WebChannel is closed. Also notifies about which maps,\n * if any, that may not have been delivered to the server.\n * @param {WebChannelBase} channel The channel.\n * @param {Array<Wire.QueuedMap>=} opt_pendingMaps The\n * array of pending maps, which may or may not have been delivered to the\n * server.\n * @param {Array<Wire.QueuedMap>=} opt_undeliveredMaps\n * The array of undelivered maps, which have definitely not been delivered\n * to the server.\n */\nWebChannelBase.Handler.prototype.channelClosed = function(\n channel, opt_pendingMaps, opt_undeliveredMaps) {};\n\n\n/**\n * Gets any parameters that should be added at the time another connection is\n * made to the server.\n * @param {WebChannelBase} channel The channel.\n * @return {!Object} Extra parameter keys and values to add to the requests.\n */\nWebChannelBase.Handler.prototype.getAdditionalParams = function(channel) {\n 'use strict';\n return {};\n};\n\n\n/**\n * Gets the URI of an image that can be used to test network connectivity.\n * @param {WebChannelBase} channel The channel.\n * @return {goog.Uri?} A custom URI to load for the network test.\n */\nWebChannelBase.Handler.prototype.getNetworkTestImageUri = function(channel) {\n 'use strict';\n return null;\n};\n\n\n/**\n * Gets whether this channel is currently active. This is used to determine the\n * length of time to wait before retrying.\n * @param {WebChannelBase} channel The channel.\n * @return {boolean} Whether the channel is currently active.\n */\nWebChannelBase.Handler.prototype.isActive = function(channel) {\n 'use strict';\n return true;\n};\n\n/**\n * Whether or not this channel uses WHATWG Fetch/streams.\n * @override\n * @return {boolean}\n */\nWebChannelBase.prototype.usesFetchStreams = function() {\n 'use strict';\n return this.usesFetchStreams_;\n};\n\n\n/**\n * Called by the channel if enumeration of the map throws an exception.\n * @param {WebChannelBase} channel The channel.\n * @param {Object} map The map that can't be enumerated.\n */\nWebChannelBase.Handler.prototype.badMapError = function(channel, map) {};\n\n\n/**\n * Allows the handler to override a host prefix provided by the server. Will\n * be called whenever the channel has received such a prefix and is considering\n * its use.\n * @param {?string} serverHostPrefix The host prefix provided by the server.\n * @return {?string} The host prefix the client should use.\n */\nWebChannelBase.Handler.prototype.correctHostPrefix = function(\n serverHostPrefix) {\n 'use strict';\n return serverHostPrefix;\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Class for parsing and formatting URIs.\n *\n * This package is deprecated in favour of the Closure URL package (goog.url)\n * when manipulating URIs for use by a browser. This package uses regular\n * expressions to parse a potential URI which can fall out of sync with how a\n * browser will actually interpret the URI. See\n * `goog.uri.utils.setUrlPackageSupportLoggingHandler` for one way to identify\n * URIs that should instead be parsed using the URL package.\n *\n * Use goog.Uri(string) to parse a URI string. Use goog.Uri.create(...) to\n * create a new instance of the goog.Uri object from Uri parts.\n *\n * e.g: <code>var myUri = new goog.Uri(window.location);</code>\n *\n * Implements RFC 3986 for parsing/formatting URIs.\n * http://www.ietf.org/rfc/rfc3986.txt\n *\n * Some changes have been made to the interface (more like .NETs), though the\n * internal representation is now of un-encoded parts, this will change the\n * behavior slightly.\n */\n\ngoog.provide('goog.Uri');\ngoog.provide('goog.Uri.QueryData');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.collections.maps');\ngoog.require('goog.string');\ngoog.require('goog.structs');\ngoog.require('goog.uri.utils');\ngoog.require('goog.uri.utils.ComponentIndex');\ngoog.require('goog.uri.utils.StandardQueryParam');\n\n\n\n/**\n * This class contains setters and getters for the parts of the URI.\n * The <code>getXyz</code>/<code>setXyz</code> methods return the decoded part\n * -- so<code>goog.Uri.parse('/foo%20bar').getPath()</code> will return the\n * decoded path, <code>/foo bar</code>.\n *\n * Reserved characters (see RFC 3986 section 2.2) can be present in\n * their percent-encoded form in scheme, domain, and path URI components and\n * will not be auto-decoded. For example:\n * <code>goog.Uri.parse('rel%61tive/path%2fto/resource').getPath()</code> will\n * return <code>relative/path%2fto/resource</code>.\n *\n * The constructor accepts an optional unparsed, raw URI string. The parser\n * is relaxed, so special characters that aren't escaped but don't cause\n * ambiguities will not cause parse failures.\n *\n * All setters return <code>this</code> and so may be chained, a la\n * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.\n *\n * @param {*=} opt_uri Optional string URI to parse\n * (use goog.Uri.create() to create a URI from parts), or if\n * a goog.Uri is passed, a clone is created.\n * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore\n * the case of the parameter name.\n *\n * @throws URIError If opt_uri is provided and URI is malformed (that is,\n * if decodeURIComponent fails on any of the URI components).\n * @constructor\n * @struct\n */\ngoog.Uri = function(opt_uri, opt_ignoreCase) {\n 'use strict';\n /**\n * Scheme such as \"http\".\n * @private {string}\n */\n this.scheme_ = '';\n\n /**\n * User credentials in the form \"username:password\".\n * @private {string}\n */\n this.userInfo_ = '';\n\n /**\n * Domain part, e.g. \"www.google.com\".\n * @private {string}\n */\n this.domain_ = '';\n\n /**\n * Port, e.g. 8080.\n * @private {?number}\n */\n this.port_ = null;\n\n /**\n * Path, e.g. \"/tests/img.png\".\n * @private {string}\n */\n this.path_ = '';\n\n /**\n * The fragment without the #.\n * @private {string}\n */\n this.fragment_ = '';\n\n /**\n * Whether or not this Uri should be treated as Read Only.\n * @private {boolean}\n */\n this.isReadOnly_ = false;\n\n /**\n * Whether or not to ignore case when comparing query params.\n * @private {boolean}\n */\n this.ignoreCase_ = false;\n\n /**\n * Object representing query data.\n * @private {!goog.Uri.QueryData}\n */\n this.queryData_;\n\n // Parse in the uri string\n var m;\n if (opt_uri instanceof goog.Uri) {\n this.ignoreCase_ = (opt_ignoreCase !== undefined) ? opt_ignoreCase :\n opt_uri.getIgnoreCase();\n this.setScheme(opt_uri.getScheme());\n this.setUserInfo(opt_uri.getUserInfo());\n this.setDomain(opt_uri.getDomain());\n this.setPort(opt_uri.getPort());\n this.setPath(opt_uri.getPath());\n this.setQueryData(opt_uri.getQueryData().clone());\n this.setFragment(opt_uri.getFragment());\n } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {\n this.ignoreCase_ = !!opt_ignoreCase;\n\n // Set the parts -- decoding as we do so.\n // COMPATIBILITY NOTE - In IE, unmatched fields may be empty strings,\n // whereas in other browsers they will be undefined.\n this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);\n this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);\n this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);\n this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);\n this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);\n this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);\n this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);\n\n } else {\n this.ignoreCase_ = !!opt_ignoreCase;\n this.queryData_ = new goog.Uri.QueryData(null, this.ignoreCase_);\n }\n};\n\n\n/**\n * Parameter name added to stop caching.\n * @type {string}\n */\ngoog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;\n\n\n/**\n * @return {string} The string form of the url.\n * @override\n */\ngoog.Uri.prototype.toString = function() {\n 'use strict';\n var out = [];\n\n var scheme = this.getScheme();\n if (scheme) {\n out.push(\n goog.Uri.encodeSpecialChars_(\n scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n ':');\n }\n\n var domain = this.getDomain();\n if (domain || scheme == 'file') {\n out.push('//');\n\n var userInfo = this.getUserInfo();\n if (userInfo) {\n out.push(\n goog.Uri.encodeSpecialChars_(\n userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n '@');\n }\n\n out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));\n\n var port = this.getPort();\n if (port != null) {\n out.push(':', String(port));\n }\n }\n\n var path = this.getPath();\n if (path) {\n if (this.hasDomain() && path.charAt(0) != '/') {\n out.push('/');\n }\n out.push(goog.Uri.encodeSpecialChars_(\n path,\n path.charAt(0) == '/' ? goog.Uri.reDisallowedInAbsolutePath_ :\n goog.Uri.reDisallowedInRelativePath_,\n true));\n }\n\n var query = this.getEncodedQuery();\n if (query) {\n out.push('?', query);\n }\n\n var fragment = this.getFragment();\n if (fragment) {\n out.push(\n '#',\n goog.Uri.encodeSpecialChars_(\n fragment, goog.Uri.reDisallowedInFragment_));\n }\n return out.join('');\n};\n\n\n/**\n * Resolves the given relative URI (a goog.Uri object), using the URI\n * represented by this instance as the base URI.\n *\n * There are several kinds of relative URIs:<br>\n * 1. foo - replaces the last part of the path, the whole query and fragment<br>\n * 2. /foo - replaces the path, the query and fragment<br>\n * 3. //foo - replaces everything from the domain on. foo is a domain name<br>\n * 4. ?foo - replace the query and fragment<br>\n * 5. #foo - replace the fragment only\n *\n * Additionally, if relative URI has a non-empty path, all \"..\" and \".\"\n * segments will be resolved, as described in RFC 3986.\n *\n * @param {!goog.Uri} relativeUri The relative URI to resolve.\n * @return {!goog.Uri} The resolved URI.\n */\ngoog.Uri.prototype.resolve = function(relativeUri) {\n 'use strict';\n var absoluteUri = this.clone();\n\n // we satisfy these conditions by looking for the first part of relativeUri\n // that is not blank and applying defaults to the rest\n\n var overridden = relativeUri.hasScheme();\n\n if (overridden) {\n absoluteUri.setScheme(relativeUri.getScheme());\n } else {\n overridden = relativeUri.hasUserInfo();\n }\n\n if (overridden) {\n absoluteUri.setUserInfo(relativeUri.getUserInfo());\n } else {\n overridden = relativeUri.hasDomain();\n }\n\n if (overridden) {\n absoluteUri.setDomain(relativeUri.getDomain());\n } else {\n overridden = relativeUri.hasPort();\n }\n\n var path = relativeUri.getPath();\n if (overridden) {\n absoluteUri.setPort(relativeUri.getPort());\n } else {\n overridden = relativeUri.hasPath();\n if (overridden) {\n // resolve path properly\n if (path.charAt(0) != '/') {\n // path is relative\n if (this.hasDomain() && !this.hasPath()) {\n // RFC 3986, section 5.2.3, case 1\n path = '/' + path;\n } else {\n // RFC 3986, section 5.2.3, case 2\n var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');\n if (lastSlashIndex != -1) {\n path = absoluteUri.getPath().slice(0, lastSlashIndex + 1) + path;\n }\n }\n }\n path = goog.Uri.removeDotSegments(path);\n }\n }\n\n if (overridden) {\n absoluteUri.setPath(path);\n } else {\n overridden = relativeUri.hasQuery();\n }\n\n if (overridden) {\n absoluteUri.setQueryData(relativeUri.getQueryData().clone());\n } else {\n overridden = relativeUri.hasFragment();\n }\n\n if (overridden) {\n absoluteUri.setFragment(relativeUri.getFragment());\n }\n\n return absoluteUri;\n};\n\n\n/**\n * Clones the URI instance.\n * @return {!goog.Uri} New instance of the URI object.\n */\ngoog.Uri.prototype.clone = function() {\n 'use strict';\n return new goog.Uri(this);\n};\n\n\n/**\n * @return {string} The encoded scheme/protocol for the URI.\n */\ngoog.Uri.prototype.getScheme = function() {\n 'use strict';\n return this.scheme_;\n};\n\n\n/**\n * Sets the scheme/protocol.\n * @throws URIError If opt_decode is true and newScheme is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newScheme New scheme value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setScheme = function(newScheme, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.scheme_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme;\n\n // remove an : at the end of the scheme so somebody can pass in\n // window.location.protocol\n if (this.scheme_) {\n this.scheme_ = this.scheme_.replace(/:$/, '');\n }\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the scheme has been set.\n */\ngoog.Uri.prototype.hasScheme = function() {\n 'use strict';\n return !!this.scheme_;\n};\n\n\n/**\n * @return {string} The decoded user info.\n */\ngoog.Uri.prototype.getUserInfo = function() {\n 'use strict';\n return this.userInfo_;\n};\n\n\n/**\n * Sets the userInfo.\n * @throws URIError If opt_decode is true and newUserInfo is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newUserInfo New userInfo value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.userInfo_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the user info has been set.\n */\ngoog.Uri.prototype.hasUserInfo = function() {\n 'use strict';\n return !!this.userInfo_;\n};\n\n\n/**\n * @return {string} The decoded domain.\n */\ngoog.Uri.prototype.getDomain = function() {\n 'use strict';\n return this.domain_;\n};\n\n\n/**\n * Sets the domain.\n * @throws URIError If opt_decode is true and newDomain is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newDomain New domain value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setDomain = function(newDomain, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.domain_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the domain has been set.\n */\ngoog.Uri.prototype.hasDomain = function() {\n 'use strict';\n return !!this.domain_;\n};\n\n\n/**\n * @return {?number} The port number.\n */\ngoog.Uri.prototype.getPort = function() {\n 'use strict';\n return this.port_;\n};\n\n\n/**\n * Sets the port number.\n * @param {*} newPort Port number. Will be explicitly casted to a number.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPort = function(newPort) {\n 'use strict';\n this.enforceReadOnly();\n\n if (newPort) {\n newPort = Number(newPort);\n if (isNaN(newPort) || newPort < 0) {\n throw new Error('Bad port number ' + newPort);\n }\n this.port_ = newPort;\n } else {\n this.port_ = null;\n }\n\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the port has been set.\n */\ngoog.Uri.prototype.hasPort = function() {\n 'use strict';\n return this.port_ != null;\n};\n\n\n/**\n * @return {string} The decoded path.\n */\ngoog.Uri.prototype.getPath = function() {\n 'use strict';\n return this.path_;\n};\n\n\n/**\n * Sets the path.\n * @throws URIError If opt_decode is true and newPath is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newPath New path value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPath = function(newPath, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the path has been set.\n */\ngoog.Uri.prototype.hasPath = function() {\n 'use strict';\n return !!this.path_;\n};\n\n\n/**\n * @return {boolean} Whether the query string has been set.\n */\ngoog.Uri.prototype.hasQuery = function() {\n 'use strict';\n return this.queryData_.toString() !== '';\n};\n\n\n/**\n * Sets the query data.\n * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * Applies only if queryData is a string.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQueryData = function(queryData, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n\n if (queryData instanceof goog.Uri.QueryData) {\n this.queryData_ = queryData;\n this.queryData_.setIgnoreCase(this.ignoreCase_);\n } else {\n if (!opt_decode) {\n // QueryData accepts encoded query string, so encode it if\n // opt_decode flag is not true.\n queryData = goog.Uri.encodeSpecialChars_(\n queryData, goog.Uri.reDisallowedInQuery_);\n }\n this.queryData_ = new goog.Uri.QueryData(queryData, this.ignoreCase_);\n }\n\n return this;\n};\n\n\n/**\n * Sets the URI query.\n * @param {string} newQuery New query value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQuery = function(newQuery, opt_decode) {\n 'use strict';\n return this.setQueryData(newQuery, opt_decode);\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getEncodedQuery = function() {\n 'use strict';\n return this.queryData_.toString();\n};\n\n\n/**\n * @return {string} The decoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getDecodedQuery = function() {\n 'use strict';\n return this.queryData_.toDecodedString();\n};\n\n\n/**\n * Returns the query data.\n * @return {!goog.Uri.QueryData} QueryData object.\n */\ngoog.Uri.prototype.getQueryData = function() {\n 'use strict';\n return this.queryData_;\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n *\n * Warning: This method, unlike other getter methods, returns encoded\n * value, instead of decoded one.\n */\ngoog.Uri.prototype.getQuery = function() {\n 'use strict';\n return this.getEncodedQuery();\n};\n\n\n/**\n * Sets the value of the named query parameters, clearing previous values for\n * that key.\n *\n * @param {string} key The parameter to set.\n * @param {*} value The new value. Value does not need to be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValue = function(key, value) {\n 'use strict';\n this.enforceReadOnly();\n this.queryData_.set(key, value);\n return this;\n};\n\n\n/**\n * Sets the values of the named query parameters, clearing previous values for\n * that key. Not new values will currently be moved to the end of the query\n * string.\n *\n * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])\n * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>\n *\n * @param {string} key The parameter to set.\n * @param {*} values The new values. If values is a single\n * string then it will be treated as the sole value. Values do not need to\n * be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValues = function(key, values) {\n 'use strict';\n this.enforceReadOnly();\n\n if (!Array.isArray(values)) {\n values = [String(values)];\n }\n\n this.queryData_.setValues(key, values);\n\n return this;\n};\n\n\n/**\n * Returns the value<b>s</b> for a given cgi parameter as a list of decoded\n * query parameter values.\n * @param {string} name The parameter to get values for.\n * @return {!Array<?>} The values for a given cgi parameter as a list of\n * decoded query parameter values.\n */\ngoog.Uri.prototype.getParameterValues = function(name) {\n 'use strict';\n return this.queryData_.getValues(name);\n};\n\n\n/**\n * Returns the first value for a given cgi parameter or undefined if the given\n * parameter name does not appear in the query string.\n * @param {string} paramName Unescaped parameter name.\n * @return {string|undefined} The first value for a given cgi parameter or\n * undefined if the given parameter name does not appear in the query\n * string.\n */\ngoog.Uri.prototype.getParameterValue = function(paramName) {\n 'use strict';\n return /** @type {string|undefined} */ (this.queryData_.get(paramName));\n};\n\n\n/**\n * @return {string} The URI fragment, not including the #.\n */\ngoog.Uri.prototype.getFragment = function() {\n 'use strict';\n return this.fragment_;\n};\n\n\n/**\n * Sets the URI fragment.\n * @throws URIError If opt_decode is true and newFragment is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newFragment New fragment value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setFragment = function(newFragment, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.fragment_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI has a fragment set.\n */\ngoog.Uri.prototype.hasFragment = function() {\n 'use strict';\n return !!this.fragment_;\n};\n\n\n/**\n * Returns true if this has the same domain as that of uri2.\n * @param {!goog.Uri} uri2 The URI object to compare to.\n * @return {boolean} true if same domain; false otherwise.\n */\ngoog.Uri.prototype.hasSameDomainAs = function(uri2) {\n 'use strict';\n return ((!this.hasDomain() && !uri2.hasDomain()) ||\n this.getDomain() == uri2.getDomain()) &&\n ((!this.hasPort() && !uri2.hasPort()) ||\n this.getPort() == uri2.getPort());\n};\n\n\n/**\n * Adds a random parameter to the Uri.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.makeUnique = function() {\n 'use strict';\n this.enforceReadOnly();\n this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());\n\n return this;\n};\n\n\n/**\n * Removes the named query parameter.\n *\n * @param {string} key The parameter to remove.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.removeParameter = function(key) {\n 'use strict';\n this.enforceReadOnly();\n this.queryData_.remove(key);\n return this;\n};\n\n\n/**\n * Sets whether Uri is read only. If this goog.Uri is read-only,\n * enforceReadOnly_ will be called at the start of any function that may modify\n * this Uri.\n * @param {boolean} isReadOnly whether this goog.Uri should be read only.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setReadOnly = function(isReadOnly) {\n 'use strict';\n this.isReadOnly_ = isReadOnly;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI is read only.\n */\ngoog.Uri.prototype.isReadOnly = function() {\n 'use strict';\n return this.isReadOnly_;\n};\n\n\n/**\n * Checks if this Uri has been marked as read only, and if so, throws an error.\n * This should be called whenever any modifying function is called.\n */\ngoog.Uri.prototype.enforceReadOnly = function() {\n 'use strict';\n if (this.isReadOnly_) {\n throw new Error('Tried to modify a read-only Uri');\n }\n};\n\n\n/**\n * Sets whether to ignore case.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setIgnoreCase = function(ignoreCase) {\n 'use strict';\n this.ignoreCase_ = ignoreCase;\n if (this.queryData_) {\n this.queryData_.setIgnoreCase(ignoreCase);\n }\n return this;\n};\n\n\n/**\n * @return {boolean} Whether to ignore case.\n */\ngoog.Uri.prototype.getIgnoreCase = function() {\n 'use strict';\n return this.ignoreCase_;\n};\n\n\n//==============================================================================\n// Static members\n//==============================================================================\n\n\n/**\n * Creates a uri from the string form. Basically an alias of new goog.Uri().\n * If a Uri object is passed to parse then it will return a clone of the object.\n *\n * @throws URIError If parsing the URI is malformed. The passed URI components\n * should all be parseable by decodeURIComponent.\n * @param {*} uri Raw URI string or instance of Uri\n * object.\n * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter\n * names in #getParameterValue.\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.parse = function(uri, opt_ignoreCase) {\n 'use strict';\n return uri instanceof goog.Uri ? uri.clone() :\n new goog.Uri(uri, opt_ignoreCase);\n};\n\n\n/**\n * Creates a new goog.Uri object from unencoded parts.\n *\n * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.\n * @param {?string=} opt_userInfo username:password.\n * @param {?string=} opt_domain www.google.com.\n * @param {?number=} opt_port 9830.\n * @param {?string=} opt_path /some/path/to/a/file.html.\n * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.\n * @param {?string=} opt_fragment The fragment without the #.\n * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in\n * #getParameterValue.\n *\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.create = function(\n opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query,\n opt_fragment, opt_ignoreCase) {\n 'use strict';\n var uri = new goog.Uri(null, opt_ignoreCase);\n\n // Only set the parts if they are defined and not empty strings.\n opt_scheme && uri.setScheme(opt_scheme);\n opt_userInfo && uri.setUserInfo(opt_userInfo);\n opt_domain && uri.setDomain(opt_domain);\n opt_port && uri.setPort(opt_port);\n opt_path && uri.setPath(opt_path);\n opt_query && uri.setQueryData(opt_query);\n opt_fragment && uri.setFragment(opt_fragment);\n\n return uri;\n};\n\n\n/**\n * Resolves a relative Uri against a base Uri, accepting both strings and\n * Uri objects.\n *\n * @param {*} base Base Uri.\n * @param {*} rel Relative Uri.\n * @return {!goog.Uri} Resolved uri.\n */\ngoog.Uri.resolve = function(base, rel) {\n 'use strict';\n if (!(base instanceof goog.Uri)) {\n base = goog.Uri.parse(base);\n }\n\n if (!(rel instanceof goog.Uri)) {\n rel = goog.Uri.parse(rel);\n }\n\n return base.resolve(rel);\n};\n\n\n/**\n * Removes dot segments in given path component, as described in\n * RFC 3986, section 5.2.4.\n *\n * @param {string} path A non-empty path component.\n * @return {string} Path component with removed dot segments.\n */\ngoog.Uri.removeDotSegments = function(path) {\n 'use strict';\n if (path == '..' || path == '.') {\n return '';\n\n } else if (\n !goog.string.contains(path, './') && !goog.string.contains(path, '/.')) {\n // This optimization detects uris which do not contain dot-segments,\n // and as a consequence do not require any processing.\n return path;\n\n } else {\n var leadingSlash = goog.string.startsWith(path, '/');\n var segments = path.split('/');\n var out = [];\n\n for (var pos = 0; pos < segments.length;) {\n var segment = segments[pos++];\n\n if (segment == '.') {\n if (leadingSlash && pos == segments.length) {\n out.push('');\n }\n } else if (segment == '..') {\n if (out.length > 1 || out.length == 1 && out[0] != '') {\n out.pop();\n }\n if (leadingSlash && pos == segments.length) {\n out.push('');\n }\n } else {\n out.push(segment);\n leadingSlash = true;\n }\n }\n\n return out.join('/');\n }\n};\n\n\n/**\n * Decodes a value or returns the empty string if it isn't defined or empty.\n * @throws URIError If decodeURIComponent fails to decode val.\n * @param {string|undefined} val Value to decode.\n * @param {boolean=} opt_preserveReserved If true, restricted characters will\n * not be decoded.\n * @return {string} Decoded value.\n * @private\n */\ngoog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {\n 'use strict';\n // Don't use UrlDecode() here because val is not a query parameter.\n if (!val) {\n return '';\n }\n\n // decodeURI has the same output for '%2f' and '%252f'. We double encode %25\n // so that we can distinguish between the 2 inputs. This is later undone by\n // removeDoubleEncoding_.\n return opt_preserveReserved ? decodeURI(val.replace(/%25/g, '%2525')) :\n decodeURIComponent(val);\n};\n\n\n/**\n * If unescapedPart is non null, then escapes any characters in it that aren't\n * valid characters in a url and also escapes any special characters that\n * appear in extra.\n *\n * @param {*} unescapedPart The string to encode.\n * @param {RegExp} extra A character set of characters in [\\01-\\177].\n * @param {boolean=} opt_removeDoubleEncoding If true, remove double percent\n * encoding.\n * @return {?string} null iff unescapedPart == null.\n * @private\n */\ngoog.Uri.encodeSpecialChars_ = function(\n unescapedPart, extra, opt_removeDoubleEncoding) {\n 'use strict';\n if (typeof unescapedPart === 'string') {\n var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);\n if (opt_removeDoubleEncoding) {\n // encodeURI double-escapes %XX sequences used to represent restricted\n // characters in some URI components, remove the double escaping here.\n encoded = goog.Uri.removeDoubleEncoding_(encoded);\n }\n return encoded;\n }\n return null;\n};\n\n\n/**\n * Converts a character in [\\01-\\177] to its unicode character equivalent.\n * @param {string} ch One character string.\n * @return {string} Encoded string.\n * @private\n */\ngoog.Uri.encodeChar_ = function(ch) {\n 'use strict';\n var n = ch.charCodeAt(0);\n return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);\n};\n\n\n/**\n * Removes double percent-encoding from a string.\n * @param {string} doubleEncodedString String\n * @return {string} String with double encoding removed.\n * @private\n */\ngoog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {\n 'use strict';\n return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, '%$1');\n};\n\n\n/**\n * Regular expression for characters that are disallowed in the scheme or\n * userInfo part of the URI.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\\/\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in a relative path.\n * Colon is included due to RFC 3986 3.3.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInRelativePath_ = /[\\#\\?:]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in an absolute path.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInAbsolutePath_ = /[\\#\\?]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the query.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInQuery_ = /[\\#\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the fragment.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInFragment_ = /#/g;\n\n\n/**\n * Checks whether two URIs have the same domain.\n * @param {string} uri1String First URI string.\n * @param {string} uri2String Second URI string.\n * @return {boolean} true if the two URIs have the same domain; false otherwise.\n */\ngoog.Uri.haveSameDomain = function(uri1String, uri2String) {\n 'use strict';\n // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.\n // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.\n var pieces1 = goog.uri.utils.split(uri1String);\n var pieces2 = goog.uri.utils.split(uri2String);\n return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n\n/**\n * Class used to represent URI query parameters. It is essentially a hash of\n * name-value pairs, though a name can be present more than once.\n *\n * Has the same interface as the collections in goog.structs.\n *\n * @param {?string=} opt_query Optional encoded query string to parse into\n * the object.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n * name in #get.\n * @constructor\n * @struct\n * @final\n */\ngoog.Uri.QueryData = function(opt_query, opt_ignoreCase) {\n 'use strict';\n /**\n * The map containing name/value or name/array-of-values pairs.\n * May be null if it requires parsing from the query string.\n *\n * We need to use a Map because we cannot guarantee that the key names will\n * not be problematic for IE.\n *\n * @private {?Map<string, !Array<*>>}\n */\n this.keyMap_ = null;\n\n /**\n * The number of params, or null if it requires computing.\n * @private {?number}\n */\n this.count_ = null;\n\n /**\n * Encoded query string, or null if it requires computing from the key map.\n * @private {?string}\n */\n this.encodedQuery_ = opt_query || null;\n\n /**\n * If true, ignore the case of the parameter name in #get.\n * @private {boolean}\n */\n this.ignoreCase_ = !!opt_ignoreCase;\n};\n\n\n/**\n * If the underlying key map is not yet initialized, it parses the\n * query string and fills the map with parsed data.\n * @private\n */\ngoog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {\n 'use strict';\n if (!this.keyMap_) {\n this.keyMap_ = /** @type {!Map<string, !Array<*>>} */ (new Map());\n this.count_ = 0;\n if (this.encodedQuery_) {\n var self = this;\n goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\n 'use strict';\n self.add(goog.string.urlDecode(name), value);\n });\n }\n }\n};\n\n\n/**\n * Creates a new query data instance from a map of names and values.\n *\n * @param {!goog.collections.maps.MapLike<string, ?>|!Object} map Map of string\n * parameter names to parameter value. If parameter value is an array, it is\n * treated as if the key maps to each individual value in the\n * array.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n * name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromMap = function(map, opt_ignoreCase) {\n 'use strict';\n var keys = goog.structs.getKeys(map);\n if (typeof keys == 'undefined') {\n throw new Error('Keys are undefined');\n }\n\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n var values = goog.structs.getValues(map);\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = values[i];\n if (!Array.isArray(value)) {\n queryData.add(key, value);\n } else {\n queryData.setValues(key, value);\n }\n }\n return queryData;\n};\n\n\n/**\n * Creates a new query data instance from parallel arrays of parameter names\n * and values. Allows for duplicate parameter names. Throws an error if the\n * lengths of the arrays differ.\n *\n * @param {!Array<string>} keys Parameter names.\n * @param {!Array<?>} values Parameter values.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n * name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromKeysValues = function(\n keys, values, opt_ignoreCase) {\n 'use strict';\n if (keys.length != values.length) {\n throw new Error('Mismatched lengths for keys/values');\n }\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n for (var i = 0; i < keys.length; i++) {\n queryData.add(keys[i], values[i]);\n }\n return queryData;\n};\n\n\n/**\n * @return {?number} The number of parameters.\n */\ngoog.Uri.QueryData.prototype.getCount = function() {\n 'use strict';\n this.ensureKeyMapInitialized_();\n return this.count_;\n};\n\n\n/**\n * Adds a key value pair.\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.add = function(key, value) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n\n key = this.getKeyName_(key);\n var values = this.keyMap_.get(key);\n if (!values) {\n this.keyMap_.set(key, (values = []));\n }\n values.push(value);\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n return this;\n};\n\n\n/**\n * Removes all the params with the given key.\n * @param {string} key Name.\n * @return {boolean} Whether any parameter was removed.\n */\ngoog.Uri.QueryData.prototype.remove = function(key) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n\n key = this.getKeyName_(key);\n if (this.keyMap_.has(key)) {\n this.invalidateCache_();\n\n // Decrement parameter count.\n this.count_ =\n goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n return this.keyMap_.delete(key);\n }\n return false;\n};\n\n\n/**\n * Clears the parameters.\n */\ngoog.Uri.QueryData.prototype.clear = function() {\n 'use strict';\n this.invalidateCache_();\n this.keyMap_ = null;\n this.count_ = 0;\n};\n\n\n/**\n * @return {boolean} Whether we have any parameters.\n */\ngoog.Uri.QueryData.prototype.isEmpty = function() {\n 'use strict';\n this.ensureKeyMapInitialized_();\n return this.count_ == 0;\n};\n\n\n/**\n * Whether there is a parameter with the given name\n * @param {string} key The parameter name to check for.\n * @return {boolean} Whether there is a parameter with the given name.\n */\ngoog.Uri.QueryData.prototype.containsKey = function(key) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n key = this.getKeyName_(key);\n return this.keyMap_.has(key);\n};\n\n\n/**\n * Whether there is a parameter with the given value.\n * @param {*} value The value to check for.\n * @return {boolean} Whether there is a parameter with the given value.\n */\ngoog.Uri.QueryData.prototype.containsValue = function(value) {\n 'use strict';\n // NOTE(arv): This solution goes through all the params even if it was the\n // first param. We can get around this by not reusing code or by switching to\n // iterators.\n var vals = this.getValues();\n return goog.array.contains(vals, value);\n};\n\n\n/**\n * Runs a callback on every key-value pair in the map, including duplicate keys.\n * This won't maintain original order when duplicate keys are interspersed (like\n * getKeys() / getValues()).\n * @param {function(this:SCOPE, ?, string, !goog.Uri.QueryData)} f\n * @param {SCOPE=} opt_scope The value of \"this\" inside f.\n * @template SCOPE\n */\ngoog.Uri.QueryData.prototype.forEach = function(f, opt_scope) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(values, key) {\n 'use strict';\n values.forEach(function(value) {\n 'use strict';\n f.call(opt_scope, value, key, this);\n }, this);\n }, this);\n};\n\n\n/**\n * Returns all the keys of the parameters. If a key is used multiple times\n * it will be included multiple times in the returned array\n * @return {!Array<string>} All the keys of the parameters.\n */\ngoog.Uri.QueryData.prototype.getKeys = function() {\n 'use strict';\n this.ensureKeyMapInitialized_();\n // We need to get the values to know how many keys to add.\n const vals = Array.from(this.keyMap_.values());\n const keys = Array.from(this.keyMap_.keys());\n const rv = [];\n for (let i = 0; i < keys.length; i++) {\n const val = vals[i];\n for (let j = 0; j < val.length; j++) {\n rv.push(keys[i]);\n }\n }\n return rv;\n};\n\n\n/**\n * Returns all the values of the parameters with the given name. If the query\n * data has no such key this will return an empty array. If no key is given\n * all values wil be returned.\n * @param {string=} opt_key The name of the parameter to get the values for.\n * @return {!Array<?>} All the values of the parameters with the given name.\n */\ngoog.Uri.QueryData.prototype.getValues = function(opt_key) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n let rv = [];\n if (typeof opt_key === 'string') {\n if (this.containsKey(opt_key)) {\n rv = rv.concat(this.keyMap_.get(this.getKeyName_(opt_key)));\n }\n } else {\n // Return all values.\n const values = Array.from(this.keyMap_.values());\n for (let i = 0; i < values.length; i++) {\n rv = rv.concat(values[i]);\n }\n }\n return rv;\n};\n\n\n/**\n * Sets a key value pair and removes all other keys with the same value.\n *\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.set = function(key, value) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n\n // TODO(chrishenry): This could be better written as\n // this.remove(key), this.add(key, value), but that would reorder\n // the key (since the key is first removed and then added at the\n // end) and we would have to fix unit tests that depend on key\n // ordering.\n key = this.getKeyName_(key);\n if (this.containsKey(key)) {\n this.count_ =\n goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n }\n this.keyMap_.set(key, [value]);\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n return this;\n};\n\n\n/**\n * Returns the first value associated with the key. If the query data has no\n * such key this will return undefined or the optional default.\n * @param {string} key The name of the parameter to get the value for.\n * @param {*=} opt_default The default value to return if the query data\n * has no such key.\n * @return {*} The first string value associated with the key, or opt_default\n * if there's no value.\n */\ngoog.Uri.QueryData.prototype.get = function(key, opt_default) {\n 'use strict';\n if (!key) {\n return opt_default;\n }\n var values = this.getValues(key);\n return values.length > 0 ? String(values[0]) : opt_default;\n};\n\n\n/**\n * Sets the values for a key. If the key already exists, this will\n * override all of the existing values that correspond to the key.\n * @param {string} key The key to set values for.\n * @param {!Array<?>} values The values to set.\n */\ngoog.Uri.QueryData.prototype.setValues = function(key, values) {\n 'use strict';\n this.remove(key);\n\n if (values.length > 0) {\n this.invalidateCache_();\n this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));\n this.count_ = goog.asserts.assertNumber(this.count_) + values.length;\n }\n};\n\n\n/**\n * @return {string} Encoded query string.\n * @override\n */\ngoog.Uri.QueryData.prototype.toString = function() {\n 'use strict';\n if (this.encodedQuery_) {\n return this.encodedQuery_;\n }\n\n if (!this.keyMap_) {\n return '';\n }\n\n const sb = [];\n\n // In the past, we use this.getKeys() and this.getVals(), but that\n // generates a lot of allocations as compared to simply iterating\n // over the keys.\n const keys = Array.from(this.keyMap_.keys());\n for (var i = 0; i < keys.length; i++) {\n const key = keys[i];\n const encodedKey = goog.string.urlEncode(key);\n const val = this.getValues(key);\n for (var j = 0; j < val.length; j++) {\n var param = encodedKey;\n // Ensure that null and undefined are encoded into the url as\n // literal strings.\n if (val[j] !== '') {\n param += '=' + goog.string.urlEncode(val[j]);\n }\n sb.push(param);\n }\n }\n\n return this.encodedQuery_ = sb.join('&');\n};\n\n\n/**\n * @throws URIError If URI is malformed (that is, if decodeURIComponent fails on\n * any of the URI components).\n * @return {string} Decoded query string.\n */\ngoog.Uri.QueryData.prototype.toDecodedString = function() {\n 'use strict';\n return goog.Uri.decodeOrEmpty_(this.toString());\n};\n\n\n/**\n * Invalidate the cache.\n * @private\n */\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\n 'use strict';\n this.encodedQuery_ = null;\n};\n\n\n/**\n * Removes all keys that are not in the provided list. (Modifies this object.)\n * @param {Array<string>} keys The desired keys.\n * @return {!goog.Uri.QueryData} a reference to this object.\n */\ngoog.Uri.QueryData.prototype.filterKeys = function(keys) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(value, key) {\n 'use strict';\n if (!goog.array.contains(keys, key)) {\n this.remove(key);\n }\n }, this);\n return this;\n};\n\n\n/**\n * Clone the query data instance.\n * @return {!goog.Uri.QueryData} New instance of the QueryData object.\n */\ngoog.Uri.QueryData.prototype.clone = function() {\n 'use strict';\n var rv = new goog.Uri.QueryData();\n rv.encodedQuery_ = this.encodedQuery_;\n if (this.keyMap_) {\n rv.keyMap_ = /** @type {!Map<string, !Array<*>>} */ (new Map(this.keyMap_));\n rv.count_ = this.count_;\n }\n return rv;\n};\n\n\n/**\n * Helper function to get the key name from a JavaScript object. Converts\n * the object to a string, and to lower case if necessary.\n * @private\n * @param {*} arg The object to get a key name from.\n * @return {string} valid key name which can be looked up in #keyMap_.\n */\ngoog.Uri.QueryData.prototype.getKeyName_ = function(arg) {\n 'use strict';\n var keyName = String(arg);\n if (this.ignoreCase_) {\n keyName = keyName.toLowerCase();\n }\n return keyName;\n};\n\n\n/**\n * Ignore case in parameter names.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n */\ngoog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {\n 'use strict';\n var resetKeys = ignoreCase && !this.ignoreCase_;\n if (resetKeys) {\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n this.keyMap_.forEach(function(value, key) {\n 'use strict';\n var lowerCase = key.toLowerCase();\n if (key != lowerCase) {\n this.remove(key);\n this.setValues(lowerCase, value);\n }\n }, this);\n }\n this.ignoreCase_ = ignoreCase;\n};\n\n\n/**\n * Extends a query data object with another query data or map like object. This\n * operates 'in-place', it does not create a new QueryData object.\n *\n * @param {...(?goog.Uri.QueryData|?goog.collections.maps.MapLike<?,\n * ?>|?Object)} var_args The object from which key value pairs will be\n * copied. Note: does not accept null.\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters.\n */\ngoog.Uri.QueryData.prototype.extend = function(var_args) {\n 'use strict';\n for (var i = 0; i < arguments.length; i++) {\n var data = arguments[i];\n goog.structs.forEach(data, function(value, key) {\n 'use strict';\n this.add(key, value);\n }, this);\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The dispose method is used to clean up references and\n * resources.\n */\n\ngoog.module('goog.dispose');\ngoog.module.declareLegacyNamespace();\n\n/**\n * Calls `dispose` on the argument if it supports it. If obj is not an\n * object with a dispose() method, this is a no-op.\n * @param {*} obj The object to dispose of.\n */\nfunction dispose(obj) {\n if (obj && typeof obj.dispose == 'function') {\n obj.dispose();\n }\n}\nexports = dispose;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Codec functions of the v8 wire protocol. Eventually we'd want\n * to support pluggable wire-format to improve wire efficiency and to enable\n * binary encoding. Such support will require an interface class, which\n * will be added later.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.WireV8');\n\ngoog.require('goog.asserts');\ngoog.require('goog.collections.maps');\ngoog.require('goog.json');\ngoog.require('goog.json.NativeJsonProcessor');\ngoog.require('goog.labs.net.webChannel.Wire');\ngoog.require('goog.structs');\ngoog.requireType('goog.string.Parser');\n\n\n\n/**\n * The v8 codec class.\n *\n * @constructor\n * @struct\n */\ngoog.labs.net.webChannel.WireV8 = function() {\n 'use strict';\n /**\n * Parser for a response payload. The parser should return an array.\n * @private {!goog.string.Parser}\n */\n this.parser_ = new goog.json.NativeJsonProcessor();\n};\n\n\ngoog.scope(function() {\n'use strict';\nconst WireV8 = goog.labs.net.webChannel.WireV8;\nconst Wire = goog.labs.net.webChannel.Wire;\n\n\n/**\n * Encodes a standalone message into the wire format.\n *\n * May throw exception if the message object contains any invalid elements.\n *\n * @param {!Object|!goog.collections.maps.MapLike} message The message data.\n * V8 only support JS objects (or Map).\n * @param {!Array<string>} buffer The text buffer to write the message to.\n * @param {string=} opt_prefix The prefix for each field of the object.\n */\nWireV8.prototype.encodeMessage = function(message, buffer, opt_prefix) {\n 'use strict';\n const prefix = opt_prefix || '';\n try {\n goog.structs.forEach(message, function(value, key) {\n 'use strict';\n let encodedValue = value;\n if (goog.isObject(value)) {\n encodedValue = goog.json.serialize(value);\n } // keep the fast-path for primitive types\n buffer.push(prefix + key + '=' + encodeURIComponent(encodedValue));\n });\n } catch (ex) {\n // We send a map here because lots of the retry logic relies on map IDs,\n // so we have to send something (possibly redundant).\n buffer.push(\n prefix + 'type' +\n '=' + encodeURIComponent('_badmap'));\n throw ex;\n }\n};\n\n\n/**\n * Encodes all the buffered messages of the forward channel.\n *\n * @param {!Array<Wire.QueuedMap>} messageQueue The message data.\n * V8 only support JS objects.\n * @param {number} count The number of messages to be encoded.\n * @param {?function(!Object)} badMapHandler Callback for bad messages.\n * @return {string} the encoded messages\n */\nWireV8.prototype.encodeMessageQueue = function(\n messageQueue, count, badMapHandler) {\n 'use strict';\n let offset = -1;\n while (true) {\n const sb = ['count=' + count];\n // To save a bit of bandwidth, specify the base mapId and the rest as\n // offsets from it.\n if (offset == -1) {\n if (count > 0) {\n offset = messageQueue[0].mapId;\n sb.push('ofs=' + offset);\n } else {\n offset = 0;\n }\n } else {\n sb.push('ofs=' + offset);\n }\n let done = true;\n for (let i = 0; i < count; i++) {\n let mapId = messageQueue[i].mapId;\n const map = messageQueue[i].map;\n mapId -= offset;\n if (mapId < 0) {\n // redo the encoding in case of retry/reordering, plus extra space\n offset = Math.max(0, messageQueue[i].mapId - 100);\n done = false;\n continue;\n }\n try {\n this.encodeMessage(map, sb, 'req' + mapId + '_');\n } catch (ex) {\n if (badMapHandler) {\n badMapHandler(map);\n }\n }\n }\n if (done) {\n return sb.join('&');\n }\n }\n};\n\n\n/**\n * Decodes a standalone message received from the wire. May throw exception\n * if text is ill-formatted.\n *\n * Must be valid JSON as it is insecure to use eval() to decode JS literals;\n * and eval() is disallowed in Chrome apps too.\n *\n * Invalid JS literals include null array elements, quotas etc.\n *\n * @param {string} messageText The string content as received from the wire.\n * @return {*} The decoded message object.\n */\nWireV8.prototype.decodeMessage = function(messageText) {\n 'use strict';\n const response = this.parser_.parse(messageText);\n goog.asserts.assert(Array.isArray(response)); // throw exception\n return response;\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A pool of forward channel requests to enable real-time\n * messaging from the client to server.\n *\n */\n\ngoog.module('goog.labs.net.webChannel.ForwardChannelRequestPool');\n\ngoog.module.declareLegacyNamespace();\n\nconst ChannelRequest = goog.require('goog.labs.net.webChannel.ChannelRequest');\nconst Wire = goog.require('goog.labs.net.webChannel.Wire');\nconst array = goog.require('goog.array');\nconst googString = goog.require('goog.string');\n\n\n/**\n * This class represents the state of all forward channel requests.\n *\n * @param {number=} opt_maxPoolSize The maximum pool size.\n *\n * @struct @constructor @final\n */\nconst ForwardChannelRequestPool = function(opt_maxPoolSize) {\n /**\n * The max pool size as configured.\n *\n * @private {number}\n */\n this.maxPoolSizeConfigured_ =\n opt_maxPoolSize || ForwardChannelRequestPool.MAX_POOL_SIZE_;\n\n /**\n * The current size limit of the request pool. This limit is meant to be\n * read-only after the channel is fully opened.\n *\n * If SPDY or HTTP2 is enabled, set it to the max pool size, which is also\n * configurable.\n *\n * @private {number}\n */\n this.maxSize_ = ForwardChannelRequestPool.isSpdyOrHttp2Enabled_() ?\n this.maxPoolSizeConfigured_ :\n 1;\n\n /**\n * The container for all the pending request objects.\n *\n * @private {?Set<?ChannelRequest>}\n */\n this.requestPool_ = null;\n\n if (this.maxSize_ > 1) {\n this.requestPool_ = new Set();\n }\n\n /**\n * The single request object when the pool size is limited to one.\n *\n * @private {?ChannelRequest}\n */\n this.request_ = null;\n\n /**\n * Saved pending messages when the pool is cancelled.\n *\n * @private {!Array<Wire.QueuedMap>}\n */\n this.pendingMessages_ = [];\n};\n\n\n/**\n * The default size limit of the request pool.\n *\n * @private {number}\n */\nForwardChannelRequestPool.MAX_POOL_SIZE_ = 10;\n\n\n/**\n * @return {boolean} True if SPDY or HTTP2 is enabled. Uses chrome-specific APIs\n * as a fallback and will always return false for other browsers where\n * PerformanceNavigationTiming is not available.\n * @private\n */\nForwardChannelRequestPool.isSpdyOrHttp2Enabled_ = function() {\n if (goog.global.PerformanceNavigationTiming) {\n const entrys = /** @type {!Array<!PerformanceNavigationTiming>} */ (\n goog.global.performance.getEntriesByType('navigation'));\n return entrys.length > 0 &&\n (entrys[0].nextHopProtocol == 'hq' ||\n entrys[0].nextHopProtocol == 'h2');\n }\n return !!(\n goog.global.chrome && goog.global.chrome.loadTimes &&\n goog.global.chrome.loadTimes() &&\n goog.global.chrome.loadTimes().wasFetchedViaSpdy);\n};\n\n\n/**\n * Once we know the client protocol (from the handshake), check if we need\n * enable the request pool accordingly. This is more robust than using\n * browser-internal APIs (specific to Chrome).\n *\n * @param {string} clientProtocol The client protocol\n */\nForwardChannelRequestPool.prototype.applyClientProtocol = function(\n clientProtocol) {\n if (this.requestPool_) {\n return;\n }\n\n if (googString.contains(clientProtocol, 'spdy') ||\n googString.contains(clientProtocol, 'quic') ||\n googString.contains(clientProtocol, 'h2')) {\n this.maxSize_ = this.maxPoolSizeConfigured_;\n this.requestPool_ = new Set();\n if (this.request_) {\n this.addRequest(this.request_);\n this.request_ = null;\n }\n }\n};\n\n\n/**\n * @return {boolean} True if the pool is full.\n */\nForwardChannelRequestPool.prototype.isFull = function() {\n if (this.request_) {\n return true;\n }\n\n if (this.requestPool_) {\n return this.requestPool_.size >= this.maxSize_;\n }\n\n return false;\n};\n\n\n/**\n * @return {number} The current size limit.\n */\nForwardChannelRequestPool.prototype.getMaxSize = function() {\n return this.maxSize_;\n};\n\n\n/**\n * @return {number} The number of pending requests in the pool.\n */\nForwardChannelRequestPool.prototype.getRequestCount = function() {\n if (this.request_) {\n return 1;\n }\n\n if (this.requestPool_) {\n return this.requestPool_.size;\n }\n\n return 0;\n};\n\n\n/**\n * @param {ChannelRequest} req The channel request.\n * @return {boolean} True if the request is a included inside the pool.\n */\nForwardChannelRequestPool.prototype.hasRequest = function(req) {\n if (this.request_) {\n return this.request_ == req;\n }\n\n if (this.requestPool_) {\n return this.requestPool_.has(req);\n }\n\n return false;\n};\n\n\n/**\n * Adds a new request to the pool.\n *\n * @param {!ChannelRequest} req The new channel request.\n */\nForwardChannelRequestPool.prototype.addRequest = function(req) {\n if (this.requestPool_) {\n this.requestPool_.add(req);\n } else {\n this.request_ = req;\n }\n};\n\n\n/**\n * Removes the given request from the pool.\n *\n * @param {ChannelRequest} req The channel request.\n * @return {boolean} Whether the request has been removed from the pool.\n */\nForwardChannelRequestPool.prototype.removeRequest = function(req) {\n if (this.request_ && this.request_ == req) {\n this.request_ = null;\n return true;\n }\n\n if (this.requestPool_ && this.requestPool_.has(req)) {\n this.requestPool_.delete(req);\n return true;\n }\n\n return false;\n};\n\n\n/**\n * Clears the pool and cancel all the pending requests.\n */\nForwardChannelRequestPool.prototype.cancel = function() {\n // save any pending messages\n this.pendingMessages_ = this.getPendingMessages();\n\n if (this.request_) {\n this.request_.cancel();\n this.request_ = null;\n return;\n }\n\n if (this.requestPool_ && this.requestPool_.size !== 0) {\n for (const val of this.requestPool_.values()) {\n val.cancel();\n }\n this.requestPool_.clear();\n }\n};\n\n\n/**\n * @return {boolean} Whether there are any pending requests.\n */\nForwardChannelRequestPool.prototype.hasPendingRequest = function() {\n return (this.request_ != null) ||\n (this.requestPool_ != null && this.requestPool_.size !== 0);\n};\n\n\n/**\n * @return {!Array<Wire.QueuedMap>} All the pending messages from the pool,\n * as a new array.\n */\nForwardChannelRequestPool.prototype.getPendingMessages = function() {\n if (this.request_ != null) {\n return this.pendingMessages_.concat(this.request_.getPendingMessages());\n }\n\n if (this.requestPool_ != null && this.requestPool_.size !== 0) {\n let result = this.pendingMessages_;\n for (const val of this.requestPool_.values()) {\n result = result.concat(val.getPendingMessages());\n }\n return result;\n }\n\n return array.clone(this.pendingMessages_);\n};\n\n\n/**\n * Records pending messages, e.g. when a request receives a failed response.\n *\n * @param {!Array<Wire.QueuedMap>} messages Pending messages.\n */\nForwardChannelRequestPool.prototype.addPendingMessages = function(messages) {\n this.pendingMessages_ = this.pendingMessages_.concat(messages);\n};\n\n\n/**\n * Clears any recorded pending messages.\n */\nForwardChannelRequestPool.prototype.clearPendingMessages = function() {\n this.pendingMessages_.length = 0;\n};\n\n\n/**\n * Cancels all pending requests and force the completion of channel requests.\n *\n * Need go through the standard onRequestComplete logic to expose the max-retry\n * failure in the standard way.\n *\n * @param {function(!ChannelRequest)} onComplete The completion callback.\n * @return {boolean} true if any request has been forced to complete.\n */\nForwardChannelRequestPool.prototype.forceComplete = function(onComplete) {\n if (this.request_ != null) {\n this.request_.cancel();\n onComplete(this.request_);\n return true;\n }\n\n if (this.requestPool_ && this.requestPool_.size !== 0) {\n for (const val of this.requestPool_.values()) {\n val.cancel();\n onComplete(val);\n }\n return true;\n }\n\n return false;\n};\n\nexports = ForwardChannelRequestPool;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Generics method for collection-like classes and objects.\n *\n *\n * This file contains functions to work with collections. It supports using\n * Map, Set, Array and Object and other classes that implement collection-like\n * methods.\n * @suppress {strictMissingProperties}\n */\n\n\ngoog.provide('goog.structs');\n\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n// We treat an object as a dictionary if it has getKeys or it is an object that\n// isn't arrayLike.\n\n\n/**\n * Returns the number of values in the collection-like object.\n * @param {Object} col The collection-like object.\n * @return {number} The number of values in the collection-like object.\n */\ngoog.structs.getCount = function(col) {\n 'use strict';\n if (col.getCount && typeof col.getCount == 'function') {\n return col.getCount();\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return col.length;\n }\n return goog.object.getCount(col);\n};\n\n\n/**\n * Returns the values of the collection-like object.\n * @param {Object} col The collection-like object.\n * @return {!Array<?>} The values in the collection-like object.\n */\ngoog.structs.getValues = function(col) {\n 'use strict';\n if (col.getValues && typeof col.getValues == 'function') {\n return col.getValues();\n }\n // ES6 Map and Set both define a values function that returns an iterator.\n // The typeof check allows the compiler to remove the Map and Set polyfills\n // if they are otherwise unused throughout the entire binary.\n if ((typeof Map !== 'undefined' && col instanceof Map) ||\n (typeof Set !== 'undefined' && col instanceof Set)) {\n return Array.from(col.values());\n }\n if (typeof col === 'string') {\n return col.split('');\n }\n if (goog.isArrayLike(col)) {\n var rv = [];\n var l = col.length;\n for (var i = 0; i < l; i++) {\n rv.push(col[i]);\n }\n return rv;\n }\n return goog.object.getValues(col);\n};\n\n\n/**\n * Returns the keys of the collection. Some collections have no notion of\n * keys/indexes and this function will return undefined in those cases.\n * @param {Object} col The collection-like object.\n * @return {!Array|undefined} The keys in the collection.\n */\ngoog.structs.getKeys = function(col) {\n 'use strict';\n if (col.getKeys && typeof col.getKeys == 'function') {\n return col.getKeys();\n }\n // if we have getValues but no getKeys we know this is a key-less collection\n if (col.getValues && typeof col.getValues == 'function') {\n return undefined;\n }\n // ES6 Map and Set both define a keys function that returns an iterator. For\n // Sets this iterates over the same values as the values iterator.\n // The typeof check allows the compiler to remove the Map and Set polyfills\n // if they are otherwise unused throughout the entire binary.\n if (typeof Map !== 'undefined' && col instanceof Map) {\n return Array.from(col.keys());\n }\n // Unlike the native Set, goog.structs.Set does not expose keys as the values.\n if (typeof Set !== 'undefined' && col instanceof Set) {\n return undefined;\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n var rv = [];\n var l = col.length;\n for (var i = 0; i < l; i++) {\n rv.push(i);\n }\n return rv;\n }\n\n return goog.object.getKeys(col);\n};\n\n\n/**\n * Whether the collection contains the given value. This is O(n) and uses\n * equals (==) to test the existence.\n * @param {Object} col The collection-like object.\n * @param {*} val The value to check for.\n * @return {boolean} True if the map contains the value.\n */\ngoog.structs.contains = function(col, val) {\n 'use strict';\n if (col.contains && typeof col.contains == 'function') {\n return col.contains(val);\n }\n if (col.containsValue && typeof col.containsValue == 'function') {\n return col.containsValue(val);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return goog.array.contains(/** @type {!Array<?>} */ (col), val);\n }\n return goog.object.containsValue(col, val);\n};\n\n\n/**\n * Whether the collection is empty.\n * @param {Object} col The collection-like object.\n * @return {boolean} True if empty.\n */\ngoog.structs.isEmpty = function(col) {\n 'use strict';\n if (col.isEmpty && typeof col.isEmpty == 'function') {\n return col.isEmpty();\n }\n\n // We do not use goog.string.isEmptyOrWhitespace because here we treat the\n // string as\n // collection and as such even whitespace matters\n\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return /** @type {!Array<?>} */ (col).length === 0;\n }\n return goog.object.isEmpty(col);\n};\n\n\n/**\n * Removes all the elements from the collection.\n * @param {Object} col The collection-like object.\n * @return {void}\n */\ngoog.structs.clear = function(col) {\n 'use strict';\n // NOTE(arv): This should not contain strings because strings are immutable\n if (col.clear && typeof col.clear == 'function') {\n col.clear();\n } else if (goog.isArrayLike(col)) {\n goog.array.clear(/** @type {IArrayLike<?>} */ (col));\n } else {\n goog.object.clear(col);\n }\n};\n\n\n/**\n * Calls a function for each value in a collection. The function takes\n * three arguments; the value, the key and the collection.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):?} f The function to call for every value.\n * This function takes\n * 3 arguments (the value, the key or undefined if the collection has no\n * notion of keys, and the collection) and the return value is irrelevant.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n * within `f`.\n * @return {void}\n * @template T,S\n * @deprecated Use a more specific method, e.g. native Array.prototype.forEach,\n * or for-of.\n */\ngoog.structs.forEach = function(col, f, opt_obj) {\n 'use strict';\n if (col.forEach && typeof col.forEach == 'function') {\n col.forEach(f, opt_obj);\n } else if (goog.isArrayLike(col) || typeof col === 'string') {\n Array.prototype.forEach.call(/** @type {!Array<?>} */ (col), f, opt_obj);\n } else {\n var keys = goog.structs.getKeys(col);\n var values = goog.structs.getValues(col);\n var l = values.length;\n for (var i = 0; i < l; i++) {\n f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col);\n }\n }\n};\n\n\n/**\n * Calls a function for every value in the collection. When a call returns true,\n * adds the value to a new collection (Array is returned by default).\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n * value. This function takes\n * 3 arguments (the value, the key or undefined if the collection has no\n * notion of keys, and the collection) and should return a Boolean. If the\n * return value is true the value is added to the result collection. If it\n * is false the value is not included.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n * within `f`.\n * @return {!Object|!Array<?>} A new collection where the passed values are\n * present. If col is a key-less collection an array is returned. If col\n * has keys and values a plain old JS object is returned.\n * @template T,S\n */\ngoog.structs.filter = function(col, f, opt_obj) {\n 'use strict';\n if (typeof col.filter == 'function') {\n return col.filter(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return Array.prototype.filter.call(\n /** @type {!Array<?>} */ (col), f, opt_obj);\n }\n\n var rv;\n var keys = goog.structs.getKeys(col);\n var values = goog.structs.getValues(col);\n var l = values.length;\n if (keys) {\n rv = {};\n for (var i = 0; i < l; i++) {\n if (f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col)) {\n rv[keys[i]] = values[i];\n }\n }\n } else {\n // We should not use Array#filter here since we want to make sure that\n // the index is undefined as well as make sure that col is passed to the\n // function.\n rv = [];\n for (var i = 0; i < l; i++) {\n if (f.call(opt_obj, values[i], undefined, col)) {\n rv.push(values[i]);\n }\n }\n }\n return rv;\n};\n\n\n/**\n * Calls a function for every value in the collection and adds the result into a\n * new collection (defaults to creating a new Array).\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):V} f The function to call for every value.\n * This function takes 3 arguments (the value, the key or undefined if the\n * collection has no notion of keys, and the collection) and should return\n * something. The result will be used as the value in the new collection.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n * within `f`.\n * @return {!Object<V>|!Array<V>} A new collection with the new values. If\n * col is a key-less collection an array is returned. If col has keys and\n * values a plain old JS object is returned.\n * @template T,S,V\n */\ngoog.structs.map = function(col, f, opt_obj) {\n 'use strict';\n if (typeof col.map == 'function') {\n return col.map(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return Array.prototype.map.call(/** @type {!Array<?>} */ (col), f, opt_obj);\n }\n\n var rv;\n var keys = goog.structs.getKeys(col);\n var values = goog.structs.getValues(col);\n var l = values.length;\n if (keys) {\n rv = {};\n for (var i = 0; i < l; i++) {\n rv[keys[i]] = f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col);\n }\n } else {\n // We should not use Array#map here since we want to make sure that\n // the index is undefined as well as make sure that col is passed to the\n // function.\n rv = [];\n for (var i = 0; i < l; i++) {\n rv[i] = f.call(/** @type {?} */ (opt_obj), values[i], undefined, col);\n }\n }\n return rv;\n};\n\n\n/**\n * Calls f for each value in a collection. If any call returns true this returns\n * true (without checking the rest). If all returns false this returns false.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n * value. This function takes 3 arguments (the value, the key or undefined\n * if the collection has no notion of keys, and the collection) and should\n * return a boolean.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n * within `f`.\n * @return {boolean} True if any value passes the test.\n * @template T,S\n */\ngoog.structs.some = function(col, f, opt_obj) {\n 'use strict';\n if (typeof col.some == 'function') {\n return col.some(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return Array.prototype.some.call(\n /** @type {!Array<?>} */ (col), f, opt_obj);\n }\n var keys = goog.structs.getKeys(col);\n var values = goog.structs.getValues(col);\n var l = values.length;\n for (var i = 0; i < l; i++) {\n if (f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {\n return true;\n }\n }\n return false;\n};\n\n\n/**\n * Calls f for each value in a collection. If all calls return true this return\n * true this returns true. If any returns false this returns false at this point\n * and does not continue to check the remaining values.\n *\n * @param {S} col The collection-like object.\n * @param {function(this:T,?,?,S):boolean} f The function to call for every\n * value. This function takes 3 arguments (the value, the key or\n * undefined if the collection has no notion of keys, and the collection)\n * and should return a boolean.\n * @param {T=} opt_obj The object to be used as the value of 'this'\n * within `f`.\n * @return {boolean} True if all key-value pairs pass the test.\n * @template T,S\n */\ngoog.structs.every = function(col, f, opt_obj) {\n 'use strict';\n if (typeof col.every == 'function') {\n return col.every(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return Array.prototype.every.call(\n /** @type {!Array<?>} */ (col), f, opt_obj);\n }\n var keys = goog.structs.getKeys(col);\n var values = goog.structs.getValues(col);\n var l = values.length;\n for (var i = 0; i < l; i++) {\n if (!f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {\n return false;\n }\n }\n return true;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Simple utilities for dealing with URI strings.\n *\n * This package is deprecated in favour of the Closure URL package (goog.url)\n * when manipulating URIs for use by a browser. This package uses regular\n * expressions to parse a potential URI which can fall out of sync with how a\n * browser will actually interpret the URI. See\n * `goog.uri.utils.setUrlPackageSupportLoggingHandler` for one way to identify\n * URIs that should instead be parsed using the URL package.\n *\n * This is intended to be a lightweight alternative to constructing goog.Uri\n * objects. Whereas goog.Uri adds several kilobytes to the binary regardless\n * of how much of its functionality you use, this is designed to be a set of\n * mostly-independent utilities so that the compiler includes only what is\n * necessary for the task. Estimated savings of porting is 5k pre-gzip and\n * 1.5k post-gzip. To ensure the savings remain, future developers should\n * avoid adding new functionality to existing functions, but instead create\n * new ones and factor out shared code.\n *\n * Many of these utilities have limited functionality, tailored to common\n * cases. The query parameter utilities assume that the parameter keys are\n * already encoded, since most keys are compile-time alphanumeric strings. The\n * query parameter mutation utilities also do not tolerate fragment identifiers.\n *\n * By design, these functions can be slower than goog.Uri equivalents.\n * Repeated calls to some of functions may be quadratic in behavior for IE,\n * although the effect is somewhat limited given the 2kb limit.\n *\n * One advantage of the limited functionality here is that this approach is\n * less sensitive to differences in URI encodings than goog.Uri, since these\n * functions operate on strings directly, rather than decoding them and\n * then re-encoding.\n *\n * Uses features of RFC 3986 for parsing/formatting URIs:\n * http://www.ietf.org/rfc/rfc3986.txt\n */\n\ngoog.provide('goog.uri.utils');\ngoog.provide('goog.uri.utils.ComponentIndex');\ngoog.provide('goog.uri.utils.QueryArray');\ngoog.provide('goog.uri.utils.QueryValue');\ngoog.provide('goog.uri.utils.StandardQueryParam');\n\ngoog.require('goog.asserts');\ngoog.require('goog.string');\n\n\n/**\n * Character codes inlined to avoid object allocations due to charCode.\n * @enum {number}\n * @private\n */\ngoog.uri.utils.CharCode_ = {\n AMPERSAND: 38,\n EQUAL: 61,\n HASH: 35,\n QUESTION: 63\n};\n\n\n/**\n * Builds a URI string from already-encoded parts.\n *\n * No encoding is performed. Any component may be omitted as either null or\n * undefined.\n *\n * @param {?string=} opt_scheme The scheme such as 'http'.\n * @param {?string=} opt_userInfo The user name before the '@'.\n * @param {?string=} opt_domain The domain such as 'www.google.com', already\n * URI-encoded.\n * @param {(string|number|null)=} opt_port The port number.\n * @param {?string=} opt_path The path, already URI-encoded. If it is not\n * empty, it must begin with a slash.\n * @param {?string=} opt_queryData The URI-encoded query data.\n * @param {?string=} opt_fragment The URI-encoded fragment identifier.\n * @return {string} The fully combined URI.\n */\ngoog.uri.utils.buildFromEncodedParts = function(\n opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData,\n opt_fragment) {\n 'use strict';\n var out = '';\n\n if (opt_scheme) {\n out += opt_scheme + ':';\n }\n\n if (opt_domain) {\n out += '//';\n\n if (opt_userInfo) {\n out += opt_userInfo + '@';\n }\n\n out += opt_domain;\n\n if (opt_port) {\n out += ':' + opt_port;\n }\n }\n\n if (opt_path) {\n out += opt_path;\n }\n\n if (opt_queryData) {\n out += '?' + opt_queryData;\n }\n\n if (opt_fragment) {\n out += '#' + opt_fragment;\n }\n\n return out;\n};\n\n\n/**\n * A regular expression for breaking a URI into its component parts.\n *\n * {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B\n * As the \"first-match-wins\" algorithm is identical to the \"greedy\"\n * disambiguation method used by POSIX regular expressions, it is natural and\n * commonplace to use a regular expression for parsing the potential five\n * components of a URI reference.\n *\n * The following line is the regular expression for breaking-down a\n * well-formed URI reference into its components.\n *\n * <pre>\n * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?\n * 12 3 4 5 6 7 8 9\n * </pre>\n *\n * The numbers in the second line above are only to assist readability; they\n * indicate the reference points for each subexpression (i.e., each paired\n * parenthesis). We refer to the value matched for subexpression <n> as $<n>.\n * For example, matching the above expression to\n * <pre>\n * http://www.ics.uci.edu/pub/ietf/uri/#Related\n * </pre>\n * results in the following subexpression matches:\n * <pre>\n * $1 = http:\n * $2 = http\n * $3 = //www.ics.uci.edu\n * $4 = www.ics.uci.edu\n * $5 = /pub/ietf/uri/\n * $6 = <undefined>\n * $7 = <undefined>\n * $8 = #Related\n * $9 = Related\n * </pre>\n * where <undefined> indicates that the component is not present, as is the\n * case for the query component in the above example. Therefore, we can\n * determine the value of the five components as\n * <pre>\n * scheme = $2\n * authority = $4\n * path = $5\n * query = $7\n * fragment = $9\n * </pre>\n *\n * The regular expression has been modified slightly to expose the\n * userInfo, domain, and port separately from the authority.\n * The modified version yields\n * <pre>\n * $1 = http scheme\n * $2 = <undefined> userInfo -\\\n * $3 = www.ics.uci.edu domain | authority\n * $4 = <undefined> port -/\n * $5 = /pub/ietf/uri/ path\n * $6 = <undefined> query without ?\n * $7 = Related fragment without #\n * </pre>\n *\n * TODO(user): separate out the authority terminating characters once this\n * file is moved to ES6.\n * @type {!RegExp}\n * @private\n */\ngoog.uri.utils.splitRe_ = new RegExp(\n '^' + // Anchor against the entire string.\n '(?:' +\n '([^:/?#.]+)' + // scheme - ignore special characters\n // used by other URL parts such as :,\n // ?, /, #, and .\n ':)?' +\n '(?://' +\n '(?:([^\\\\\\\\/?#]*)@)?' + // userInfo\n '([^\\\\\\\\/?#]*?)' + // domain\n '(?::([0-9]+))?' + // port\n '(?=[\\\\\\\\/?#]|$)' + // authority-terminating character.\n ')?' +\n '([^?#]+)?' + // path\n '(?:\\\\?([^#]*))?' + // query\n '(?:#([\\\\s\\\\S]*))?' + // fragment. Can't use '.*' with 's' flag as Firefox\n // doesn't support the flag, and can't use an\n // \"everything set\" ([^]) as IE10 doesn't match any\n // characters with it.\n '$');\n\n\n/**\n * The index of each URI component in the return value of goog.uri.utils.split.\n * @enum {number}\n */\ngoog.uri.utils.ComponentIndex = {\n SCHEME: 1,\n USER_INFO: 2,\n DOMAIN: 3,\n PORT: 4,\n PATH: 5,\n QUERY_DATA: 6,\n FRAGMENT: 7\n};\n\n/**\n * @type {?function(string)}\n * @private\n */\ngoog.uri.utils.urlPackageSupportLoggingHandler_ = null;\n\n/**\n * @param {?function(string)} handler The handler function to call when a URI\n * with a protocol that is better supported by the Closure URL package is\n * detected.\n */\ngoog.uri.utils.setUrlPackageSupportLoggingHandler = function(handler) {\n 'use strict';\n goog.uri.utils.urlPackageSupportLoggingHandler_ = handler;\n};\n\n/**\n * Splits a URI into its component parts.\n *\n * Each component can be accessed via the component indices; for example:\n * <pre>\n * goog.uri.utils.split(someStr)[goog.uri.utils.ComponentIndex.QUERY_DATA];\n * </pre>\n *\n * @param {string} uri The URI string to examine.\n * @return {!Array<string|undefined>} Each component still URI-encoded.\n * Each component that is present will contain the encoded value, whereas\n * components that are not present will be undefined or empty, depending\n * on the browser's regular expression implementation. Never null, since\n * arbitrary strings may still look like path names.\n */\ngoog.uri.utils.split = function(uri) {\n 'use strict';\n // See @return comment -- never null.\n var result = /** @type {!Array<string|undefined>} */ (\n uri.match(goog.uri.utils.splitRe_));\n if (goog.uri.utils.urlPackageSupportLoggingHandler_ &&\n ['http', 'https', 'ws', 'wss',\n 'ftp'].indexOf(result[goog.uri.utils.ComponentIndex.SCHEME]) >= 0) {\n goog.uri.utils.urlPackageSupportLoggingHandler_(uri);\n }\n return result;\n};\n\n\n/**\n * @param {?string} uri A possibly null string.\n * @param {boolean=} opt_preserveReserved If true, percent-encoding of RFC-3986\n * reserved characters will not be removed.\n * @return {?string} The string URI-decoded, or null if uri is null.\n * @private\n */\ngoog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) {\n 'use strict';\n if (!uri) {\n return uri;\n }\n\n return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri);\n};\n\n\n/**\n * Gets a URI component by index.\n *\n * It is preferred to use the getPathEncoded() variety of functions ahead,\n * since they are more readable.\n *\n * @param {goog.uri.utils.ComponentIndex} componentIndex The component index.\n * @param {string} uri The URI to examine.\n * @return {?string} The still-encoded component, or null if the component\n * is not present.\n * @private\n */\ngoog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) {\n 'use strict';\n // Convert undefined, null, and empty string into null.\n return goog.uri.utils.split(uri)[componentIndex] || null;\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The protocol or scheme, or null if none. Does not\n * include trailing colons or slashes.\n */\ngoog.uri.utils.getScheme = function(uri) {\n 'use strict';\n return goog.uri.utils.getComponentByIndex_(\n goog.uri.utils.ComponentIndex.SCHEME, uri);\n};\n\n\n/**\n * Gets the effective scheme for the URL. If the URL is relative then the\n * scheme is derived from the page's location.\n * @param {string} uri The URI to examine.\n * @return {string} The protocol or scheme, always lower case.\n */\ngoog.uri.utils.getEffectiveScheme = function(uri) {\n 'use strict';\n var scheme = goog.uri.utils.getScheme(uri);\n if (!scheme && goog.global.self && goog.global.self.location) {\n var protocol = goog.global.self.location.protocol;\n scheme = protocol.slice(0, -1);\n }\n // NOTE: When called from a web worker in Firefox 3.5, location may be null.\n // All other browsers with web workers support self.location from the worker.\n return scheme ? scheme.toLowerCase() : '';\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The user name still encoded, or null if none.\n */\ngoog.uri.utils.getUserInfoEncoded = function(uri) {\n 'use strict';\n return goog.uri.utils.getComponentByIndex_(\n goog.uri.utils.ComponentIndex.USER_INFO, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded user info, or null if none.\n */\ngoog.uri.utils.getUserInfo = function(uri) {\n 'use strict';\n return goog.uri.utils.decodeIfPossible_(\n goog.uri.utils.getUserInfoEncoded(uri));\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The domain name still encoded, or null if none.\n */\ngoog.uri.utils.getDomainEncoded = function(uri) {\n 'use strict';\n return goog.uri.utils.getComponentByIndex_(\n goog.uri.utils.ComponentIndex.DOMAIN, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded domain, or null if none.\n */\ngoog.uri.utils.getDomain = function(uri) {\n 'use strict';\n return goog.uri.utils.decodeIfPossible_(\n goog.uri.utils.getDomainEncoded(uri), true /* opt_preserveReserved */);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?number} The port number, or null if none.\n */\ngoog.uri.utils.getPort = function(uri) {\n 'use strict';\n // Coerce to a number. If the result of getComponentByIndex_ is null or\n // non-numeric, the number coersion yields NaN. This will then return\n // null for all non-numeric cases (though also zero, which isn't a relevant\n // port number).\n return Number(\n goog.uri.utils.getComponentByIndex_(\n goog.uri.utils.ComponentIndex.PORT, uri)) ||\n null;\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The path still encoded, or null if none. Includes the\n * leading slash, if any.\n */\ngoog.uri.utils.getPathEncoded = function(uri) {\n 'use strict';\n return goog.uri.utils.getComponentByIndex_(\n goog.uri.utils.ComponentIndex.PATH, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded path, or null if none. Includes the leading\n * slash, if any.\n */\ngoog.uri.utils.getPath = function(uri) {\n 'use strict';\n return goog.uri.utils.decodeIfPossible_(\n goog.uri.utils.getPathEncoded(uri), true /* opt_preserveReserved */);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The query data still encoded, or null if none. Does not\n * include the question mark itself.\n */\ngoog.uri.utils.getQueryData = function(uri) {\n 'use strict';\n return goog.uri.utils.getComponentByIndex_(\n goog.uri.utils.ComponentIndex.QUERY_DATA, uri);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The fragment identifier, or null if none. Does not\n * include the hash mark itself.\n */\ngoog.uri.utils.getFragmentEncoded = function(uri) {\n 'use strict';\n // The hash mark may not appear in any other part of the URL.\n var hashIndex = uri.indexOf('#');\n return hashIndex < 0 ? null : uri.slice(hashIndex + 1);\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @param {?string} fragment The encoded fragment identifier, or null if none.\n * Does not include the hash mark itself.\n * @return {string} The URI with the fragment set.\n */\ngoog.uri.utils.setFragmentEncoded = function(uri, fragment) {\n 'use strict';\n return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : '');\n};\n\n\n/**\n * @param {string} uri The URI to examine.\n * @return {?string} The decoded fragment identifier, or null if none. Does\n * not include the hash mark.\n */\ngoog.uri.utils.getFragment = function(uri) {\n 'use strict';\n return goog.uri.utils.decodeIfPossible_(\n goog.uri.utils.getFragmentEncoded(uri));\n};\n\n\n/**\n * Extracts everything up to the port of the URI.\n * @param {string} uri The URI string.\n * @return {string} Everything up to and including the port.\n */\ngoog.uri.utils.getHost = function(uri) {\n 'use strict';\n var pieces = goog.uri.utils.split(uri);\n return goog.uri.utils.buildFromEncodedParts(\n pieces[goog.uri.utils.ComponentIndex.SCHEME],\n pieces[goog.uri.utils.ComponentIndex.USER_INFO],\n pieces[goog.uri.utils.ComponentIndex.DOMAIN],\n pieces[goog.uri.utils.ComponentIndex.PORT]);\n};\n\n\n/**\n * Returns the origin for a given URL.\n * @param {string} uri The URI string.\n * @return {string} Everything up to and including the port.\n */\ngoog.uri.utils.getOrigin = function(uri) {\n 'use strict';\n var pieces = goog.uri.utils.split(uri);\n return goog.uri.utils.buildFromEncodedParts(\n pieces[goog.uri.utils.ComponentIndex.SCHEME], null /* opt_userInfo */,\n pieces[goog.uri.utils.ComponentIndex.DOMAIN],\n pieces[goog.uri.utils.ComponentIndex.PORT]);\n};\n\n\n/**\n * Extracts the path of the URL and everything after.\n * @param {string} uri The URI string.\n * @return {string} The URI, starting at the path and including the query\n * parameters and fragment identifier.\n */\ngoog.uri.utils.getPathAndAfter = function(uri) {\n 'use strict';\n var pieces = goog.uri.utils.split(uri);\n return goog.uri.utils.buildFromEncodedParts(\n null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH],\n pieces[goog.uri.utils.ComponentIndex.QUERY_DATA],\n pieces[goog.uri.utils.ComponentIndex.FRAGMENT]);\n};\n\n\n/**\n * Gets the URI with the fragment identifier removed.\n * @param {string} uri The URI to examine.\n * @return {string} Everything preceding the hash mark.\n */\ngoog.uri.utils.removeFragment = function(uri) {\n 'use strict';\n // The hash mark may not appear in any other part of the URL.\n var hashIndex = uri.indexOf('#');\n return hashIndex < 0 ? uri : uri.slice(0, hashIndex);\n};\n\n\n/**\n * Ensures that two URI's have the exact same domain, scheme, and port.\n *\n * Unlike the version in goog.Uri, this checks protocol, and therefore is\n * suitable for checking against the browser's same-origin policy.\n *\n * @param {string} uri1 The first URI.\n * @param {string} uri2 The second URI.\n * @return {boolean} Whether they have the same scheme, domain and port.\n */\ngoog.uri.utils.haveSameDomain = function(uri1, uri2) {\n 'use strict';\n var pieces1 = goog.uri.utils.split(uri1);\n var pieces2 = goog.uri.utils.split(uri2);\n return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n pieces1[goog.uri.utils.ComponentIndex.SCHEME] ==\n pieces2[goog.uri.utils.ComponentIndex.SCHEME] &&\n pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n/**\n * Asserts that there are no fragment or query identifiers, only in uncompiled\n * mode.\n * @param {string} uri The URI to examine.\n * @private\n */\ngoog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) {\n 'use strict';\n goog.asserts.assert(\n uri.indexOf('#') < 0 && uri.indexOf('?') < 0,\n 'goog.uri.utils: Fragment or query identifiers are not supported: [%s]',\n uri);\n};\n\n\n/**\n * Supported query parameter values by the parameter serializing utilities.\n *\n * If a value is null or undefined, the key-value pair is skipped, as an easy\n * way to omit parameters conditionally. Non-array parameters are converted\n * to a string and URI encoded. Array values are expanded into multiple\n * &key=value pairs, with each element stringized and URI-encoded.\n *\n * @typedef {*}\n */\ngoog.uri.utils.QueryValue;\n\n\n/**\n * An array representing a set of query parameters with alternating keys\n * and values.\n *\n * Keys are assumed to be URI encoded already and live at even indices. See\n * goog.uri.utils.QueryValue for details on how parameter values are encoded.\n *\n * Example:\n * <pre>\n * var data = [\n * // Simple param: ?name=BobBarker\n * 'name', 'BobBarker',\n * // Conditional param -- may be omitted entirely.\n * 'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null,\n * // Multi-valued param: &house=LosAngeles&house=NewYork&house=null\n * 'house', ['LosAngeles', 'NewYork', null]\n * ];\n * </pre>\n *\n * @typedef {!Array<string|goog.uri.utils.QueryValue>}\n */\ngoog.uri.utils.QueryArray;\n\n\n/**\n * Parses encoded query parameters and calls callback function for every\n * parameter found in the string.\n *\n * Missing value of parameter (e.g. “…&key&…”) is treated as if the value was an\n * empty string. Keys may be empty strings (e.g. “…&=value&…”) which also means\n * that “…&=&…” and “…&&…” will result in an empty key and value.\n *\n * @param {string} encodedQuery Encoded query string excluding question mark at\n * the beginning.\n * @param {function(string, string)} callback Function called for every\n * parameter found in query string. The first argument (name) will not be\n * urldecoded (so the function is consistent with buildQueryData), but the\n * second will. If the parameter has no value (i.e. “=” was not present)\n * the second argument (value) will be an empty string.\n */\ngoog.uri.utils.parseQueryData = function(encodedQuery, callback) {\n 'use strict';\n if (!encodedQuery) {\n return;\n }\n var pairs = encodedQuery.split('&');\n for (var i = 0; i < pairs.length; i++) {\n var indexOfEquals = pairs[i].indexOf('=');\n var name = null;\n var value = null;\n if (indexOfEquals >= 0) {\n name = pairs[i].substring(0, indexOfEquals);\n value = pairs[i].substring(indexOfEquals + 1);\n } else {\n name = pairs[i];\n }\n callback(name, value ? goog.string.urlDecode(value) : '');\n }\n};\n\n\n/**\n * Split the URI into 3 parts where the [1] is the queryData without a leading\n * '?'. For example, the URI http://foo.com/bar?a=b#abc returns\n * ['http://foo.com/bar','a=b','#abc'].\n * @param {string} uri The URI to parse.\n * @return {!Array<string>} An array representation of uri of length 3 where the\n * middle value is the queryData without a leading '?'.\n * @private\n */\ngoog.uri.utils.splitQueryData_ = function(uri) {\n 'use strict';\n // Find the query data and hash.\n var hashIndex = uri.indexOf('#');\n if (hashIndex < 0) {\n hashIndex = uri.length;\n }\n var questionIndex = uri.indexOf('?');\n var queryData;\n if (questionIndex < 0 || questionIndex > hashIndex) {\n questionIndex = hashIndex;\n queryData = '';\n } else {\n queryData = uri.substring(questionIndex + 1, hashIndex);\n }\n return [uri.slice(0, questionIndex), queryData, uri.slice(hashIndex)];\n};\n\n\n/**\n * Join an array created by splitQueryData_ back into a URI.\n * @param {!Array<string>} parts A URI in the form generated by splitQueryData_.\n * @return {string} The joined URI.\n * @private\n */\ngoog.uri.utils.joinQueryData_ = function(parts) {\n 'use strict';\n return parts[0] + (parts[1] ? '?' + parts[1] : '') + parts[2];\n};\n\n\n/**\n * @param {string} queryData\n * @param {string} newData\n * @return {string}\n * @private\n */\ngoog.uri.utils.appendQueryData_ = function(queryData, newData) {\n 'use strict';\n if (!newData) {\n return queryData;\n }\n return queryData ? queryData + '&' + newData : newData;\n};\n\n\n/**\n * @param {string} uri\n * @param {string} queryData\n * @return {string}\n * @private\n */\ngoog.uri.utils.appendQueryDataToUri_ = function(uri, queryData) {\n 'use strict';\n if (!queryData) {\n return uri;\n }\n var parts = goog.uri.utils.splitQueryData_(uri);\n parts[1] = goog.uri.utils.appendQueryData_(parts[1], queryData);\n return goog.uri.utils.joinQueryData_(parts);\n};\n\n\n/**\n * Appends key=value pairs to an array, supporting multi-valued objects.\n * @param {*} key The key prefix.\n * @param {goog.uri.utils.QueryValue} value The value to serialize.\n * @param {!Array<string>} pairs The array to which the 'key=value' strings\n * should be appended.\n * @private\n */\ngoog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) {\n 'use strict';\n goog.asserts.assertString(key);\n if (Array.isArray(value)) {\n // Convince the compiler it's an array.\n goog.asserts.assertArray(value);\n for (var j = 0; j < value.length; j++) {\n // Convert to string explicitly, to short circuit the null and array\n // logic in this function -- this ensures that null and undefined get\n // written as literal 'null' and 'undefined', and arrays don't get\n // expanded out but instead encoded in the default way.\n goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs);\n }\n } else if (value != null) {\n // Skip a top-level null or undefined entirely.\n pairs.push(\n key +\n // Check for empty string. Zero gets encoded into the url as literal\n // strings. For empty string, skip the equal sign, to be consistent\n // with UriBuilder.java.\n (value === '' ? '' : '=' + goog.string.urlEncode(value)));\n }\n};\n\n\n/**\n * Builds a query data string from a sequence of alternating keys and values.\n * Currently generates \"&key&\" for empty args.\n *\n * @param {!IArrayLike<string|goog.uri.utils.QueryValue>} keysAndValues\n * Alternating keys and values. See the QueryArray typedef.\n * @param {number=} opt_startIndex A start offset into the arary, defaults to 0.\n * @return {string} The encoded query string, in the form 'a=1&b=2'.\n */\ngoog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) {\n 'use strict';\n goog.asserts.assert(\n Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2 == 0,\n 'goog.uri.utils: Key/value lists must be even in length.');\n\n var params = [];\n for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) {\n var key = /** @type {string} */ (keysAndValues[i]);\n goog.uri.utils.appendKeyValuePairs_(key, keysAndValues[i + 1], params);\n }\n return params.join('&');\n};\n\n\n/**\n * Builds a query data string from a map.\n * Currently generates \"&key&\" for empty args.\n *\n * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys\n * are URI-encoded parameter keys, and the values are arbitrary types\n * or arrays. Keys with a null value are dropped.\n * @return {string} The encoded query string, in the form 'a=1&b=2'.\n */\ngoog.uri.utils.buildQueryDataFromMap = function(map) {\n 'use strict';\n var params = [];\n for (var key in map) {\n goog.uri.utils.appendKeyValuePairs_(key, map[key], params);\n }\n return params.join('&');\n};\n\n\n/**\n * Appends URI parameters to an existing URI.\n *\n * The variable arguments may contain alternating keys and values. Keys are\n * assumed to be already URI encoded. The values should not be URI-encoded,\n * and will instead be encoded by this function.\n * <pre>\n * appendParams('http://www.foo.com?existing=true',\n * 'key1', 'value1',\n * 'key2', 'value?willBeEncoded',\n * 'key3', ['valueA', 'valueB', 'valueC'],\n * 'key4', null);\n * result: 'http://www.foo.com?existing=true&' +\n * 'key1=value1&' +\n * 'key2=value%3FwillBeEncoded&' +\n * 'key3=valueA&key3=valueB&key3=valueC'\n * </pre>\n *\n * A single call to this function will not exhibit quadratic behavior in IE,\n * whereas multiple repeated calls may, although the effect is limited by\n * fact that URL's generally can't exceed 2kb.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {...(goog.uri.utils.QueryArray|goog.uri.utils.QueryValue)}\n * var_args\n * An array or argument list conforming to goog.uri.utils.QueryArray.\n * @return {string} The URI with all query parameters added.\n */\ngoog.uri.utils.appendParams = function(uri, var_args) {\n 'use strict';\n var queryData = arguments.length == 2 ?\n goog.uri.utils.buildQueryData(arguments[1], 0) :\n goog.uri.utils.buildQueryData(arguments, 1);\n return goog.uri.utils.appendQueryDataToUri_(uri, queryData);\n};\n\n\n/**\n * Appends query parameters from a map.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {!Object<goog.uri.utils.QueryValue>} map An object where keys are\n * URI-encoded parameter keys, and the values are arbitrary types or arrays.\n * Keys with a null value are dropped.\n * @return {string} The new parameters.\n */\ngoog.uri.utils.appendParamsFromMap = function(uri, map) {\n 'use strict';\n var queryData = goog.uri.utils.buildQueryDataFromMap(map);\n return goog.uri.utils.appendQueryDataToUri_(uri, queryData);\n};\n\n\n/**\n * Appends a single URI parameter.\n *\n * Repeated calls to this can exhibit quadratic behavior in IE6 due to the\n * way string append works, though it should be limited given the 2kb limit.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {string} key The key, which must already be URI encoded.\n * @param {*=} opt_value The value, which will be stringized and encoded\n * (assumed not already to be encoded). If omitted, undefined, or null, the\n * key will be added as a valueless parameter.\n * @return {string} The URI with the query parameter added.\n */\ngoog.uri.utils.appendParam = function(uri, key, opt_value) {\n 'use strict';\n var value = (opt_value != null) ? '=' + goog.string.urlEncode(opt_value) : '';\n return goog.uri.utils.appendQueryDataToUri_(uri, key + value);\n};\n\n\n/**\n * Finds the next instance of a query parameter with the specified name.\n *\n * Does not instantiate any objects.\n *\n * @param {string} uri The URI to search. May contain a fragment identifier\n * if opt_hashIndex is specified.\n * @param {number} startIndex The index to begin searching for the key at. A\n * match may be found even if this is one character after the ampersand.\n * @param {string} keyEncoded The URI-encoded key.\n * @param {number} hashOrEndIndex Index to stop looking at. If a hash\n * mark is present, it should be its index, otherwise it should be the\n * length of the string.\n * @return {number} The position of the first character in the key's name,\n * immediately after either a question mark or a dot.\n * @private\n */\ngoog.uri.utils.findParam_ = function(\n uri, startIndex, keyEncoded, hashOrEndIndex) {\n 'use strict';\n var index = startIndex;\n var keyLength = keyEncoded.length;\n\n // Search for the key itself and post-filter for surronuding punctuation,\n // rather than expensively building a regexp.\n while ((index = uri.indexOf(keyEncoded, index)) >= 0 &&\n index < hashOrEndIndex) {\n var precedingChar = uri.charCodeAt(index - 1);\n // Ensure that the preceding character is '&' or '?'.\n if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND ||\n precedingChar == goog.uri.utils.CharCode_.QUESTION) {\n // Ensure the following character is '&', '=', '#', or NaN\n // (end of string).\n var followingChar = uri.charCodeAt(index + keyLength);\n if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL ||\n followingChar == goog.uri.utils.CharCode_.AMPERSAND ||\n followingChar == goog.uri.utils.CharCode_.HASH) {\n return index;\n }\n }\n index += keyLength + 1;\n }\n\n return -1;\n};\n\n\n/**\n * Regular expression for finding a hash mark or end of string.\n * @type {RegExp}\n * @private\n */\ngoog.uri.utils.hashOrEndRe_ = /#|$/;\n\n\n/**\n * Determines if the URI contains a specific key.\n *\n * Performs no object instantiations.\n *\n * @param {string} uri The URI to process. May contain a fragment\n * identifier.\n * @param {string} keyEncoded The URI-encoded key. Case-sensitive.\n * @return {boolean} Whether the key is present.\n */\ngoog.uri.utils.hasParam = function(uri, keyEncoded) {\n 'use strict';\n return goog.uri.utils.findParam_(\n uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)) >= 0;\n};\n\n\n/**\n * Gets the first value of a query parameter.\n * @param {string} uri The URI to process. May contain a fragment.\n * @param {string} keyEncoded The URI-encoded key. Case-sensitive.\n * @return {?string} The first value of the parameter (URI-decoded), or null\n * if the parameter is not found.\n */\ngoog.uri.utils.getParamValue = function(uri, keyEncoded) {\n 'use strict';\n var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n var foundIndex =\n goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex);\n\n if (foundIndex < 0) {\n return null;\n } else {\n var endPosition = uri.indexOf('&', foundIndex);\n if (endPosition < 0 || endPosition > hashOrEndIndex) {\n endPosition = hashOrEndIndex;\n }\n // Progress forth to the end of the \"key=\" or \"key&\" substring.\n foundIndex += keyEncoded.length + 1;\n return goog.string.urlDecode(\n uri.slice(foundIndex, endPosition !== -1 ? endPosition : 0));\n }\n};\n\n\n/**\n * Gets all values of a query parameter.\n * @param {string} uri The URI to process. May contain a fragment.\n * @param {string} keyEncoded The URI-encoded key. Case-sensitive.\n * @return {!Array<string>} All URI-decoded values with the given key.\n * If the key is not found, this will have length 0, but never be null.\n */\ngoog.uri.utils.getParamValues = function(uri, keyEncoded) {\n 'use strict';\n var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n var position = 0;\n var foundIndex;\n var result = [];\n\n while ((foundIndex = goog.uri.utils.findParam_(\n uri, position, keyEncoded, hashOrEndIndex)) >= 0) {\n // Find where this parameter ends, either the '&' or the end of the\n // query parameters.\n position = uri.indexOf('&', foundIndex);\n if (position < 0 || position > hashOrEndIndex) {\n position = hashOrEndIndex;\n }\n\n // Progress forth to the end of the \"key=\" or \"key&\" substring.\n foundIndex += keyEncoded.length + 1;\n result.push(\n goog.string.urlDecode(uri.slice(foundIndex, Math.max(position, 0))));\n }\n\n return result;\n};\n\n\n/**\n * Regexp to find trailing question marks and ampersands.\n * @type {RegExp}\n * @private\n */\ngoog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/;\n\n\n/**\n * Removes all instances of a query parameter.\n * @param {string} uri The URI to process. Must not contain a fragment.\n * @param {string} keyEncoded The URI-encoded key.\n * @return {string} The URI with all instances of the parameter removed.\n */\ngoog.uri.utils.removeParam = function(uri, keyEncoded) {\n 'use strict';\n var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_);\n var position = 0;\n var foundIndex;\n var buffer = [];\n\n // Look for a query parameter.\n while ((foundIndex = goog.uri.utils.findParam_(\n uri, position, keyEncoded, hashOrEndIndex)) >= 0) {\n // Get the portion of the query string up to, but not including, the ?\n // or & starting the parameter.\n buffer.push(uri.substring(position, foundIndex));\n // Progress to immediately after the '&'. If not found, go to the end.\n // Avoid including the hash mark.\n position = Math.min(\n (uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex, hashOrEndIndex);\n }\n\n // Append everything that is remaining.\n buffer.push(uri.slice(position));\n\n // Join the buffer, and remove trailing punctuation that remains.\n return buffer.join('').replace(\n goog.uri.utils.trailingQueryPunctuationRe_, '$1');\n};\n\n\n/**\n * Replaces all existing definitions of a parameter with a single definition.\n *\n * Repeated calls to this can exhibit quadratic behavior due to the need to\n * find existing instances and reconstruct the string, though it should be\n * limited given the 2kb limit. Consider using appendParams or setParamsFromMap\n * to update multiple parameters in bulk.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {string} keyEncoded The key, which must already be URI encoded.\n * @param {*} value The value, which will be stringized and encoded (assumed\n * not already to be encoded).\n * @return {string} The URI with the query parameter added.\n */\ngoog.uri.utils.setParam = function(uri, keyEncoded, value) {\n 'use strict';\n return goog.uri.utils.appendParam(\n goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value);\n};\n\n\n/**\n * Effeciently set or remove multiple query parameters in a URI. Order of\n * unchanged parameters will not be modified, all updated parameters will be\n * appended to the end of the query. Params with values of null or undefined are\n * removed.\n *\n * @param {string} uri The URI to process.\n * @param {!Object<string, goog.uri.utils.QueryValue>} params A list of\n * parameters to update. If null or undefined, the param will be removed.\n * @return {string} An updated URI where the query data has been updated with\n * the params.\n */\ngoog.uri.utils.setParamsFromMap = function(uri, params) {\n 'use strict';\n var parts = goog.uri.utils.splitQueryData_(uri);\n var queryData = parts[1];\n var buffer = [];\n if (queryData) {\n queryData.split('&').forEach(function(pair) {\n 'use strict';\n var indexOfEquals = pair.indexOf('=');\n var name = indexOfEquals >= 0 ? pair.slice(0, indexOfEquals) : pair;\n if (!params.hasOwnProperty(name)) {\n buffer.push(pair);\n }\n });\n }\n parts[1] = goog.uri.utils.appendQueryData_(\n buffer.join('&'), goog.uri.utils.buildQueryDataFromMap(params));\n return goog.uri.utils.joinQueryData_(parts);\n};\n\n\n/**\n * Generates a URI path using a given URI and a path with checks to\n * prevent consecutive \"//\". The baseUri passed in must not contain\n * query or fragment identifiers. The path to append may not contain query or\n * fragment identifiers.\n *\n * @param {string} baseUri URI to use as the base.\n * @param {string} path Path to append.\n * @return {string} Updated URI.\n */\ngoog.uri.utils.appendPath = function(baseUri, path) {\n 'use strict';\n goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);\n\n // Remove any trailing '/'\n if (goog.string.endsWith(baseUri, '/')) {\n baseUri = baseUri.slice(0, -1);\n }\n // Remove any leading '/'\n if (goog.string.startsWith(path, '/')) {\n path = path.slice(1);\n }\n return '' + baseUri + '/' + path;\n};\n\n\n/**\n * Replaces the path.\n * @param {string} uri URI to use as the base.\n * @param {string} path New path.\n * @return {string} Updated URI.\n */\ngoog.uri.utils.setPath = function(uri, path) {\n 'use strict';\n // Add any missing '/'.\n if (!goog.string.startsWith(path, '/')) {\n path = '/' + path;\n }\n var parts = goog.uri.utils.split(uri);\n return goog.uri.utils.buildFromEncodedParts(\n parts[goog.uri.utils.ComponentIndex.SCHEME],\n parts[goog.uri.utils.ComponentIndex.USER_INFO],\n parts[goog.uri.utils.ComponentIndex.DOMAIN],\n parts[goog.uri.utils.ComponentIndex.PORT], path,\n parts[goog.uri.utils.ComponentIndex.QUERY_DATA],\n parts[goog.uri.utils.ComponentIndex.FRAGMENT]);\n};\n\n\n/**\n * Standard supported query parameters.\n * @enum {string}\n */\ngoog.uri.utils.StandardQueryParam = {\n\n /** Unused parameter for unique-ifying. */\n RANDOM: 'zx'\n};\n\n\n/**\n * Sets the zx parameter of a URI to a random value.\n * @param {string} uri Any URI.\n * @return {string} That URI with the \"zx\" parameter added or replaced to\n * contain a random string.\n */\ngoog.uri.utils.makeUnique = function(uri) {\n 'use strict';\n return goog.uri.utils.setParam(\n uri, goog.uri.utils.StandardQueryParam.RANDOM,\n goog.string.getRandomString());\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Interface and shared data structures for implementing\n * different wire protocol versions.\n */\ngoog.provide('goog.labs.net.webChannel.Wire');\ngoog.provide('goog.labs.net.webChannel.Wire.QueuedMap');\n\n\n\ngoog.require('goog.collections.maps');\n\n\n\n/**\n * The interface class.\n * @interface\n */\ngoog.labs.net.webChannel.Wire = class {\n constructor() {}\n};\n\n\n/**\n * The latest protocol version that this class supports. We request this version\n * from the server when opening the connection. Should match\n * LATEST_CHANNEL_VERSION on the server code.\n * @type {number}\n */\ngoog.labs.net.webChannel.Wire.LATEST_CHANNEL_VERSION = 8;\n\n\n/**\n * The JSON field key for the raw data wrapper object.\n * @type {string}\n */\ngoog.labs.net.webChannel.Wire.RAW_DATA_KEY = '__data__';\n\n\n\n/**\n * Simple container class for a (mapId, map) pair.\n */\ngoog.labs.net.webChannel.Wire.QueuedMap = class {\n /**\n * @param {number} mapId The id for this map.\n * @param {!Object|!goog.collections.maps.MapLike} map The map itself.\n * @param {!Object=} opt_context The context associated with the map.\n */\n constructor(mapId, map, opt_context) {\n 'use strict';\n /**\n * The id for this map.\n * @type {number}\n */\n this.mapId = mapId;\n\n /**\n * The map itself.\n * @type {!Object|!goog.collections.maps.MapLike}\n */\n this.map = map;\n\n /**\n * The context for the map.\n * @type {Object}\n */\n this.context = opt_context || null;\n }\n\n /**\n * @return {number|undefined} the size of the raw JSON message or\n * undefined if the message is not encoded as a raw JSON message\n */\n getRawDataSize() {\n 'use strict';\n if (goog.labs.net.webChannel.Wire.RAW_DATA_KEY in this.map) {\n const data = this.map[goog.labs.net.webChannel.Wire.RAW_DATA_KEY];\n if (typeof data === 'string') {\n return data.length;\n }\n }\n\n return undefined;\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Defines a class for parsing JSON using the browser's built in\n * JSON library.\n */\n\ngoog.module('goog.json.NativeJsonProcessor');\ngoog.module.declareLegacyNamespace();\n\nconst Parser = goog.require('goog.string.Parser');\nconst Stringifier = goog.require('goog.string.Stringifier');\nconst asserts = goog.require('goog.asserts');\nconst {Replacer, Reviver} = goog.require('goog.json.types');\n\n\n\n/**\n * A class that parses and stringifies JSON using the browser's built-in JSON\n * library.\n *\n\n * @implements {Parser}\n * @implements {Stringifier}\n * @final\n */\nexports = class {\n /**\n * @param {?Replacer=} opt_replacer An optional replacer to use during\n * serialization.\n * @param {?=} opt_reviver An optional reviver to use during\n * parsing.\n */\n constructor(opt_replacer, opt_reviver) {\n asserts.assert(goog.global['JSON'] !== undefined, 'JSON not defined');\n\n /**\n * @type {!Replacer|null|undefined}\n * @private\n */\n this.replacer_ = opt_replacer;\n\n /**\n * @type {!Reviver|null|undefined}\n * @private\n */\n this.reviver_ = opt_reviver;\n };\n\n /**\n * Serializes an object or a value to a string.\n * Agnostic to the particular format of object and string.\n *\n * @param {*} object The object to stringify.\n * @return {string} A string representation of the input.\n * @override\n */\n stringify(object) {\n return goog.global['JSON'].stringify(object, this.replacer_);\n }\n\n /**\n * Parses a string into an object and returns the result.\n * Agnostic to the format of string and object.\n *\n * @param {string} s The string to parse.\n * @return {*} The object generated from the string.\n * @override\n */\n parse(s) {\n return goog.global['JSON'].parse(s, this.reviver_);\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utility functions for managing networking, such as\n * testing network connectivity.\n *\n */\n\n\ngoog.provide('goog.labs.net.webChannel.netUtils');\n\ngoog.require('goog.Uri');\ngoog.require('goog.labs.net.webChannel.WebChannelDebug');\n\ngoog.scope(function() {\n'use strict';\nconst netUtils = goog.labs.net.webChannel.netUtils;\nconst WebChannelDebug = goog.labs.net.webChannel.WebChannelDebug;\n\n\n/**\n * Default timeout to allow for URI pings.\n * @type {number}\n */\nnetUtils.NETWORK_TIMEOUT = 10000;\n\n\n/**\n * Pings the network with an image URI to check if an error is a server error\n * or user's network error.\n *\n * The caller needs to add a 'rand' parameter to make sure the response is\n * not fulfilled by browser cache.\n *\n * @param {function(boolean)} callback The function to call back with results.\n * @param {goog.Uri=} opt_imageUri The URI (of an image) to use for the network\n * test.\n */\nnetUtils.testNetwork = function(callback, opt_imageUri) {\n 'use strict';\n let uri = opt_imageUri;\n if (!uri) {\n // default google.com image\n uri = new goog.Uri('//www.google.com/images/cleardot.gif');\n\n if (!(goog.global.location && goog.global.location.protocol == 'http')) {\n uri.setScheme('https'); // e.g. chrome-extension\n }\n uri.makeUnique();\n }\n\n netUtils.testLoadImage(uri.toString(), netUtils.NETWORK_TIMEOUT, callback);\n};\n\n\n/**\n * Test loading the given image, retrying if necessary.\n * @param {string} url URL to the image.\n * @param {number} timeout Milliseconds before giving up.\n * @param {function(boolean)} callback Function to call with results.\n * @param {number} retries The number of times to retry.\n * @param {!WebChannelDebug} channelDebug The debug object\n * @param {number=} opt_pauseBetweenRetriesMS Optional number of milliseconds\n * between retries - defaults to 0.\n */\nnetUtils.testLoadImageWithRetries = function(\n url, timeout, callback, retries, channelDebug, opt_pauseBetweenRetriesMS) {\n 'use strict';\n channelDebug.debug('TestLoadImageWithRetries: ' + opt_pauseBetweenRetriesMS);\n if (retries == 0) {\n // no more retries, give up\n callback(false);\n return;\n }\n\n const pauseBetweenRetries = opt_pauseBetweenRetriesMS || 0;\n retries--;\n netUtils.testLoadImage(url, timeout, function(succeeded) {\n 'use strict';\n if (succeeded) {\n callback(true);\n } else {\n // try again\n goog.global.setTimeout(function() {\n 'use strict';\n netUtils.testLoadImageWithRetries(\n url, timeout, callback, retries, channelDebug, pauseBetweenRetries);\n }, pauseBetweenRetries);\n }\n });\n};\n\n\n/**\n * Test loading the given image.\n * @param {string} url URL to the image.\n * @param {number} timeout Milliseconds before giving up.\n * @param {function(boolean)} callback Function to call with results.\n * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration\n */\nnetUtils.testLoadImage = function(url, timeout, callback) {\n 'use strict';\n const channelDebug = new WebChannelDebug();\n channelDebug.debug('TestLoadImage: loading ' + url);\n if (goog.global.Image) {\n const img = new Image();\n img.onload = goog.partial(\n netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: loaded',\n true, callback);\n img.onerror = goog.partial(\n netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: error',\n false, callback);\n img.onabort = goog.partial(\n netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: abort',\n false, callback);\n img.ontimeout = goog.partial(\n netUtils.imageCallback_, channelDebug, img, 'TestLoadImage: timeout',\n false, callback);\n\n goog.global.setTimeout(function() {\n 'use strict';\n if (img.ontimeout) {\n img.ontimeout();\n }\n }, timeout);\n img.src = url;\n } else {\n // log ERROR_OTHER from environements where Image is not supported\n callback(false);\n }\n};\n\n\n/**\n * Wrap the image callback with debug and cleanup logic.\n * @param {!WebChannelDebug} channelDebug The WebChannelDebug object.\n * @param {!Image} img The image element.\n * @param {string} debugText The debug text.\n * @param {boolean} result The result of image loading.\n * @param {function(boolean)} callback The image callback.\n * @private\n */\nnetUtils.imageCallback_ = function(\n channelDebug, img, debugText, result, callback) {\n 'use strict';\n try {\n channelDebug.debug(debugText);\n netUtils.clearImageCallbacks_(img);\n callback(result);\n } catch (e) {\n channelDebug.dumpException(e);\n }\n};\n\n\n/**\n * Clears handlers to avoid memory leaks.\n * @param {Image} img The image to clear handlers from.\n * @private\n * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration\n */\nnetUtils.clearImageCallbacks_ = function(img) {\n 'use strict';\n img.onload = null;\n img.onerror = null;\n img.onabort = null;\n img.ontimeout = null;\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.net.FetchXmlHttp');\ngoog.provide('goog.net.FetchXmlHttpFactory');\n\ngoog.require('goog.asserts');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.functions');\ngoog.require('goog.log');\ngoog.require('goog.net.XhrLike');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n\n/**\n * @record\n */\ngoog.net.FetchXmlHttpFactoryOptions = function() {\n /**\n * @type {!WorkerGlobalScope|undefined} The Service Worker global scope.\n */\n this.worker;\n\n /**\n * @type {boolean|undefined} Whether to store the FetchXmlHttp response as an\n * array of Uint8Arrays. If this is true then the 'responseType' attribute\n * must be empty.\n */\n this.streamBinaryChunks;\n};\n\n\n\n/**\n * Factory for creating Xhr objects that uses the native fetch() method.\n * https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\n * @param {!goog.net.FetchXmlHttpFactoryOptions} opts\n * @extends {goog.net.XmlHttpFactory}\n * @struct\n * @constructor\n */\ngoog.net.FetchXmlHttpFactory = function(opts) {\n 'use strict';\n goog.net.FetchXmlHttpFactory.base(this, 'constructor');\n\n /** @private @final {?WorkerGlobalScope} */\n this.worker_ = opts.worker || null;\n\n /** @private @final {boolean} */\n this.streamBinaryChunks_ = opts.streamBinaryChunks || false;\n\n /** @private {!RequestCredentials|undefined} */\n this.credentialsMode_ = undefined;\n\n /** @private {!RequestCache|undefined} */\n this.cacheMode_ = undefined;\n};\ngoog.inherits(goog.net.FetchXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.FetchXmlHttpFactory.prototype.createInstance = function() {\n 'use strict';\n const instance =\n new goog.net.FetchXmlHttp(this.worker_, this.streamBinaryChunks_);\n if (this.credentialsMode_) {\n instance.setCredentialsMode(this.credentialsMode_);\n }\n if (this.cacheMode_) {\n instance.setCacheMode(this.cacheMode_);\n }\n return instance;\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttpFactory.prototype.internalGetOptions =\n goog.functions.constant({});\n\n\n/**\n * @param {!RequestCredentials} credentialsMode The credentials mode of the\n * Service Worker fetch.\n */\ngoog.net.FetchXmlHttpFactory.prototype.setCredentialsMode = function(\n credentialsMode) {\n 'use strict';\n this.credentialsMode_ = credentialsMode;\n};\n\n\n/**\n * @param {!RequestCache} cacheMode The cache mode of the Service Worker fetch.\n */\ngoog.net.FetchXmlHttpFactory.prototype.setCacheMode = function(cacheMode) {\n 'use strict';\n this.cacheMode_ = cacheMode;\n};\n\n\n\n/**\n * FetchXmlHttp object constructor.\n * @param {?WorkerGlobalScope} worker\n * @param {boolean} streamBinaryChunks\n * @extends {goog.events.EventTarget}\n * @implements {goog.net.XhrLike}\n * @constructor\n * @struct\n */\ngoog.net.FetchXmlHttp = function(worker, streamBinaryChunks) {\n 'use strict';\n goog.net.FetchXmlHttp.base(this, 'constructor');\n\n /** @private @final {?WorkerGlobalScope} */\n this.worker_ = worker;\n\n /** @private @final {boolean} */\n this.streamBinaryChunks_ = streamBinaryChunks;\n\n /** @private {RequestCredentials|undefined} */\n this.credentialsMode_ = undefined;\n\n /** @private {RequestCache|undefined} */\n this.cacheMode_ = undefined;\n\n /**\n * Request state.\n * @type {goog.net.FetchXmlHttp.RequestState}\n */\n this.readyState = goog.net.FetchXmlHttp.RequestState.UNSENT;\n\n /**\n * HTTP status.\n * @type {number}\n */\n this.status = 0;\n\n /**\n * HTTP status string.\n * @type {string}\n */\n this.statusText = '';\n\n /**\n * Content of the response.\n * @type {string|!ArrayBuffer|!Array<!Uint8Array>}\n */\n this.response = '';\n\n /**\n * Content of the response.\n * @type {string}\n */\n this.responseText = '';\n\n /**\n * The type of the response. If this is set to 'arraybuffer' the request will\n * be discrete, streaming is only supported for text encoded requests.\n * @type {string}\n */\n this.responseType = '';\n\n /**\n * Document response entity body.\n * NOTE: This is always null and not supported by this class.\n * @final {null}\n */\n this.responseXML = null;\n\n /**\n * Method to call when the state changes.\n * @type {?function()}\n */\n this.onreadystatechange = null;\n\n /** @private {!Headers} */\n this.requestHeaders_ = new Headers();\n\n /** @private {?Headers} */\n this.responseHeaders_ = null;\n\n /**\n * Request method (GET or POST).\n * @private {string}\n */\n this.method_ = 'GET';\n\n /**\n * Request URL.\n * @private {string}\n */\n this.url_ = '';\n\n /**\n * Whether the request is in progress.\n * @private {boolean}\n */\n this.inProgress_ = false;\n\n /** @private @final {?goog.log.Logger} */\n this.logger_ = goog.log.getLogger('goog.net.FetchXmlHttp');\n\n /** @private {?Response} */\n this.fetchResponse_ = null;\n\n /** @private {!ReadableStreamDefaultReader|null} */\n this.currentReader_ = null;\n\n /** @private {?TextDecoder} */\n this.textDecoder_ = null;\n};\ngoog.inherits(goog.net.FetchXmlHttp, goog.events.EventTarget);\n\n\n/**\n * State of the requests.\n * @enum {number}\n */\ngoog.net.FetchXmlHttp.RequestState = {\n UNSENT: 0,\n OPENED: 1,\n HEADER_RECEIVED: 2,\n LOADING: 3,\n DONE: 4,\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.open = function(method, url, opt_async) {\n 'use strict';\n goog.asserts.assert(!!opt_async, 'Only async requests are supported.');\n if (this.readyState != goog.net.FetchXmlHttp.RequestState.UNSENT) {\n this.abort();\n throw new Error('Error reopening a connection');\n }\n\n this.method_ = method;\n this.url_ = url;\n\n this.readyState = goog.net.FetchXmlHttp.RequestState.OPENED;\n this.dispatchCallback_();\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.send = function(opt_data) {\n 'use strict';\n if (this.readyState != goog.net.FetchXmlHttp.RequestState.OPENED) {\n this.abort();\n throw new Error('need to call open() first. ');\n }\n\n this.inProgress_ = true;\n const requestInit = {\n headers: this.requestHeaders_,\n method: this.method_,\n credentials: this.credentialsMode_,\n cache: this.cacheMode_,\n };\n if (opt_data) {\n requestInit['body'] = opt_data;\n }\n\n (this.worker_ || goog.global)\n .fetch(new Request(this.url_, /** @type {!RequestInit} */ (requestInit)))\n .then(\n this.handleResponse_.bind(this), this.handleSendFailure_.bind(this));\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.abort = function() {\n 'use strict';\n this.response = this.responseText = '';\n this.requestHeaders_ = new Headers();\n this.status = 0;\n\n if (!!this.currentReader_) {\n this.currentReader_.cancel('Request was aborted.')\n .catch(\n e => goog.log.warning(\n this.logger_, 'Fetch reader cancellation error.', e));\n }\n\n if (((this.readyState >= goog.net.FetchXmlHttp.RequestState.OPENED) &&\n this.inProgress_) &&\n (this.readyState != goog.net.FetchXmlHttp.RequestState.DONE)) {\n this.inProgress_ = false;\n this.requestDone_();\n }\n\n this.readyState = goog.net.FetchXmlHttp.RequestState.UNSENT;\n};\n\n\n/**\n * Handles the fetch response.\n * @param {!Response} response\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponse_ = function(response) {\n 'use strict';\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n\n this.fetchResponse_ = response;\n\n if (!this.responseHeaders_) {\n this.status = this.fetchResponse_.status;\n this.statusText = this.fetchResponse_.statusText;\n this.responseHeaders_ = response.headers;\n this.readyState = goog.net.FetchXmlHttp.RequestState.HEADER_RECEIVED;\n this.dispatchCallback_();\n }\n // A callback may abort the request.\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n\n this.readyState = goog.net.FetchXmlHttp.RequestState.LOADING;\n this.dispatchCallback_();\n // A callback may abort the request.\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n\n if (this.responseType === 'arraybuffer') {\n response.arrayBuffer().then(\n this.handleResponseArrayBuffer_.bind(this),\n this.handleSendFailure_.bind(this));\n } else if (\n typeof (goog.global.ReadableStream) !== 'undefined' &&\n 'body' in response) {\n this.currentReader_ =\n /** @type {!ReadableStreamDefaultReader} */ (response.body.getReader());\n if (this.streamBinaryChunks_) {\n if (this.responseType) {\n throw new Error(\n 'responseType must be empty for \"streamBinaryChunks\" mode responses.');\n }\n this.response = [];\n } else {\n this.response = this.responseText = '';\n this.textDecoder_ = new TextDecoder();\n }\n this.readInputFromFetch_();\n } else {\n response.text().then(\n this.handleResponseText_.bind(this),\n this.handleSendFailure_.bind(this));\n }\n};\n\n\n/**\n * Reads the next chunk of data from the fetch response.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.readInputFromFetch_ = function() {\n 'use strict';\n this.currentReader_.read()\n .then(this.handleDataFromStream_.bind(this))\n .catch(this.handleSendFailure_.bind(this));\n};\n\n\n/**\n * Handles a chunk of data from the fetch response stream reader.\n * @param {!IIterableResult} result\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleDataFromStream_ = function(result) {\n 'use strict';\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n\n if (this.streamBinaryChunks_ && result.value) {\n // When streamBinaryChunks_ is enabled, \"response\" is an array\n /** @type {!Array} */ (this.response)\n .push(/** @type {!Uint8Array} */ (result.value));\n } else if (!this.streamBinaryChunks_) {\n const dataPacket = result.value ?\n /** @type {!Uint8Array} */ (result.value) :\n new Uint8Array(0);\n const newText =\n this.textDecoder_.decode(dataPacket, {stream: !result.done});\n if (newText) {\n this.responseText += newText;\n this.response = this.responseText;\n }\n }\n if (result.done) {\n this.requestDone_();\n } else {\n this.dispatchCallback_();\n }\n\n if (this.readyState == goog.net.FetchXmlHttp.RequestState.LOADING) {\n this.readInputFromFetch_();\n }\n};\n\n/**\n * Handles the response text.\n * @param {string} responseText\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponseText_ = function(responseText) {\n 'use strict';\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n this.response = this.responseText = responseText;\n this.requestDone_();\n};\n\n\n/**\n * Handles the response text.\n * @param {!ArrayBuffer} responseArrayBuffer\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponseArrayBuffer_ = function(\n responseArrayBuffer) {\n 'use strict';\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n this.response = responseArrayBuffer;\n this.requestDone_();\n};\n\n\n/**\n * Handles the send failure.\n * @param {*} error\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleSendFailure_ = function(error) {\n 'use strict';\n const e = error instanceof Error ? error : Error(error);\n goog.log.warning(this.logger_, 'Failed to fetch url ' + this.url_, e);\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n this.requestDone_();\n};\n\n\n/**\n * Sets the request state to DONE and performs cleanup.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.requestDone_ = function() {\n 'use strict';\n this.readyState = goog.net.FetchXmlHttp.RequestState.DONE;\n\n this.fetchResponse_ = null;\n this.currentReader_ = null;\n this.textDecoder_ = null;\n\n this.dispatchCallback_();\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.setRequestHeader = function(header, value) {\n 'use strict';\n this.requestHeaders_.append(header, value);\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.getResponseHeader = function(header) {\n 'use strict';\n // TODO(user): This method should return null when the headers are not\n // present or the specified header is missing. The externs need to be fixed.\n if (!this.responseHeaders_) {\n goog.log.warning(\n this.logger_,\n 'Attempting to get response header but no headers have been received ' +\n 'for url: ' + this.url_);\n return '';\n }\n return this.responseHeaders_.get(header.toLowerCase()) || '';\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.getAllResponseHeaders = function() {\n 'use strict';\n if (!this.responseHeaders_) {\n goog.log.warning(\n this.logger_,\n 'Attempting to get all response headers but no headers have been ' +\n 'received for url: ' + this.url_);\n return '';\n }\n const lines = [];\n const iter = this.responseHeaders_.entries();\n let entry = iter.next();\n while (!entry.done) {\n const pair = entry.value;\n lines.push(pair[0] + ': ' + pair[1]);\n entry = iter.next();\n }\n return lines.join('\\r\\n');\n};\n\n\n/**\n * @param {!RequestCredentials} credentialsMode The credentials mode of the\n * Service Worker fetch.\n */\ngoog.net.FetchXmlHttp.prototype.setCredentialsMode = function(credentialsMode) {\n 'use strict';\n this.credentialsMode_ = credentialsMode;\n};\n\n/**\n * @return {!RequestCredentials|undefined} The credentials mode of the\n * Service Worker fetch.\n */\ngoog.net.FetchXmlHttp.prototype.getCredentialsMode = function() {\n 'use strict';\n return this.credentialsMode_;\n};\n\n/**\n * @param {!RequestCache} cacheMode The cache mode of the Service Worker fetch.\n */\ngoog.net.FetchXmlHttp.prototype.setCacheMode = function(cacheMode) {\n 'use strict';\n this.cacheMode_ = cacheMode;\n};\n\n\n/**\n * Dispatches the callback, if the callback attribute is defined.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.dispatchCallback_ = function() {\n 'use strict';\n if (this.onreadystatechange) {\n this.onreadystatechange.call(this);\n }\n};\n\n// Polyfill XmlHttpRequest's withCredentials property for specifying whether to\n// include credentials on cross domain requests.\nObject.defineProperty(goog.net.FetchXmlHttp.prototype, 'withCredentials', {\n get:\n /**\n * @this {goog.net.FetchXmlHttp}\n * @return {boolean} Whether to include credentials in cross domain\n * requests.\n */\n function() {\n 'use strict';\n return this.getCredentialsMode() === 'include';\n },\n\n set:\n /**\n * @param {boolean} value Whether to include credentials in cross domain\n * requests.\n * @this {goog.net.FetchXmlHttp}\n **/\n function(value) {\n 'use strict';\n this.setCredentialsMode(value ? 'include' : 'same-origin');\n }\n});\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for creating functions. Loosely inspired by these\n * java classes from the Guava library:\n * com.google.common.base.Functions\n * https://google.github.io/guava/releases/snapshot-jre/api/docs/index.html?com/google/common/base/Functions.html\n *\n * com.google.common.base.Predicates\n * https://google.github.io/guava/releases/snapshot-jre/api/docs/index.html?com/google/common/base/Predicates.html\n *\n * More about these can be found at\n * https://github.com/google/guava/wiki/FunctionalExplained\n */\n\n\ngoog.provide('goog.functions');\n\n\n/**\n * Creates a function that always returns the same value.\n * @param {T} retValue The value to return.\n * @return {function():T} The new function.\n * @template T\n */\ngoog.functions.constant = function(retValue) {\n 'use strict';\n return function() {\n 'use strict';\n return retValue;\n };\n};\n\n\n/**\n * Always returns false.\n * @type {function(...): boolean}\n */\ngoog.functions.FALSE = function() {\n 'use strict';\n return false;\n};\n\n\n/**\n * Always returns true.\n * @type {function(...): boolean}\n */\ngoog.functions.TRUE = function() {\n 'use strict';\n return true;\n};\n\n\n/**\n * Always returns `null`.\n * @type {function(...): null}\n */\ngoog.functions.NULL = function() {\n 'use strict';\n return null;\n};\n\n\n/**\n * Always returns `undefined`.\n * @type {function(...): undefined}\n */\ngoog.functions.UNDEFINED = function() {\n return undefined;\n};\n\n/**\n * Always returns `undefined` (loosely-typed version).\n * @type {!Function}\n */\ngoog.functions.EMPTY = /** @type {?} */ (goog.functions.UNDEFINED);\n\n\n/**\n * A simple function that returns the first argument of whatever is passed\n * into it.\n * @param {T=} opt_returnValue The single value that will be returned.\n * @param {...*} var_args Optional trailing arguments. These are ignored.\n * @return {T} The first argument passed in, or undefined if nothing was passed.\n * @template T\n */\ngoog.functions.identity = function(opt_returnValue, var_args) {\n 'use strict';\n return opt_returnValue;\n};\n\n\n/**\n * Creates a function that always throws an error with the given message.\n * @param {string} message The error message.\n * @return {!Function} The error-throwing function.\n */\ngoog.functions.error = function(message) {\n 'use strict';\n return function() {\n 'use strict';\n throw new Error(message);\n };\n};\n\n\n/**\n * Creates a function that throws the given object.\n * @param {*} err An object to be thrown.\n * @return {!Function} The error-throwing function.\n */\ngoog.functions.fail = function(err) {\n 'use strict';\n return function() {\n 'use strict';\n throw err;\n };\n};\n\n\n/**\n * Given a function, create a function that keeps opt_numArgs arguments and\n * silently discards all additional arguments.\n * @param {Function} f The original function.\n * @param {number=} opt_numArgs The number of arguments to keep. Defaults to 0.\n * @return {!Function} A version of f that only keeps the first opt_numArgs\n * arguments.\n */\ngoog.functions.lock = function(f, opt_numArgs) {\n 'use strict';\n opt_numArgs = opt_numArgs || 0;\n return function() {\n 'use strict';\n const self = /** @type {*} */ (this);\n return f.apply(self, Array.prototype.slice.call(arguments, 0, opt_numArgs));\n };\n};\n\n\n/**\n * Creates a function that returns its nth argument.\n * @param {number} n The position of the return argument.\n * @return {!Function} A new function.\n */\ngoog.functions.nth = function(n) {\n 'use strict';\n return function() {\n 'use strict';\n return arguments[n];\n };\n};\n\n\n/**\n * Like goog.partial(), except that arguments are added after arguments to the\n * returned function.\n *\n * Usage:\n * function f(arg1, arg2, arg3, arg4) { ... }\n * var g = goog.functions.partialRight(f, arg3, arg4);\n * g(arg1, arg2);\n *\n * @param {!Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn\n * at the end.\n * @return {!Function} A partially-applied form of the function goog.partial()\n * was invoked as a method of.\n */\ngoog.functions.partialRight = function(fn, var_args) {\n 'use strict';\n const rightArgs = Array.prototype.slice.call(arguments, 1);\n return function() {\n 'use strict';\n // Even in strict mode, IE10/11 and Edge (non-Chromium) use global context\n // when free-calling functions. To catch cases where people were using this\n // erroneously, we explicitly change the context to undefined to match\n // strict mode specifications.\n let self = /** @type {*} */ (this);\n if (self === goog.global) {\n self = undefined;\n }\n const newArgs = Array.prototype.slice.call(arguments);\n newArgs.push.apply(newArgs, rightArgs);\n return fn.apply(self, newArgs);\n };\n};\n\n\n/**\n * Given a function, create a new function that swallows its return value\n * and replaces it with a new one.\n * @param {Function} f A function.\n * @param {T} retValue A new return value.\n * @return {function(...?):T} A new function.\n * @template T\n */\ngoog.functions.withReturnValue = function(f, retValue) {\n 'use strict';\n return goog.functions.sequence(f, goog.functions.constant(retValue));\n};\n\n\n/**\n * Creates a function that returns whether its argument equals the given value.\n *\n * Example:\n * var key = goog.object.findKey(obj, goog.functions.equalTo('needle'));\n *\n * @param {*} value The value to compare to.\n * @param {boolean=} opt_useLooseComparison Whether to use a loose (==)\n * comparison rather than a strict (===) one. Defaults to false.\n * @return {function(*):boolean} The new function.\n */\ngoog.functions.equalTo = function(value, opt_useLooseComparison) {\n 'use strict';\n return function(other) {\n 'use strict';\n return opt_useLooseComparison ? (value == other) : (value === other);\n };\n};\n\n\n/**\n * Creates the composition of the functions passed in.\n * For example, (goog.functions.compose(f, g))(a) is equivalent to f(g(a)).\n * @param {function(...?):T} fn The final function.\n * @param {...Function} var_args A list of functions.\n * @return {function(...?):T} The composition of all inputs.\n * @template T\n */\ngoog.functions.compose = function(fn, var_args) {\n 'use strict';\n const functions = arguments;\n const length = functions.length;\n return function() {\n 'use strict';\n const self = /** @type {*} */ (this);\n let result;\n if (length) {\n result = functions[length - 1].apply(self, arguments);\n }\n\n for (let i = length - 2; i >= 0; i--) {\n result = functions[i].call(self, result);\n }\n return result;\n };\n};\n\n\n/**\n * Creates a function that calls the functions passed in in sequence, and\n * returns the value of the last function. For example,\n * (goog.functions.sequence(f, g))(x) is equivalent to f(x),g(x).\n * @param {...Function} var_args A list of functions.\n * @return {!Function} A function that calls all inputs in sequence.\n */\ngoog.functions.sequence = function(var_args) {\n 'use strict';\n const functions = arguments;\n const length = functions.length;\n return function() {\n 'use strict';\n const self = /** @type {*} */ (this);\n let result;\n for (let i = 0; i < length; i++) {\n result = functions[i].apply(self, arguments);\n }\n return result;\n };\n};\n\n\n/**\n * Creates a function that returns true if each of its components evaluates\n * to true. The components are evaluated in order, and the evaluation will be\n * short-circuited as soon as a function returns false.\n * For example, (goog.functions.and(f, g))(x) is equivalent to f(x) && g(x).\n * @param {...Function} var_args A list of functions.\n * @return {function(...?):boolean} A function that ANDs its component\n * functions.\n */\ngoog.functions.and = function(var_args) {\n 'use strict';\n const functions = arguments;\n const length = functions.length;\n return function() {\n 'use strict';\n const self = /** @type {*} */ (this);\n for (let i = 0; i < length; i++) {\n if (!functions[i].apply(self, arguments)) {\n return false;\n }\n }\n return true;\n };\n};\n\n\n/**\n * Creates a function that returns true if any of its components evaluates\n * to true. The components are evaluated in order, and the evaluation will be\n * short-circuited as soon as a function returns true.\n * For example, (goog.functions.or(f, g))(x) is equivalent to f(x) || g(x).\n * @param {...Function} var_args A list of functions.\n * @return {function(...?):boolean} A function that ORs its component\n * functions.\n */\ngoog.functions.or = function(var_args) {\n 'use strict';\n const functions = arguments;\n const length = functions.length;\n return function() {\n 'use strict';\n const self = /** @type {*} */ (this);\n for (let i = 0; i < length; i++) {\n if (functions[i].apply(self, arguments)) {\n return true;\n }\n }\n return false;\n };\n};\n\n\n/**\n * Creates a function that returns the Boolean opposite of a provided function.\n * For example, (goog.functions.not(f))(x) is equivalent to !f(x).\n * @param {!Function} f The original function.\n * @return {function(...?):boolean} A function that delegates to f and returns\n * opposite.\n */\ngoog.functions.not = function(f) {\n 'use strict';\n return function() {\n 'use strict';\n const self = /** @type {*} */ (this);\n return !f.apply(self, arguments);\n };\n};\n\n\n/**\n * Generic factory function to construct an object given the constructor\n * and the arguments. Intended to be bound to create object factories.\n *\n * Example:\n *\n * var factory = goog.partial(goog.functions.create, Class);\n *\n * @param {function(new:T, ...)} constructor The constructor for the Object.\n * @param {...*} var_args The arguments to be passed to the constructor.\n * @return {T} A new instance of the class given in `constructor`.\n * @template T\n * @deprecated This function does not work with ES6 class constructors. Use\n * arrow functions + spread args instead.\n */\ngoog.functions.create = function(constructor, var_args) {\n 'use strict';\n /**\n * @constructor\n * @final\n */\n const temp = function() {};\n temp.prototype = constructor.prototype;\n\n // obj will have constructor's prototype in its chain and\n // 'obj instanceof constructor' will be true.\n const obj = new temp();\n\n // obj is initialized by constructor.\n // arguments is only array-like so lacks shift(), but can be used with\n // the Array prototype function.\n constructor.apply(obj, Array.prototype.slice.call(arguments, 1));\n return obj;\n};\n\n\n/**\n * @define {boolean} Whether the return value cache should be used.\n * This should only be used to disable caches when testing.\n */\ngoog.functions.CACHE_RETURN_VALUE =\n goog.define('goog.functions.CACHE_RETURN_VALUE', true);\n\n\n/**\n * Gives a wrapper function that caches the return value of a parameterless\n * function when first called.\n *\n * When called for the first time, the given function is called and its\n * return value is cached (thus this is only appropriate for idempotent\n * functions). Subsequent calls will return the cached return value. This\n * allows the evaluation of expensive functions to be delayed until first used.\n *\n * To cache the return values of functions with parameters, see goog.memoize.\n *\n * @param {function():T} fn A function to lazily evaluate.\n * @return {function():T} A wrapped version the function.\n * @template T\n */\ngoog.functions.cacheReturnValue = function(fn) {\n 'use strict';\n let called = false;\n let value;\n\n return function() {\n 'use strict';\n if (!goog.functions.CACHE_RETURN_VALUE) {\n return fn();\n }\n\n if (!called) {\n value = fn();\n called = true;\n }\n\n return value;\n };\n};\n\n\n/**\n * Wraps a function to allow it to be called, at most, once. All\n * additional calls are no-ops.\n *\n * This is particularly useful for initialization functions\n * that should be called, at most, once.\n *\n * @param {function():*} f Function to call.\n * @return {function():undefined} Wrapped function.\n */\ngoog.functions.once = function(f) {\n 'use strict';\n // Keep a reference to the function that we null out when we're done with\n // it -- that way, the function can be GC'd when we're done with it.\n let inner = f;\n return function() {\n 'use strict';\n if (inner) {\n const tmp = inner;\n inner = null;\n tmp();\n }\n };\n};\n\n\n/**\n * Wraps a function to allow it to be called, at most, once per interval\n * (specified in milliseconds). If the wrapper function is called N times within\n * that interval, only the Nth call will go through.\n *\n * This is particularly useful for batching up repeated actions where the\n * last action should win. This can be used, for example, for refreshing an\n * autocomplete pop-up every so often rather than updating with every keystroke,\n * since the final text typed by the user is the one that should produce the\n * final autocomplete results. For more stateful debouncing with support for\n * pausing, resuming, and canceling debounced actions, use\n * `goog.async.Debouncer`.\n *\n * @param {function(this:SCOPE, ...?)} f Function to call.\n * @param {number} interval Interval over which to debounce. The function will\n * only be called after the full interval has elapsed since the last call.\n * @param {SCOPE=} opt_scope Object in whose scope to call the function.\n * @return {function(...?): undefined} Wrapped function.\n * @template SCOPE\n */\ngoog.functions.debounce = function(f, interval, opt_scope) {\n 'use strict';\n let timeout = 0;\n return /** @type {function(...?)} */ (function(var_args) {\n 'use strict';\n goog.global.clearTimeout(timeout);\n const args = arguments;\n timeout = goog.global.setTimeout(function() {\n 'use strict';\n f.apply(opt_scope, args);\n }, interval);\n });\n};\n\n\n/**\n * Wraps a function to allow it to be called, at most, once per interval\n * (specified in milliseconds). If the wrapper function is called N times in\n * that interval, both the 1st and the Nth calls will go through.\n *\n * This is particularly useful for limiting repeated user requests where the\n * the last action should win, but you also don't want to wait until the end of\n * the interval before sending a request out, as it leads to a perception of\n * slowness for the user.\n *\n * @param {function(this:SCOPE, ...?)} f Function to call.\n * @param {number} interval Interval over which to throttle. The function can\n * only be called once per interval.\n * @param {SCOPE=} opt_scope Object in whose scope to call the function.\n * @return {function(...?): undefined} Wrapped function.\n * @template SCOPE\n */\ngoog.functions.throttle = function(f, interval, opt_scope) {\n 'use strict';\n let timeout = 0;\n let shouldFire = false;\n let storedArgs = [];\n\n const handleTimeout = function() {\n 'use strict';\n timeout = 0;\n if (shouldFire) {\n shouldFire = false;\n fire();\n }\n };\n\n const fire = function() {\n 'use strict';\n timeout = goog.global.setTimeout(handleTimeout, interval);\n let args = storedArgs;\n storedArgs = []; // Avoid a space leak by clearing stored arguments.\n f.apply(opt_scope, args);\n };\n\n return /** @type {function(...?)} */ (function(var_args) {\n 'use strict';\n storedArgs = arguments;\n if (!timeout) {\n fire();\n } else {\n shouldFire = true;\n }\n });\n};\n\n\n/**\n * Wraps a function to allow it to be called, at most, once per interval\n * (specified in milliseconds). If the wrapper function is called N times within\n * that interval, only the 1st call will go through.\n *\n * This is particularly useful for limiting repeated user requests where the\n * first request is guaranteed to have all the data required to perform the\n * final action, so there's no need to wait until the end of the interval before\n * sending the request out.\n *\n * @param {function(this:SCOPE, ...?)} f Function to call.\n * @param {number} interval Interval over which to rate-limit. The function will\n * only be called once per interval, and ignored for the remainer of the\n * interval.\n * @param {SCOPE=} opt_scope Object in whose scope to call the function.\n * @return {function(...?): undefined} Wrapped function.\n * @template SCOPE\n */\ngoog.functions.rateLimit = function(f, interval, opt_scope) {\n 'use strict';\n let timeout = 0;\n\n const handleTimeout = function() {\n 'use strict';\n timeout = 0;\n };\n\n return /** @type {function(...?)} */ (function(var_args) {\n 'use strict';\n if (!timeout) {\n timeout = goog.global.setTimeout(handleTimeout, interval);\n f.apply(opt_scope, arguments);\n }\n });\n};\n\n/**\n * Returns true if the specified value is a function.\n * @param {*} val Variable to test.\n * @return {boolean} Whether variable is a function.\n */\ngoog.functions.isFunction = (val) => {\n return typeof val === 'function';\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Utility to attempt native JSON processing, falling back to\n * goog.json if not available.\n *\n * This is intended as a drop-in for current users of goog.json who want\n * to take advantage of native JSON if present.\n */\n\ngoog.provide('goog.json.hybrid');\n\ngoog.require('goog.asserts');\ngoog.require('goog.json');\n\n\n/**\n * Attempts to serialize the JSON string natively, falling back to\n * `goog.json.serialize` if unsuccessful.\n * @param {!Object} obj JavaScript object to serialize to JSON.\n * @return {string} Resulting JSON string.\n */\ngoog.json.hybrid.stringify = goog.json.USE_NATIVE_JSON ?\n goog.global['JSON']['stringify'] :\n function(obj) {\n 'use strict';\n if (goog.global.JSON) {\n try {\n return goog.global.JSON.stringify(obj);\n } catch (e) {\n // Native serialization failed. Fall through to retry with\n // goog.json.serialize.\n }\n }\n\n return goog.json.serialize(obj);\n };\n\n\n/**\n * Attempts to parse the JSON string natively, falling back to\n * the supplied `fallbackParser` if unsuccessful.\n * @param {string} jsonString JSON string to parse.\n * @param {function(string):Object} fallbackParser Fallback JSON parser used\n * if native\n * @return {?Object} Resulting JSON object.\n * @private\n */\ngoog.json.hybrid.parse_ = function(jsonString, fallbackParser) {\n 'use strict';\n if (goog.global.JSON) {\n try {\n var obj = goog.global.JSON.parse(jsonString);\n goog.asserts.assert(typeof obj == 'object');\n return /** @type {?Object} */ (obj);\n } catch (e) {\n // Native parse failed. Fall through to retry with goog.json.parse.\n }\n }\n\n return fallbackParser(jsonString);\n};\n\n\n/**\n * Attempts to parse the JSON string natively, falling back to\n * `goog.json.parse` if unsuccessful.\n * @param {string} jsonString JSON string to parse.\n * @return {?Object} Resulting JSON object.\n */\ngoog.json.hybrid.parse = goog.json.USE_NATIVE_JSON ?\n goog.global['JSON']['parse'] :\n function(jsonString) {\n 'use strict';\n return goog.json.hybrid.parse_(jsonString, goog.json.parse);\n };\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Constants for HTTP status codes.\n */\n\ngoog.provide('goog.net.HttpStatus');\n\n\n/**\n * HTTP Status Codes defined in RFC 2616, RFC 6585, RFC 4918 and RFC 7538.\n * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html\n * @see http://tools.ietf.org/html/rfc6585\n * @see https://tools.ietf.org/html/rfc4918\n * @see https://tools.ietf.org/html/rfc7538\n * @enum {number}\n */\ngoog.net.HttpStatus = {\n // Informational 1xx\n CONTINUE: 100,\n SWITCHING_PROTOCOLS: 101,\n\n // Successful 2xx\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NON_AUTHORITATIVE_INFORMATION: 203,\n NO_CONTENT: 204,\n RESET_CONTENT: 205,\n PARTIAL_CONTENT: 206,\n MULTI_STATUS: 207,\n\n // Redirection 3xx\n MULTIPLE_CHOICES: 300,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n USE_PROXY: 305,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // Client Error 4xx\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n REQUEST_ENTITY_TOO_LARGE: 413,\n REQUEST_URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n REQUEST_RANGE_NOT_SATISFIABLE: 416,\n EXPECTATION_FAILED: 417,\n UNPROCESSABLE_ENTITY: 422,\n LOCKED: 423,\n FAILED_DEPENDENCY: 424,\n PRECONDITION_REQUIRED: 428,\n TOO_MANY_REQUESTS: 429,\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n CLIENT_CLOSED_REQUEST: 499, // Nonstandard, used by GRPC\n\n // Server Error 5xx\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n INSUFFICIENT_STORAGE: 507,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n\n /*\n * IE returns this code for 204 due to its use of URLMon, which returns this\n * code for 'Operation Aborted'. The status text is 'Unknown', the response\n * headers are ''. Known to occur on IE 6 on XP through IE9 on Win7.\n */\n QUIRK_IE_NO_CONTENT: 1223,\n};\n\n\n/**\n * Returns whether the given status should be considered successful.\n *\n * Successful codes are OK (200), CREATED (201), ACCEPTED (202),\n * NO CONTENT (204), PARTIAL CONTENT (206), NOT MODIFIED (304),\n * and IE's no content code (1223).\n *\n * @param {number} status The status code to test.\n * @return {boolean} Whether the status code should be considered successful.\n */\ngoog.net.HttpStatus.isSuccess = function(status) {\n 'use strict';\n switch (status) {\n case goog.net.HttpStatus.OK:\n case goog.net.HttpStatus.CREATED:\n case goog.net.HttpStatus.ACCEPTED:\n case goog.net.HttpStatus.NO_CONTENT:\n case goog.net.HttpStatus.PARTIAL_CONTENT:\n case goog.net.HttpStatus.NOT_MODIFIED:\n case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT:\n return true;\n\n default:\n return false;\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides CORS support for HTTP based RPC requests.\n *\n * As part of net.rpc package, CORS features provided by this class\n * depend on the server support. Please check related specs to decide how\n * to enable any of the features provided by this class.\n */\n\ngoog.module('goog.net.rpc.HttpCors');\n\nconst GoogUri = goog.require('goog.Uri');\nconst googObject = goog.require('goog.object');\nconst googString = goog.require('goog.string');\nconst googUriUtils = goog.require('goog.uri.utils');\n\n\n/**\n * The default URL parameter name to overwrite http headers with a URL param\n * to avoid CORS preflight.\n *\n * See https://github.com/whatwg/fetch/issues/210#issue-129531743 for the spec.\n *\n * @type {string}\n */\nexports.HTTP_HEADERS_PARAM_NAME = '$httpHeaders';\n\n\n/**\n * The default URL parameter name to overwrite http method with a URL param\n * to avoid CORS preflight.\n *\n * See https://github.com/whatwg/fetch/issues/210#issue-129531743 for the spec.\n *\n * @type {string}\n */\nexports.HTTP_METHOD_PARAM_NAME = '$httpMethod';\n\n\n/**\n * Generates the URL parameter value with custom headers encoded as\n * HTTP/1.1 headers block.\n *\n * @param {!Object<string, string>} headers The custom headers.\n * @return {string} The URL param to overwrite custom HTTP headers.\n */\nexports.generateHttpHeadersOverwriteParam = function(headers) {\n let result = '';\n googObject.forEach(headers, function(value, key) {\n result += key;\n result += ':';\n result += value;\n result += '\\r\\n';\n });\n return result;\n};\n\n\n/**\n * Generates the URL-encoded URL parameter value with custom headers encoded as\n * HTTP/1.1 headers block.\n *\n * @param {!Object<string, string>} headers The custom headers.\n * @return {string} The URL param to overwrite custom HTTP headers.\n */\nexports.generateEncodedHttpHeadersOverwriteParam = function(headers) {\n return googString.urlEncode(\n exports.generateHttpHeadersOverwriteParam(headers));\n};\n\n\n/**\n * Sets custom HTTP headers via an overwrite URL param.\n *\n * @param {!GoogUri|string} url The URI object or a string path.\n * @param {string} urlParam The URL param name.\n * @param {!Object<string, string>} extraHeaders The HTTP headers.\n * @return {!GoogUri|string} The URI object or a string path with headers\n * encoded as a url param.\n */\nexports.setHttpHeadersWithOverwriteParam = function(\n url, urlParam, extraHeaders) {\n if (googObject.isEmpty(extraHeaders)) {\n return url;\n }\n const httpHeaders = exports.generateHttpHeadersOverwriteParam(extraHeaders);\n if (typeof url === 'string') {\n return googUriUtils.appendParam(\n url, googString.urlEncode(urlParam), httpHeaders);\n } else {\n url.setParameterValue(urlParam, httpHeaders); // duplicate removed!\n return url;\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Transport support for WebChannel.\n *\n * The <code>WebChannelTransport</code> implementation serves as the factory\n * for <code>WebChannel</code>, which offers an abstraction for\n * point-to-point socket-like communication similar to what BrowserChannel\n * or HTML5 WebSocket offers.\n */\n\ngoog.provide('goog.net.WebChannelTransport');\n\ngoog.requireType('goog.net.WebChannel');\ngoog.requireType('goog.net.WebChannel.Options');\n\n\n\n/**\n * A WebChannelTransport instance represents a shared context of logical\n * connectivity between a browser client and a remote origin.\n *\n * Over a single WebChannelTransport instance, multiple WebChannels may be\n * created against different URLs, which may all share the same\n * underlying connectivity (i.e. TCP connection) whenever possible.\n *\n * When multi-domains are supported, such as CORS, multiple origins may be\n * supported over a single WebChannelTransport instance at the same time.\n *\n * Sharing between different window contexts such as tabs is not addressed\n * by WebChannelTransport. Applications may choose HTML5 shared workers\n * or other techniques to access the same transport instance\n * across different window contexts.\n *\n * @interface\n */\ngoog.net.WebChannelTransport = function() {};\n\n\n/**\n * The client version. This integer value will be passed to the server\n * when a channel is opened to inform the server the client \"capabilities\".\n *\n * Wire protocol version is a different concept and is internal to the\n * transport implementation.\n *\n * @const\n * @type {number}\n */\ngoog.net.WebChannelTransport.CLIENT_VERSION = 22;\n\n\n/**\n * Create a new WebChannel instance.\n *\n * The new WebChannel is to be opened against the server-side resource\n * as specified by the given URL. See {@link goog.net.WebChannel} for detailed\n * semantics.\n *\n * @param {string} url The URL path for the new WebChannel instance.\n * @param {!goog.net.WebChannel.Options=} opt_options Configuration for the\n * new WebChannel instance. The configuration object is reusable after\n * the new channel instance is created.\n * @return {!goog.net.WebChannel} the newly created WebChannel instance.\n */\ngoog.net.WebChannelTransport.prototype.createWebChannel = goog.abstractMethod;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implementation of a WebChannel transport using WebChannelBase.\n *\n * When WebChannelBase is used as the underlying transport, the capabilities\n * of the WebChannel are limited to what's supported by the implementation.\n * Particularly, multiplexing is not possible, and only strings are\n * supported as message types.\n */\n\ngoog.provide('goog.labs.net.webChannel.WebChannelBaseTransport');\n\ngoog.require('goog.asserts');\ngoog.require('goog.collections.maps');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.json');\ngoog.require('goog.labs.net.webChannel.ChannelRequest');\ngoog.require('goog.labs.net.webChannel.WebChannelBase');\ngoog.require('goog.labs.net.webChannel.Wire');\ngoog.require('goog.log');\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.net.WebChannelTransport');\ngoog.require('goog.object');\ngoog.require('goog.string');\n\n\n\n/**\n * Implementation of {@link goog.net.WebChannelTransport} with\n * {@link goog.labs.net.webChannel.WebChannelBase} as the underlying channel\n * implementation.\n *\n * @constructor\n * @struct\n * @implements {goog.net.WebChannelTransport}\n * @final\n */\ngoog.labs.net.webChannel.WebChannelBaseTransport = function() {\n 'use strict';\n if (!goog.labs.net.webChannel.ChannelRequest.supportsXhrStreaming()) {\n throw new Error('Environmental error: no available transport.');\n }\n};\n\n\ngoog.scope(function() {\n'use strict';\nconst WebChannelBaseTransport =\n goog.labs.net.webChannel.WebChannelBaseTransport;\nconst WebChannelBase = goog.labs.net.webChannel.WebChannelBase;\nconst Wire = goog.labs.net.webChannel.Wire;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.prototype.createWebChannel = function(\n url, opt_options) {\n 'use strict';\n return new WebChannelBaseTransport.Channel(url, opt_options);\n};\n\n\n\n/**\n * Implementation of the {@link goog.net.WebChannel} interface.\n *\n * @param {string} url The URL path for the new WebChannel instance.\n * @param {!goog.net.WebChannel.Options=} opt_options Configuration for the\n * new WebChannel instance.\n *\n * @constructor\n * @implements {goog.net.WebChannel}\n * @extends {goog.events.EventTarget}\n * @final\n */\nWebChannelBaseTransport.Channel = function(url, opt_options) {\n 'use strict';\n WebChannelBaseTransport.Channel.base(this, 'constructor');\n\n /**\n * @private {!WebChannelBase} The underlying channel object.\n */\n this.channel_ = new WebChannelBase(\n opt_options, goog.net.WebChannelTransport.CLIENT_VERSION);\n\n /**\n * @private {string} The URL of the target server end-point.\n */\n this.url_ = url;\n\n /**\n * @private {goog.log.Logger} The logger for this class.\n */\n this.logger_ =\n goog.log.getLogger('goog.labs.net.webChannel.WebChannelBaseTransport');\n\n /**\n * @private {Object<string, string>} Extra URL parameters\n * to be added to each HTTP request.\n */\n this.messageUrlParams_ =\n (opt_options && opt_options.messageUrlParams) || null;\n\n let messageHeaders = (opt_options && opt_options.messageHeaders) || null;\n\n // default is false\n if (opt_options && opt_options.clientProtocolHeaderRequired) {\n if (messageHeaders) {\n goog.object.set(\n messageHeaders, goog.net.WebChannel.X_CLIENT_PROTOCOL,\n goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);\n } else {\n messageHeaders = goog.object.create(\n goog.net.WebChannel.X_CLIENT_PROTOCOL,\n goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);\n }\n }\n\n this.channel_.setExtraHeaders(messageHeaders);\n\n let initHeaders = (opt_options && opt_options.initMessageHeaders) || null;\n\n if (opt_options && opt_options.messageContentType) {\n if (initHeaders) {\n goog.object.set(\n initHeaders, goog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE,\n opt_options.messageContentType);\n } else {\n initHeaders = goog.object.create(\n goog.net.WebChannel.X_WEBCHANNEL_CONTENT_TYPE,\n opt_options.messageContentType);\n }\n }\n\n if (opt_options && opt_options.clientProfile) {\n if (initHeaders) {\n goog.object.set(\n initHeaders, goog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE,\n opt_options.clientProfile);\n } else {\n initHeaders = goog.object.create(\n goog.net.WebChannel.X_WEBCHANNEL_CLIENT_PROFILE,\n opt_options.clientProfile);\n }\n }\n\n this.channel_.setInitHeaders(initHeaders);\n\n const httpHeadersOverwriteParam =\n opt_options && opt_options.httpHeadersOverwriteParam;\n if (httpHeadersOverwriteParam &&\n !goog.string.isEmptyOrWhitespace(httpHeadersOverwriteParam)) {\n this.channel_.setHttpHeadersOverwriteParam(httpHeadersOverwriteParam);\n }\n\n /**\n * @private {boolean} Whether to enable CORS.\n */\n this.supportsCrossDomainXhr_ =\n (opt_options && opt_options.supportsCrossDomainXhr) || false;\n\n /**\n * @private {boolean} Whether to send raw Json and bypass v8 wire format.\n */\n this.sendRawJson_ = (opt_options && opt_options.sendRawJson) || false;\n\n // Note that httpSessionIdParam will be ignored if the same parameter name\n // has already been specified with messageUrlParams\n const httpSessionIdParam = opt_options && opt_options.httpSessionIdParam;\n if (httpSessionIdParam &&\n !goog.string.isEmptyOrWhitespace(httpSessionIdParam)) {\n this.channel_.setHttpSessionIdParam(httpSessionIdParam);\n if (goog.object.containsKey(this.messageUrlParams_, httpSessionIdParam)) {\n goog.object.remove(this.messageUrlParams_, httpSessionIdParam);\n goog.log.warning(\n this.logger_,\n 'Ignore httpSessionIdParam also specified with messageUrlParams: ' +\n httpSessionIdParam);\n }\n }\n\n /**\n * The channel handler.\n *\n * @private {!WebChannelBaseTransport.Channel.Handler_}\n */\n this.channelHandler_ = new WebChannelBaseTransport.Channel.Handler_(this);\n};\ngoog.inherits(WebChannelBaseTransport.Channel, goog.events.EventTarget);\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.open = function() {\n 'use strict';\n this.channel_.setHandler(this.channelHandler_);\n if (this.supportsCrossDomainXhr_) {\n this.channel_.setSupportsCrossDomainXhrs(true);\n }\n this.channel_.connect(this.url_, (this.messageUrlParams_ || undefined));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.close = function() {\n 'use strict';\n this.channel_.disconnect();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.halfClose = function() {\n 'use strict';\n // to be implemented\n throw new Error('Not implemented');\n};\n\n\n/**\n * The WebChannelBase only supports object types.\n *\n * @param {!goog.net.WebChannel.MessageData} message The message to send.\n *\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.send = function(message) {\n 'use strict';\n this.channel_.sendMap(this.messageToMapObject_(message));\n};\n\n\n/**\n * Converts a message to the map used by the underlying channel.\n *\n * @param {!goog.net.WebChannel.MessageData} message\n * @return {!Object|!goog.collections.maps.MapLike}\n */\nWebChannelBaseTransport.Channel.prototype.messageToMapObject_ = function(\n message) {\n 'use strict';\n goog.asserts.assert(\n goog.isObject(message) || typeof message === 'string',\n 'only object type or raw string is supported');\n\n if (typeof message === 'string') {\n const rawJson = {};\n rawJson[Wire.RAW_DATA_KEY] = message;\n return rawJson;\n }\n\n if (this.sendRawJson_) {\n const rawJson = {};\n rawJson[Wire.RAW_DATA_KEY] = goog.json.serialize(message);\n return rawJson;\n }\n\n return message;\n};\n\n\n/**\n * Converts the map used by the underlying channel to a message.\n *\n * NOTE: In the case of the message being JS Object or string, the exact same\n * object passed during `messageToMapObject_()` is returned. In the case of raw\n * JSON, an equal (but not the same) object is returned (due to serialization).\n *\n * @param {!Object|!goog.collections.maps.MapLike} map\n * @return {!goog.net.WebChannel.MessageData}\n */\nWebChannelBaseTransport.Channel.prototype.mapObjectToMessage_ = function(map) {\n 'use strict';\n if (Wire.RAW_DATA_KEY in map) {\n const rawMessage = map[Wire.RAW_DATA_KEY];\n\n if (this.sendRawJson_) {\n return /** @type {!goog.net.WebChannel.MessageData} */ (\n goog.json.parse(rawMessage));\n } else { // string message\n return rawMessage;\n }\n }\n\n return map;\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.disposeInternal = function() {\n 'use strict';\n this.channel_.setHandler(null);\n delete this.channelHandler_;\n this.channel_.disconnect();\n delete this.channel_;\n\n WebChannelBaseTransport.Channel.base(this, 'disposeInternal');\n};\n\n\n\n/**\n * The message event.\n *\n * @param {!Array<?>|!Object} array The data array from the underlying channel.\n * @constructor\n * @extends {goog.net.WebChannel.MessageEvent}\n * @final\n */\nWebChannelBaseTransport.Channel.MessageEvent = function(array) {\n 'use strict';\n WebChannelBaseTransport.Channel.MessageEvent.base(this, 'constructor');\n\n // Metadata as HTTP headers and status code (always come in a pair).\n if (array['__headers__']) {\n this.headers = array['__headers__'];\n this.statusCode = array['__status__'];\n delete array['__headers__'];\n delete array['__status__'];\n }\n\n // single-metadata only\n const metadata = array['__sm__'];\n if (metadata) {\n this.metadataKey = goog.object.getAnyKey(metadata);\n if (this.metadataKey) {\n this.data = goog.object.get(metadata, this.metadataKey);\n } else {\n this.data = metadata; // empty\n }\n } else {\n this.data = array;\n }\n};\ngoog.inherits(\n WebChannelBaseTransport.Channel.MessageEvent,\n goog.net.WebChannel.MessageEvent);\n\n\n\n/**\n * The error event.\n *\n * @param {WebChannelBase.Error} error The error code.\n * @constructor\n * @extends {goog.net.WebChannel.ErrorEvent}\n * @final\n */\nWebChannelBaseTransport.Channel.ErrorEvent = function(error) {\n 'use strict';\n WebChannelBaseTransport.Channel.ErrorEvent.base(this, 'constructor');\n\n /**\n * High-level status code.\n */\n this.status = goog.net.WebChannel.ErrorStatus.NETWORK_ERROR;\n\n /**\n * @const {WebChannelBase.Error} Internal error code, for debugging use only.\n */\n this.errorCode = error;\n};\ngoog.inherits(\n WebChannelBaseTransport.Channel.ErrorEvent, goog.net.WebChannel.ErrorEvent);\n\n\n\n/**\n * Implementation of {@link WebChannelBase.Handler} interface.\n *\n * @param {!WebChannelBaseTransport.Channel} channel The enclosing WebChannel.\n *\n * @constructor\n * @extends {WebChannelBase.Handler}\n * @private\n */\nWebChannelBaseTransport.Channel.Handler_ = function(channel) {\n 'use strict';\n WebChannelBaseTransport.Channel.Handler_.base(this, 'constructor');\n\n /**\n * @type {!WebChannelBaseTransport.Channel}\n * @private\n */\n this.channel_ = channel;\n};\ngoog.inherits(WebChannelBaseTransport.Channel.Handler_, WebChannelBase.Handler);\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelOpened = function(\n channel) {\n 'use strict';\n goog.log.info(\n this.channel_.logger_, 'WebChannel opened on ' + this.channel_.url_);\n this.channel_.dispatchEvent(goog.net.WebChannel.EventType.OPEN);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelHandleArray =\n function(channel, array) {\n 'use strict';\n goog.asserts.assert(array, 'array expected to be defined');\n this.channel_.dispatchEvent(\n new WebChannelBaseTransport.Channel.MessageEvent(array));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelError = function(\n channel, error) {\n 'use strict';\n goog.log.info(\n this.channel_.logger_,\n 'WebChannel aborted on ' + this.channel_.url_ +\n ' due to channel error: ' + error);\n this.channel_.dispatchEvent(\n new WebChannelBaseTransport.Channel.ErrorEvent(error));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.Handler_.prototype.channelClosed = function(\n channel, opt_pendingMaps, opt_undeliveredMaps) {\n 'use strict';\n goog.log.info(\n this.channel_.logger_, 'WebChannel closed on ' + this.channel_.url_);\n this.channel_.dispatchEvent(goog.net.WebChannel.EventType.CLOSE);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.Channel.prototype.getRuntimeProperties = function() {\n 'use strict';\n return new WebChannelBaseTransport.ChannelProperties(this, this.channel_);\n};\n\n\n\n/**\n * Implementation of the {@link goog.net.WebChannel.RuntimeProperties}.\n *\n * @param {!WebChannelBaseTransport.Channel} transportChannel The transport\n * channel object.\n * @param {!WebChannelBase} channel The underlying channel object.\n *\n * @constructor\n * @implements {goog.net.WebChannel.RuntimeProperties}\n * @final\n */\nWebChannelBaseTransport.ChannelProperties = function(\n transportChannel, channel) {\n 'use strict';\n /**\n * The transport channel object.\n *\n * @private @const {!WebChannelBaseTransport.Channel}\n */\n this.transportChannel_ = transportChannel;\n\n /**\n * The underlying channel object.\n *\n * @private @const {!WebChannelBase}\n */\n this.channel_ = channel;\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getConcurrentRequestLimit =\n function() {\n 'use strict';\n return this.channel_.getForwardChannelRequestPool().getMaxSize();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.isSpdyEnabled = function() {\n 'use strict';\n return this.getConcurrentRequestLimit() > 1;\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getPendingRequestCount =\n function() {\n 'use strict';\n return this.channel_.getForwardChannelRequestPool().getRequestCount();\n};\n\n\n/**\n * @override\n * @return {!Array<!goog.net.WebChannel.MessageData>}\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getNonAckedMessages =\n function() {\n 'use strict';\n return this.channel_.getNonAckedMaps().map(\n queued_map => this.transportChannel_.mapObjectToMessage_(queued_map.map));\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getHttpSessionId =\n function() {\n 'use strict';\n return this.channel_.getHttpSessionId();\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.commit = function(\n callback) {\n 'use strict';\n this.channel_.setForwardChannelFlushCallback(callback);\n};\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.notifyNonAckedMessageCount =\n goog.abstractMethod;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.onCommit =\n goog.abstractMethod;\n\n\n/**\n * @override\n */\nWebChannelBaseTransport.ChannelProperties.prototype.ackCommit =\n goog.abstractMethod;\n\n\n/**\n * @override\n * @return {!Object<string, string>|undefined}\n */\nWebChannelBaseTransport.ChannelProperties.prototype.getLastResponseHeaders =\n function() {\n 'use strict';\n return this.channel_.getLastResponseHeaders();\n};\n\n/** @override */\nWebChannelBaseTransport.ChannelProperties.prototype.getLastStatusCode =\n function() {\n 'use strict';\n return this.channel_.getLastStatusCode();\n};\n}); // goog.scope\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Abstract cryptographic hash interface.\n *\n * See goog.crypt.Sha1 and goog.crypt.Md5 for sample implementations.\n */\n\ngoog.provide('goog.crypt.Hash');\n\n\n\n/**\n * Create a cryptographic hash instance.\n *\n * @constructor\n * @struct\n */\ngoog.crypt.Hash = function() {\n 'use strict';\n /**\n * The block size for the hasher.\n * @type {number}\n */\n this.blockSize = -1;\n};\n\n\n/**\n * Resets the internal accumulator.\n */\ngoog.crypt.Hash.prototype.reset = goog.abstractMethod;\n\n\n/**\n * Adds a byte array (array with values in [0-255] range) or a string (must\n * only contain 8-bit, i.e., Latin1 characters) to the internal accumulator.\n *\n * Many hash functions operate on blocks of data and implement optimizations\n * when a full chunk of data is readily available. Hence it is often preferable\n * to provide large chunks of data (a kilobyte or more) than to repeatedly\n * call the update method with few tens of bytes. If this is not possible, or\n * not feasible, it might be good to provide data in multiplies of hash block\n * size (often 64 bytes). Please see the implementation and performance tests\n * of your favourite hash.\n *\n * @param {Array<number>|Uint8Array|string} bytes Data used for the update.\n * @param {number=} opt_length Number of bytes to use.\n */\ngoog.crypt.Hash.prototype.update = goog.abstractMethod;\n\n\n/**\n * @return {!Array<number>} The finalized hash computed\n * from the internal accumulator.\n */\ngoog.crypt.Hash.prototype.digest = goog.abstractMethod;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview MD5 cryptographic hash.\n * Implementation of http://tools.ietf.org/html/rfc1321 with common\n * optimizations and tweaks (see http://en.wikipedia.org/wiki/MD5).\n *\n * Usage:\n * var md5 = new goog.crypt.Md5();\n * md5.update(bytes);\n * var hash = md5.digest();\n *\n * Performance:\n * Chrome 23 ~680 Mbit/s\n * Chrome 13 (in a VM) ~250 Mbit/s\n * Firefox 6.0 (in a VM) ~100 Mbit/s\n * IE9 (in a VM) ~27 Mbit/s\n * Firefox 3.6 ~15 Mbit/s\n * IE8 (in a VM) ~13 Mbit/s\n */\n\ngoog.provide('goog.crypt.Md5');\n\ngoog.require('goog.crypt.Hash');\n\n\n\n/**\n * MD5 cryptographic hash constructor.\n * @constructor\n * @extends {goog.crypt.Hash}\n * @final\n * @struct\n */\ngoog.crypt.Md5 = function() {\n 'use strict';\n goog.crypt.Md5.base(this, 'constructor');\n\n /** @const {number} */\n this.blockSize = 512 / 8;\n\n /**\n * Holds the current values of accumulated A-D variables (MD buffer).\n * @type {!Array<number>}\n * @private\n */\n this.chain_ = new Array(4);\n\n /**\n * A buffer holding the data until the whole block can be processed.\n * @type {!Array<number>}\n * @private\n */\n this.block_ = new Array(this.blockSize);\n\n /**\n * The length of yet-unprocessed data as collected in the block.\n * @type {number}\n * @private\n */\n this.blockLength_ = 0;\n\n /**\n * The total length of the message so far.\n * @type {number}\n * @private\n */\n this.totalLength_ = 0;\n\n this.reset();\n};\ngoog.inherits(goog.crypt.Md5, goog.crypt.Hash);\n\n\n/**\n * Integer rotation constants used by the abbreviated implementation.\n * They are hardcoded in the unrolled implementation, so it is left\n * here commented out.\n * @type {Array<number>}\n * @private\n *\ngoog.crypt.Md5.S_ = [\n 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,\n 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,\n 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,\n 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21\n];\n */\n\n/**\n * Sine function constants used by the abbreviated implementation.\n * They are hardcoded in the unrolled implementation, so it is left\n * here commented out.\n * @type {Array<number>}\n * @private\n *\ngoog.crypt.Md5.T_ = [\n 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,\n 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,\n 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,\n 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,\n 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,\n 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,\n 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,\n 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,\n 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,\n 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,\n 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,\n 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,\n 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,\n 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,\n 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,\n 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391\n];\n */\n\n\n/** @override */\ngoog.crypt.Md5.prototype.reset = function() {\n 'use strict';\n this.chain_[0] = 0x67452301;\n this.chain_[1] = 0xefcdab89;\n this.chain_[2] = 0x98badcfe;\n this.chain_[3] = 0x10325476;\n\n this.blockLength_ = 0;\n this.totalLength_ = 0;\n};\n\n\n/**\n * Internal compress helper function. It takes a block of data (64 bytes)\n * and updates the accumulator.\n * @param {Array<number>|Uint8Array|string} buf The block to compress.\n * @param {number=} opt_offset Offset of the block in the buffer.\n * @private\n */\ngoog.crypt.Md5.prototype.compress_ = function(buf, opt_offset) {\n 'use strict';\n if (!opt_offset) {\n opt_offset = 0;\n }\n\n // We allocate the array every time, but it's cheap in practice.\n var X = new Array(16);\n\n // Get 16 little endian words. It is not worth unrolling this for Chrome 11.\n if (typeof buf === 'string') {\n for (var i = 0; i < 16; ++i) {\n X[i] = (buf.charCodeAt(opt_offset++)) |\n (buf.charCodeAt(opt_offset++) << 8) |\n (buf.charCodeAt(opt_offset++) << 16) |\n (buf.charCodeAt(opt_offset++) << 24);\n }\n } else {\n for (var i = 0; i < 16; ++i) {\n X[i] = (buf[opt_offset++]) | (buf[opt_offset++] << 8) |\n (buf[opt_offset++] << 16) | (buf[opt_offset++] << 24);\n }\n }\n\n var A = this.chain_[0];\n var B = this.chain_[1];\n var C = this.chain_[2];\n var D = this.chain_[3];\n var sum = 0;\n\n /*\n * This is an abbreviated implementation, it is left here commented out for\n * reference purposes. See below for an unrolled version in use.\n *\n var f, n, tmp;\n for (var i = 0; i < 64; ++i) {\n\n if (i < 16) {\n f = (D ^ (B & (C ^ D)));\n n = i;\n } else if (i < 32) {\n f = (C ^ (D & (B ^ C)));\n n = (5 * i + 1) % 16;\n } else if (i < 48) {\n f = (B ^ C ^ D);\n n = (3 * i + 5) % 16;\n } else {\n f = (C ^ (B | (~D)));\n n = (7 * i) % 16;\n }\n\n tmp = D;\n D = C;\n C = B;\n sum = (A + f + goog.crypt.Md5.T_[i] + X[n]) & 0xffffffff;\n B += ((sum << goog.crypt.Md5.S_[i]) & 0xffffffff) |\n (sum >>> (32 - goog.crypt.Md5.S_[i]));\n A = tmp;\n }\n */\n\n /*\n * This is an unrolled MD5 implementation, which gives ~30% speedup compared\n * to the abbreviated implementation above, as measured on Chrome 11. It is\n * important to keep 32-bit croppings to minimum and inline the integer\n * rotation.\n */\n sum = (A + (D ^ (B & (C ^ D))) + X[0] + 0xd76aa478) & 0xffffffff;\n A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));\n sum = (D + (C ^ (A & (B ^ C))) + X[1] + 0xe8c7b756) & 0xffffffff;\n D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));\n sum = (C + (B ^ (D & (A ^ B))) + X[2] + 0x242070db) & 0xffffffff;\n C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));\n sum = (B + (A ^ (C & (D ^ A))) + X[3] + 0xc1bdceee) & 0xffffffff;\n B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));\n sum = (A + (D ^ (B & (C ^ D))) + X[4] + 0xf57c0faf) & 0xffffffff;\n A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));\n sum = (D + (C ^ (A & (B ^ C))) + X[5] + 0x4787c62a) & 0xffffffff;\n D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));\n sum = (C + (B ^ (D & (A ^ B))) + X[6] + 0xa8304613) & 0xffffffff;\n C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));\n sum = (B + (A ^ (C & (D ^ A))) + X[7] + 0xfd469501) & 0xffffffff;\n B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));\n sum = (A + (D ^ (B & (C ^ D))) + X[8] + 0x698098d8) & 0xffffffff;\n A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));\n sum = (D + (C ^ (A & (B ^ C))) + X[9] + 0x8b44f7af) & 0xffffffff;\n D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));\n sum = (C + (B ^ (D & (A ^ B))) + X[10] + 0xffff5bb1) & 0xffffffff;\n C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));\n sum = (B + (A ^ (C & (D ^ A))) + X[11] + 0x895cd7be) & 0xffffffff;\n B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));\n sum = (A + (D ^ (B & (C ^ D))) + X[12] + 0x6b901122) & 0xffffffff;\n A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));\n sum = (D + (C ^ (A & (B ^ C))) + X[13] + 0xfd987193) & 0xffffffff;\n D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));\n sum = (C + (B ^ (D & (A ^ B))) + X[14] + 0xa679438e) & 0xffffffff;\n C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));\n sum = (B + (A ^ (C & (D ^ A))) + X[15] + 0x49b40821) & 0xffffffff;\n B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));\n sum = (A + (C ^ (D & (B ^ C))) + X[1] + 0xf61e2562) & 0xffffffff;\n A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));\n sum = (D + (B ^ (C & (A ^ B))) + X[6] + 0xc040b340) & 0xffffffff;\n D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));\n sum = (C + (A ^ (B & (D ^ A))) + X[11] + 0x265e5a51) & 0xffffffff;\n C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));\n sum = (B + (D ^ (A & (C ^ D))) + X[0] + 0xe9b6c7aa) & 0xffffffff;\n B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));\n sum = (A + (C ^ (D & (B ^ C))) + X[5] + 0xd62f105d) & 0xffffffff;\n A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));\n sum = (D + (B ^ (C & (A ^ B))) + X[10] + 0x02441453) & 0xffffffff;\n D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));\n sum = (C + (A ^ (B & (D ^ A))) + X[15] + 0xd8a1e681) & 0xffffffff;\n C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));\n sum = (B + (D ^ (A & (C ^ D))) + X[4] + 0xe7d3fbc8) & 0xffffffff;\n B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));\n sum = (A + (C ^ (D & (B ^ C))) + X[9] + 0x21e1cde6) & 0xffffffff;\n A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));\n sum = (D + (B ^ (C & (A ^ B))) + X[14] + 0xc33707d6) & 0xffffffff;\n D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));\n sum = (C + (A ^ (B & (D ^ A))) + X[3] + 0xf4d50d87) & 0xffffffff;\n C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));\n sum = (B + (D ^ (A & (C ^ D))) + X[8] + 0x455a14ed) & 0xffffffff;\n B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));\n sum = (A + (C ^ (D & (B ^ C))) + X[13] + 0xa9e3e905) & 0xffffffff;\n A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));\n sum = (D + (B ^ (C & (A ^ B))) + X[2] + 0xfcefa3f8) & 0xffffffff;\n D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));\n sum = (C + (A ^ (B & (D ^ A))) + X[7] + 0x676f02d9) & 0xffffffff;\n C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));\n sum = (B + (D ^ (A & (C ^ D))) + X[12] + 0x8d2a4c8a) & 0xffffffff;\n B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));\n sum = (A + (B ^ C ^ D) + X[5] + 0xfffa3942) & 0xffffffff;\n A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));\n sum = (D + (A ^ B ^ C) + X[8] + 0x8771f681) & 0xffffffff;\n D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));\n sum = (C + (D ^ A ^ B) + X[11] + 0x6d9d6122) & 0xffffffff;\n C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));\n sum = (B + (C ^ D ^ A) + X[14] + 0xfde5380c) & 0xffffffff;\n B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));\n sum = (A + (B ^ C ^ D) + X[1] + 0xa4beea44) & 0xffffffff;\n A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));\n sum = (D + (A ^ B ^ C) + X[4] + 0x4bdecfa9) & 0xffffffff;\n D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));\n sum = (C + (D ^ A ^ B) + X[7] + 0xf6bb4b60) & 0xffffffff;\n C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));\n sum = (B + (C ^ D ^ A) + X[10] + 0xbebfbc70) & 0xffffffff;\n B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));\n sum = (A + (B ^ C ^ D) + X[13] + 0x289b7ec6) & 0xffffffff;\n A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));\n sum = (D + (A ^ B ^ C) + X[0] + 0xeaa127fa) & 0xffffffff;\n D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));\n sum = (C + (D ^ A ^ B) + X[3] + 0xd4ef3085) & 0xffffffff;\n C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));\n sum = (B + (C ^ D ^ A) + X[6] + 0x04881d05) & 0xffffffff;\n B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));\n sum = (A + (B ^ C ^ D) + X[9] + 0xd9d4d039) & 0xffffffff;\n A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));\n sum = (D + (A ^ B ^ C) + X[12] + 0xe6db99e5) & 0xffffffff;\n D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));\n sum = (C + (D ^ A ^ B) + X[15] + 0x1fa27cf8) & 0xffffffff;\n C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));\n sum = (B + (C ^ D ^ A) + X[2] + 0xc4ac5665) & 0xffffffff;\n B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));\n sum = (A + (C ^ (B | (~D))) + X[0] + 0xf4292244) & 0xffffffff;\n A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));\n sum = (D + (B ^ (A | (~C))) + X[7] + 0x432aff97) & 0xffffffff;\n D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));\n sum = (C + (A ^ (D | (~B))) + X[14] + 0xab9423a7) & 0xffffffff;\n C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));\n sum = (B + (D ^ (C | (~A))) + X[5] + 0xfc93a039) & 0xffffffff;\n B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));\n sum = (A + (C ^ (B | (~D))) + X[12] + 0x655b59c3) & 0xffffffff;\n A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));\n sum = (D + (B ^ (A | (~C))) + X[3] + 0x8f0ccc92) & 0xffffffff;\n D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));\n sum = (C + (A ^ (D | (~B))) + X[10] + 0xffeff47d) & 0xffffffff;\n C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));\n sum = (B + (D ^ (C | (~A))) + X[1] + 0x85845dd1) & 0xffffffff;\n B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));\n sum = (A + (C ^ (B | (~D))) + X[8] + 0x6fa87e4f) & 0xffffffff;\n A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));\n sum = (D + (B ^ (A | (~C))) + X[15] + 0xfe2ce6e0) & 0xffffffff;\n D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));\n sum = (C + (A ^ (D | (~B))) + X[6] + 0xa3014314) & 0xffffffff;\n C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));\n sum = (B + (D ^ (C | (~A))) + X[13] + 0x4e0811a1) & 0xffffffff;\n B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));\n sum = (A + (C ^ (B | (~D))) + X[4] + 0xf7537e82) & 0xffffffff;\n A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));\n sum = (D + (B ^ (A | (~C))) + X[11] + 0xbd3af235) & 0xffffffff;\n D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));\n sum = (C + (A ^ (D | (~B))) + X[2] + 0x2ad7d2bb) & 0xffffffff;\n C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));\n sum = (B + (D ^ (C | (~A))) + X[9] + 0xeb86d391) & 0xffffffff;\n B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));\n\n this.chain_[0] = (this.chain_[0] + A) & 0xffffffff;\n this.chain_[1] = (this.chain_[1] + B) & 0xffffffff;\n this.chain_[2] = (this.chain_[2] + C) & 0xffffffff;\n this.chain_[3] = (this.chain_[3] + D) & 0xffffffff;\n};\n\n\n/** @override */\ngoog.crypt.Md5.prototype.update = function(bytes, opt_length) {\n 'use strict';\n if (opt_length === undefined) {\n opt_length = bytes.length;\n }\n var lengthMinusBlock = opt_length - this.blockSize;\n\n // Copy some object properties to local variables in order to save on access\n // time from inside the loop (~10% speedup was observed on Chrome 11).\n var block = this.block_;\n var blockLength = this.blockLength_;\n var i = 0;\n\n // The outer while loop should execute at most twice.\n while (i < opt_length) {\n // When we have no data in the block to top up, we can directly process the\n // input buffer (assuming it contains sufficient data). This gives ~30%\n // speedup on Chrome 14 and ~70% speedup on Firefox 6.0, but requires that\n // the data is provided in large chunks (or in multiples of 64 bytes).\n if (blockLength == 0) {\n while (i <= lengthMinusBlock) {\n this.compress_(bytes, i);\n i += this.blockSize;\n }\n }\n\n if (typeof bytes === 'string') {\n while (i < opt_length) {\n block[blockLength++] = bytes.charCodeAt(i++);\n if (blockLength == this.blockSize) {\n this.compress_(block);\n blockLength = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n } else {\n while (i < opt_length) {\n block[blockLength++] = bytes[i++];\n if (blockLength == this.blockSize) {\n this.compress_(block);\n blockLength = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n }\n }\n\n this.blockLength_ = blockLength;\n this.totalLength_ += opt_length;\n};\n\n\n/** @override */\ngoog.crypt.Md5.prototype.digest = function() {\n 'use strict';\n // This must accommodate at least 1 padding byte (0x80), 8 bytes of\n // total bitlength, and must end at a 64-byte boundary.\n var pad = new Array(\n (this.blockLength_ < 56 ? this.blockSize : this.blockSize * 2) -\n this.blockLength_);\n\n // Add padding: 0x80 0x00*\n pad[0] = 0x80;\n for (var i = 1; i < pad.length - 8; ++i) {\n pad[i] = 0;\n }\n // Add the total number of bits, little endian 64-bit integer.\n var totalBits = this.totalLength_ * 8;\n for (var i = pad.length - 8; i < pad.length; ++i) {\n pad[i] = totalBits & 0xff;\n totalBits /= 0x100; // Don't use bit-shifting here!\n }\n this.update(pad);\n\n var digest = new Array(16);\n var n = 0;\n for (var i = 0; i < 4; ++i) {\n for (var j = 0; j < 32; j += 8) {\n digest[n++] = (this.chain_[i] >>> j) & 0xff;\n }\n }\n return digest;\n};\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Bring in closure-library dependencies\n */\n\ngoog.provide('firebase.webchannel.wrapper');\n\n// goog.net.WebChannelTransport\ngoog.require('goog.net.createWebChannelTransport');\ngoog.require('goog.net.FetchXmlHttpFactory');\ngoog.require('goog.labs.net.webChannel.requestStats');\ngoog.require('goog.labs.net.webChannel.WebChannelBaseTransport');\n\n/**\n * NOTE: The `createWebChannel` function takes an options object as a second param\n * whose properties are typically mangled. We override these in externs/overrides.js\n * Without those externs, this does not function properly.\n */\ngoog.labs.net.webChannel.WebChannelBaseTransport.prototype['createWebChannel'] =\n goog.labs.net.webChannel.WebChannelBaseTransport.prototype.createWebChannel;\ngoog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype['send'] =\n goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.send;\ngoog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype['open'] =\n goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.open;\ngoog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype['close'] =\n goog.labs.net.webChannel.WebChannelBaseTransport.Channel.prototype.close;\n\n// goog.net.ErrorCode\ngoog.require('goog.net.ErrorCode');\ngoog.net.ErrorCode['NO_ERROR'] = goog.net.ErrorCode.NO_ERROR;\ngoog.net.ErrorCode['TIMEOUT'] = goog.net.ErrorCode.TIMEOUT;\ngoog.net.ErrorCode['HTTP_ERROR'] = goog.net.ErrorCode.HTTP_ERROR;\n\n// goog.net.ErrorType\ngoog.require('goog.net.EventType');\ngoog.net.EventType['COMPLETE'] = goog.net.EventType.COMPLETE;\n\n// goog.net.WebChannel\ngoog.require('goog.net.WebChannel');\ngoog.require('goog.events.EventTarget');\ngoog.net.WebChannel['EventType'] = goog.net.WebChannel.EventType;\ngoog.net.WebChannel.EventType['OPEN'] = goog.net.WebChannel.EventType.OPEN;\ngoog.net.WebChannel.EventType['CLOSE'] = goog.net.WebChannel.EventType.CLOSE;\ngoog.net.WebChannel.EventType['ERROR'] = goog.net.WebChannel.EventType.ERROR;\ngoog.net.WebChannel.EventType['MESSAGE'] =\n goog.net.WebChannel.EventType.MESSAGE;\ngoog.events.EventTarget.prototype['listen'] =\n goog.events.EventTarget.prototype.listen;\n\ngoog.require('goog.net.XhrIo');\ngoog.net.XhrIo.prototype['listenOnce'] = goog.net.XhrIo.prototype.listenOnce;\ngoog.net.XhrIo.prototype['getLastError'] =\n goog.net.XhrIo.prototype.getLastError;\ngoog.net.XhrIo.prototype['getLastErrorCode'] =\n goog.net.XhrIo.prototype.getLastErrorCode;\ngoog.net.XhrIo.prototype['getStatus'] = goog.net.XhrIo.prototype.getStatus;\ngoog.net.XhrIo.prototype['getResponseJson'] =\n goog.net.XhrIo.prototype.getResponseJson;\ngoog.net.XhrIo.prototype['getResponseText'] =\n goog.net.XhrIo.prototype.getResponseText;\ngoog.net.XhrIo.prototype['send'] = goog.net.XhrIo.prototype.send;\ngoog.net.XhrIo.prototype['setWithCredentials'] =\n goog.net.XhrIo.prototype.setWithCredentials;\n\ngoog.require('goog.crypt.Md5');\ngoog.crypt.Md5.prototype['digest'] = goog.crypt.Md5.prototype.digest;\ngoog.crypt.Md5.prototype['reset'] = goog.crypt.Md5.prototype.reset;\ngoog.crypt.Md5.prototype['update'] = goog.crypt.Md5.prototype.update;\n\ngoog.require('goog.math.Integer');\ngoog.math.Integer.prototype['add'] = goog.math.Integer.prototype.add;\ngoog.math.Integer.prototype['multiply'] = goog.math.Integer.prototype.multiply;\ngoog.math.Integer.prototype['modulo'] = goog.math.Integer.prototype.modulo;\ngoog.math.Integer.prototype['compare'] = goog.math.Integer.prototype.compare;\ngoog.math.Integer.prototype['toNumber'] = goog.math.Integer.prototype.toNumber;\ngoog.math.Integer.prototype['toString'] = goog.math.Integer.prototype.toString;\ngoog.math.Integer.prototype['getBits'] = goog.math.Integer.prototype.getBits;\ngoog.math.Integer['fromNumber'] = goog.math.Integer.fromNumber;\ngoog.math.Integer['fromString'] = goog.math.Integer.fromString;\n\nmodule['exports']['createWebChannelTransport'] =\n goog.net.createWebChannelTransport;\nmodule['exports']['getStatEventTarget'] =\n goog.labs.net.webChannel.requestStats.getStatEventTarget;\nmodule['exports']['ErrorCode'] = goog.net.ErrorCode;\nmodule['exports']['EventType'] = goog.net.EventType;\nmodule['exports']['Event'] = goog.labs.net.webChannel.requestStats.Event;\nmodule['exports']['Stat'] = goog.labs.net.webChannel.requestStats.Stat;\nmodule['exports']['FetchXmlHttpFactory'] = goog.net.FetchXmlHttpFactory;\nmodule['exports']['WebChannel'] = goog.net.WebChannel;\nmodule['exports']['XhrIo'] = goog.net.XhrIo;\nmodule['exports']['Md5'] = goog.crypt.Md5;\nmodule['exports']['Integer'] = goog.math.Integer;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Default factory for <code>WebChannelTransport</code> to\n * avoid exposing concrete classes to clients.\n */\n\ngoog.provide('goog.net.createWebChannelTransport');\n\ngoog.require('goog.labs.net.webChannel.WebChannelBaseTransport');\ngoog.requireType('goog.net.WebChannelTransport');\n\n\n/**\n * Create a new WebChannelTransport instance using the default implementation.\n * Throws an error message if no default transport available in the current\n * environment.\n *\n * @return {!goog.net.WebChannelTransport} the newly created transport instance.\n */\ngoog.net.createWebChannelTransport = function() {\n 'use strict';\n return new goog.labs.net.webChannel.WebChannelBaseTransport();\n};\n"]} |