1 line
2.4 MiB
1 line
2.4 MiB
{"version":3,"sources":["../../node_modules/google-closure-library/closure/goog/base.js"," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/util/arrayiterator] "," [synthetic:es6/util/makeiterator] "," [synthetic:es6/promise/promise] ","src/error_auth.js","src/defines.js","../../node_modules/google-closure-library/closure/goog/promise/thenable.js","../../node_modules/google-closure-library/closure/goog/debug/error.js","../../node_modules/google-closure-library/closure/goog/asserts/asserts.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/array/array.js","../../node_modules/google-closure-library/closure/goog/net/xhrio.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/object/object.js","../../node_modules/google-closure-library/closure/goog/dom/asserts.js","../../node_modules/google-closure-library/closure/goog/string/const.js","../../node_modules/google-closure-library/closure/goog/html/trustedresourceurl.js","../../node_modules/google-closure-library/closure/goog/html/safeurl.js","../../node_modules/google-closure-library/closure/goog/html/safehtml.js","../../node_modules/google-closure-library/closure/goog/dom/safe.js","../../node_modules/google-closure-library/closure/goog/async/nexttick.js","../../node_modules/google-closure-library/closure/goog/string/string.js","../../node_modules/google-closure-library/closure/goog/reflect/reflect.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/dom/browserfeature.js","../../node_modules/google-closure-library/closure/goog/dom/dom.js","../../node_modules/google-closure-library/closure/goog/promise/promise.js","../../node_modules/google-closure-library/closure/goog/disposable/disposable.js","../../node_modules/google-closure-library/closure/goog/debug/debug.js","../../node_modules/google-closure-library/closure/goog/events/browserfeature.js","../../node_modules/google-closure-library/closure/goog/events/event.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/listener.js","../../node_modules/google-closure-library/closure/goog/events/listenermap.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/timer/timer.js","../../node_modules/google-closure-library/closure/goog/structs/structs.js","../../node_modules/google-closure-library/closure/goog/structs/map.js","../../node_modules/google-closure-library/closure/goog/uri/utils.js","../../node_modules/google-closure-library/closure/goog/uri/uri.js","src/iframeclient/ifchandler.js","../../node_modules/google-closure-library/closure/goog/json/json.js","src/utils.js","../../node_modules/google-closure-library/closure/goog/window/window.js","../../node_modules/google-closure-library/closure/goog/labs/useragent/platform.js","src/recaptchaverifier/grecaptchamock.js","src/deprecation.js","src/object.js","src/multifactorinfo.js","src/actioncodeinfo.js","src/actioncodeurl.js","src/actioncodesettings.js","../../node_modules/google-closure-library/closure/goog/crypt/crypt.js","../../node_modules/google-closure-library/closure/goog/crypt/base64.js","src/idtoken.js","src/idp.js","src/additionaluserinfo.js","src/dynamiclink.js","src/multifactorsession.js","src/authcredential.js","src/rpchandler.js","src/auth.js","src/authevent.js","src/universallinksubscriber.js","src/error_invalidorigin.js","src/error_withcredential.js","../../node_modules/google-closure-library/closure/goog/net/xmlhttpfactory.js","../../node_modules/google-closure-library/closure/goog/net/xmlhttp.js","../../node_modules/google-closure-library/closure/goog/net/corsxmlhttpfactory.js","../../node_modules/google-closure-library/closure/goog/net/httpstatus.js","../../node_modules/google-closure-library/closure/goog/debug/logrecord.js","../../node_modules/google-closure-library/closure/goog/debug/logger.js","../../node_modules/google-closure-library/closure/goog/log/log.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/net/eventtype.js","../../node_modules/google-closure-library/closure/goog/net/errorcode.js","../../node_modules/google-closure-library/third_party/closure/goog/mochikit/async/deferred.js","../../node_modules/google-closure-library/closure/goog/net/jsloader.js","src/iframeclient/iframewrapper.js","src/storage/asyncstorage.js","src/storage/storage.js","src/messagechannel/receiver.js","src/messagechannel/defines.js","src/messagechannel/postmessager.js","src/messagechannel/sender.js","src/storage/indexeddb.js","src/storage/hybridindexeddb.js","src/storage/inmemorystorage.js","src/storage/localstorage.js","src/storage/nullstorage.js","src/storage/sessionstorage.js","src/storage/factory.js","src/authstorage.js","src/storageautheventmanager.js","src/storageoauthhandlermanager.js","../../node_modules/google-closure-library/closure/goog/crypt/hash.js","../../node_modules/google-closure-library/closure/goog/crypt/sha2.js","../../node_modules/google-closure-library/closure/goog/crypt/sha256.js","src/cordovahandler.js","src/storagependingredirectmanager.js","src/autheventmanager.js","src/authsettings.js","src/confirmationresult.js","src/idtokenresult.js","src/multifactorresolver.js","src/multifactorerror.js","src/multifactorassertion.js","src/userevent.js","src/multifactoruser.js","src/authuser.js","src/proactiverefresh.js","src/token.js","src/storageredirectusermanager.js","src/storageusermanager.js","src/recaptchaverifier/grecaptcha.js","src/multifactorgenerator.js","src/recaptchaverifier/mockloader.js","src/recaptchaverifier/realloader.js","src/recaptchaverifier/recaptchaverifier.js","src/args.js","src/exports_lib.js","src/exports_auth.js"],"names":["$jscomp.defineProperty","$jscomp.global","$jscomp.getGlobal","$jscomp.arrayIteratorImpl","$jscomp.polyfill","$jscomp.makeIterator","goog","goog.global","self","goog.NONCE_PATTERN_","goog.cspNonce_","goog.nullFunction","goog.typeOf","value","s","Array","Object","className","prototype","toString","call","length","splice","propertyIsEnumerable","goog.isArrayLike","val","type","goog.isFunction","goog.isObject","goog.getUid","obj","hasOwnProperty","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","indexOf","goog.bind.apply","goog.partial","args","push","goog.now","Date","now","goog.inherits","childCtor","parentCtor","tempCtor","superClass_","constructor","fireauth.AuthError","code","message","serverResponse","fireauth.AuthError.ERROR_CODE_PREFIX","fireauth.AuthError.MESSAGES_","toPlainObject","fireauth.AuthError.prototype.toPlainObject","toJSON","fireauth.AuthError.prototype.toJSON","fireauth.AuthError.fromPlainObject","response","fullCode","substring","fireauth.AuthError.ERROR_CODE_PREFIX.length","ADMIN_ONLY_OPERATION","ARGUMENT_ERROR","APP_NOT_AUTHORIZED","APP_NOT_INSTALLED","CAPTCHA_CHECK_FAILED","CODE_EXPIRED","CORDOVA_NOT_READY","CORS_UNSUPPORTED","CREDENTIAL_ALREADY_IN_USE","CREDENTIAL_MISMATCH","CREDENTIAL_TOO_OLD_LOGIN_AGAIN","DYNAMIC_LINK_NOT_ACTIVATED","EMAIL_CHANGE_NEEDS_VERIFICATION","EMAIL_EXISTS","EXPIRED_OOB_CODE","EXPIRED_POPUP_REQUEST","INTERNAL_ERROR","INVALID_APP_CREDENTIAL","INVALID_APP_ID","INVALID_AUTH","INVALID_AUTH_EVENT","INVALID_CODE","INVALID_CONTINUE_URI","INVALID_CORDOVA_CONFIGURATION","INVALID_CUSTOM_TOKEN","INVALID_DYNAMIC_LINK_DOMAIN","INVALID_EMAIL","INVALID_API_KEY","INVALID_CERT_HASH","INVALID_IDP_RESPONSE","INVALID_MESSAGE_PAYLOAD","INVALID_MFA_PENDING_CREDENTIAL","INVALID_OAUTH_PROVIDER","INVALID_OAUTH_CLIENT_ID","INVALID_ORIGIN","INVALID_OOB_CODE","INVALID_PASSWORD","INVALID_PERSISTENCE","INVALID_PHONE_NUMBER","INVALID_PROVIDER_ID","INVALID_RECIPIENT_EMAIL","INVALID_SENDER","INVALID_SESSION_INFO","INVALID_TENANT_ID","MFA_ENROLLMENT_NOT_FOUND","MFA_REQUIRED","MISSING_ANDROID_PACKAGE_NAME","MISSING_AUTH_DOMAIN","MISSING_APP_CREDENTIAL","MISSING_CODE","MISSING_CONTINUE_URI","MISSING_IFRAME_START","MISSING_IOS_BUNDLE_ID","MISSING_MFA_ENROLLMENT_ID","MISSING_MFA_PENDING_CREDENTIAL","MISSING_OR_INVALID_NONCE","MISSING_PHONE_NUMBER","MISSING_SESSION_INFO","MODULE_DESTROYED","NEED_CONFIRMATION","NETWORK_REQUEST_FAILED","NO_AUTH_EVENT","NO_SUCH_PROVIDER","NULL_USER","OPERATION_NOT_ALLOWED","OPERATION_NOT_SUPPORTED","POPUP_BLOCKED","POPUP_CLOSED_BY_USER","PROVIDER_ALREADY_LINKED","QUOTA_EXCEEDED","REDIRECT_CANCELLED_BY_USER","REDIRECT_OPERATION_PENDING","REJECTED_CREDENTIAL","SECOND_FACTOR_EXISTS","SECOND_FACTOR_LIMIT_EXCEEDED","TENANT_ID_MISMATCH","TIMEOUT","TOKEN_EXPIRED","TOO_MANY_ATTEMPTS_TRY_LATER","UNAUTHORIZED_DOMAIN","UNSUPPORTED_FIRST_FACTOR","UNSUPPORTED_PERSISTENCE","UNSUPPORTED_TENANT_OPERATION","UNVERIFIED_EMAIL","USER_CANCELLED","USER_DELETED","USER_DISABLED","USER_MISMATCH","USER_SIGNED_OUT","WEAK_PASSWORD","WEB_STORAGE_UNSUPPORTED","fireauth.constants.Endpoint","BOQ","firebaseAuthEndpoint","secureTokenEndpoint","identityPlatformEndpoint","id","PRODUCTION","STAGING","TEST","fireauth.constants.getEndpointConfig","opt_id","endpointKey","endpoint","goog.Thenable.isImplementedBy","object","e","goog.debug.Error","opt_msg","captureStackTrace","stack","String","name","goog.asserts.AssertionError","messagePattern","messageArgs","splitParts","split","returnString","subLast","i","sub","goog.debug.Error.call","goog.asserts.fail","opt_message","create","reset","create_","reset_","occupants_","head_","goog.async.FreeList","get","item","next","put","goog.async.WorkQueue.DEFAULT_MAX_UNUSED","goog.async.WorkQueue","workTail_","workHead_","goog.async.WorkQueue.freelist_","goog.async.WorkItem","add","goog.async.WorkQueue.prototype.add","scope","goog.async.WorkQueue.freelist_.get","set","goog.async.WorkQueue.prototype.remove","goog.async.run.workQueue_.remove","goog.async.WorkItem.prototype.set","goog.async.WorkItem.prototype.reset","goog.array.indexOf","arr","opt_fromIndex","fromIndex","goog.array.forEach","forEach","f","opt_obj","l","arr2","goog.array.forEachRight","goog.array.filter","filter","res","resLength","goog.array.map","map","goog.array.some","some","goog.array.find","goog.net.XhrIo.isContentTypeHeader_","charAt","goog.array.contains","goog.array.remove","rv","goog.array.removeAllIf","removedCount","index","goog.array.concat","concat","goog.array.toArray","goog.string.internal.trim","trim","str","exec","goog.string.internal.AMP_RE_","goog.string.internal.LT_RE_","goog.string.internal.GT_RE_","goog.string.internal.QUOT_RE_","goog.string.internal.SINGLE_QUOTE_RE_","goog.string.internal.NULL_RE_","goog.string.internal.ALL_RE_","goog.string.internal.contains","subString","goog.string.internal.compareElements_","left","right","goog.labs.userAgent.util.userAgent_","navigator","goog.global.navigator","userAgent","goog.labs.userAgent.util.matchUserAgent","goog.object.forEach","key","goog.object.isEmpty","goog.object.clone","goog.object.PROTOTYPE_FIELDS_","goog.object.extend","target","source","j","goog.object.PROTOTYPE_FIELDS_.length","goog.dom.asserts.assertIsElementType_","o","typename","doc","ownerDocument","win","defaultView","parentWindow","Element","Location","ex","displayName","undefined","goog.string.Const","opt_token","opt_content","stringConstValueWithSecurityContract__googStringSecurityPrivate_","goog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_","STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_","goog.string.Const.TYPE_MARKER_","implementsGoogStringTypedString","getTypedStringValue","goog.string.Const.prototype.getTypedStringValue","goog.string.Const.prototype.toString","goog.string.Const.unwrap","stringConst","goog.string.Const.EMPTY","goog.html.TrustedResourceUrl","privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_","goog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_","TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_","goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_","goog.html.TrustedResourceUrl.prototype.getTypedStringValue","goog.html.TrustedResourceUrl.prototype.toString","goog.html.TrustedResourceUrl.unwrapTrustedScriptURL","trustedResourceUrl","goog.html.TrustedResourceUrl.format","format","formatStr","goog.html.TrustedResourceUrl.BASE_URL_.test","test","result","replace","goog.html.TrustedResourceUrl.FORMAT_MARKER_","match","JSON","stringify","arg","encodeURIComponent","goog.html.TrustedResourceUrl.BASE_URL_","goog.html.SafeUrl","privateDoNotAccessOrElseSafeUrlWrappedValue_","goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_","SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_","goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_","goog.html.SafeUrl.prototype.getTypedStringValue","goog.html.SafeUrl.prototype.toString","goog.html.SafeUrl.unwrap","safeUrl","goog.html.SAFE_URL_PATTERN_","goog.html.SafeUrl.sanitize","url","goog.html.SAFE_URL_PATTERN_.test","goog.html.SafeUrl.INNOCUOUS_STRING","goog.html.SafeHtml","privateDoNotAccessOrElseSafeHtmlWrappedValue_","SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_","goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_","goog.html.SafeHtml.prototype.getTypedStringValue","goog.html.SafeHtml.prototype.toString","goog.html.SafeHtml.unwrapTrustedHTML","safeHtml","goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_","html","initSecurityPrivateDoNotAccessOrElse_","goog.html.SafeHtml.EMPTY","goog.dom.safe.setIframeSrc","iframe","src","goog.dom.safe.setScriptSrc","script","goog.global.document","document","querySelector","nonce","getAttribute","goog.NONCE_PATTERN_.test","setAttribute","goog.string.subs","subsArguments","shift","join","goog.string.htmlEscape","goog.string.internal.ALL_RE_.test","goog.reflect.sinkValue","x","goog.reflect.cache","valueFn","cacheObj","goog.userAgent.isVersionOrHigherCache_","goog.userAgent.OPERA","goog.userAgent.IE","goog.userAgent.EDGE","goog.userAgent.EDGE_OR_IE","goog.userAgent.GECKO","toLowerCase","goog.userAgent.WEBKIT","goog.userAgent.getDocumentMode_","goog.userAgent.VERSION","version","goog.userAgent.getVersionRegexResult_","docMode","parseFloat","goog.userAgent.isVersionOrHigher","order","v1Subs","v2Subs","subCount","max","subIdx","v1Sub","v2Sub","v1Comp","v2Comp","v1CompNum","parseInt","v2CompNum","getContext","OffscreenCanvas","contextName","goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES","documentMode","Number","goog.userAgent.DOCUMENT_MODE","goog.dom.getElementHelper_","element","getElementById","goog.dom.setProperties","properties","style","cssText","htmlFor","goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty","goog.dom.DIRECT_ATTRIBUTE_MAP_","lastIndexOf","prefix","goog.dom.createDom","tagName","opt_attributes","attributes","tagNameArr","clone","goog.dom.createElement_","isArray","goog.dom.append_","parent","childHandler","child","appendChild","createTextNode","startIndex","nodeType","goog.dom.isNodeList","contentType","createElement","goog.async.throwException","exception","goog.global.setTimeout","setTimeout","goog.async.nextTick.getSetImmediateEmulator_","Channel","window","postMessage","addEventListener","goog.dom.TagName.IFRAME","display","documentElement","contentWindow","open","write","close","origin","location","protocol","host","onmessage","data","channel","head","tail","cb","goog.async.run","callback","opt_context","goog.async.run.schedule_","goog.async.run.initializeRunner_","goog.async.run.workQueueScheduled_","goog.async.run.workQueue_.add","goog.global.Promise","Promise","goog.global.Promise.resolve","resolve","promise","then","goog.async.run.processWorkQueue","goog.global.setImmediate","setImmediate","goog.global.Window","Window","goog.async.nextTick.setImmediate_","goog.async.run.workQueue_","remove","goog.async.WorkQueue.freelist_.put","goog.Promise","resolver","state_","goog.Promise.State_.PENDING","result_","callbackEntriesTail_","callbackEntries_","parent_","hadUnhandledRejection_","executing_","resolve_","goog.Promise.State_.FULFILLED","reason","goog.Promise.CancellationError","goog.Promise.State_.REJECTED","PENDING","FULFILLED","REJECTED","goog.Promise.CallbackEntry_","context","onRejected","onFulfilled","always","goog.Promise.CallbackEntry_.prototype.reset","goog.Promise.freelist_","goog.Promise.getCallbackEntry_","entry","goog.Promise.freelist_.get","goog.Promise.resolve","opt_value","goog.Promise.reject","opt_reason","reject","goog.Promise.resolveThen_","goog.Promise.maybeThen_","isThenable","goog.Promise.all","promises","toFulfill","values","onFulfill","onReject","goog.Promise.allSettled","toSettle","results","onSettled","fulfilled","goog.Promise.prototype.then","opt_onFulfilled","opt_onRejected","addChildPromise_","goog.Promise.prototype","thenAlways","goog.Promise.prototype.thenAlways","addCallbackEntry_","thenCatch","goog.Promise.prototype.thenCatch","cancel","goog.Promise.prototype.cancel","err","cancelInternal_","goog.Promise.prototype.cancelInternal_","childCount","childEntry","beforeChildEntry","childPromise","previous","removeEntryAfter_","popEntry_","executeCallback_","goog.Promise.prototype.addCallbackEntry_","callbackEntry","hasEntry_","scheduleCallbacks_","queueEntry_","goog.Promise.prototype.addChildPromise_","unblockAndFulfill_","goog.Promise.prototype.unblockAndFulfill_","unblockAndReject_","goog.Promise.prototype.unblockAndReject_","goog.Promise.prototype.resolve_","state","TypeError","BLOCKED","goog.Promise.addUnhandledRejection_","goog.Promise.tryThen_","thenable","called","goog.Promise.prototype.scheduleCallbacks_","executeCallbacks_","goog.Promise.prototype.popEntry_","goog.Promise.prototype.executeCallbacks_","goog.Promise.prototype.executeCallback_","p","goog.Promise.invokeCallback_","goog.Promise.handleRejection_.call","goog.Promise.freelist_.put","goog.Promise.handleRejection_","goog.Promise.CancellationError.base","goog.Disposable","goog.Disposable.MONITORING_MODE","goog.Disposable.MonitoringMode.OFF","goog.Disposable.instances_","disposed_","onDisposeCallbacks_","OFF","goog.Disposable.prototype.dispose","disposeInternal","uid","goog.Disposable.prototype.disposeInternal","goog.debug.freezeInternal_","freeze","HAS_W3C_EVENT_SUPPORT","SET_KEY_CODE_TO_PREVENT_DEFAULT","PASSIVE_EVENTS","goog.global.addEventListener","defineProperty","passive","options","goog.global.removeEventListener","removeEventListener","purify","goog.events.Event","opt_target","currentTarget","defaultPrevented","preventDefault","goog.events.Event.prototype.preventDefault","goog.events.BrowserEvent","opt_e","opt_currentTarget","goog.events.Event.call","goog.events.BrowserEvent.base","relatedTarget","button","screenY","screenX","clientY","clientX","metaKey","shiftKey","altKey","ctrlKey","pointerId","pointerType","event_","init","relevantTouch","changedTouches","srcElement","MOUSEOVER","fromElement","MOUSEOUT","toElement","pageX","pageY","goog.events.BrowserEvent.IE_POINTER_TYPE_MAP","TOUCH","PEN","MOUSE","goog.events.BrowserEvent.prototype.preventDefault","goog.events.BrowserEvent.superClass_.preventDefault.call","be","returnValue","goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT","VK_F1","keyCode","VK_F12","getBrowserEvent","goog.events.BrowserEvent.prototype.getBrowserEvent","goog.events.Listenable.IMPLEMENTED_BY_PROP","goog.events.ListenableKey.counter_","goog.events.Listener","listener","capture","opt_handler","proxy","handler","removed","callOnce","goog.events.Listener.prototype.markAsRemoved","goog.events.ListenerMap","listeners","typeCount_","goog.events.ListenerMap.prototype.add","opt_useCapture","opt_listenerScope","typeStr","listenerArray","goog.events.ListenerMap.findListenerIndex_","listenerObj","goog.events.ListenerMap.prototype.removeByKey","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","proxyCallbackFunction","goog.events.handleBrowserEvent_","goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT","eventObject","v","listenOnce","goog.events.unlisten","eventTargetListeners_","goog.events.unlistenByKey","removeByKey","detachEvent","goog.events.onString_","goog.events.fireListeners_","retval","goog.events.fireListener","listenerFn","listenerHandler","opt_evt","parts","cur","ieEvent","evt","useReturnValue","ancestors","parentNode","goog.events.LISTENER_WRAPPER_PROP_","handleEvent","goog.events.EventTarget","goog.Disposable.call","actualEventTarget_","parentEventTarget_","goog.events.EventTarget.prototype.addEventListener","opt_capture","opt_handlerScope","goog.events.EventTarget.prototype.removeEventListener","dispatchEvent","goog.events.EventTarget.prototype.dispatchEvent","ancestorsTree","ancestor","getParentEventTarget","oldEvent","opt_ancestorsTree","fireListeners","goog.events.EventTarget.prototype.disposeInternal","goog.events.EventTarget.superClass_.disposeInternal.call","removeAllListeners","count","goog.events.EventTarget.prototype.listen","goog.events.EventTarget.prototype.listenOnce","goog.events.EventTarget.prototype.fireListeners","unlistenByKey","goog.Timer.callOnce","opt_delay","goog.Timer.MAX_TIMEOUT_","goog.Timer.INVALID_TIMEOUT_ID_","goog.Timer.promise","delay","timerKey","opt_result","error","goog.global.clearTimeout","clearTimeout","goog.structs.getValues","col","getValues","goog.structs.getKeys","getKeys","goog.structs.forEach","keys","goog.structs.Map","opt_map","map_","keys_","count_","argLength","addAll","goog.structs.Map.prototype","goog.structs.Map.prototype.getValues","cleanupKeysArray_","goog.structs.Map.prototype.getKeys","clear","goog.structs.Map.prototype.clear","goog.structs.Map.prototype.cleanupKeysArray_","srcIndex","destIndex","goog.structs.Map.hasKey_","seen","goog.structs.Map.prototype.get","opt_val","goog.structs.Map.prototype.set","goog.structs.Map.prototype.forEach","goog.uri.utils.splitRe_","goog.uri.utils.parseQueryData","encodedQuery","pairs","indexOfEquals","decodeURIComponent","goog.Uri","opt_uri","opt_ignoreCase","domain_","userInfo_","scheme_","port_","fragment_","path_","ignoreCase_","m","setScheme","setUserInfo","setDomain","setPort","setPath","setQueryData","queryData_","setFragment","uri","SCHEME","goog.Uri.decodeOrEmpty_","USER_INFO","DOMAIN","PORT","PATH","QUERY_DATA","FRAGMENT","goog.Uri.QueryData","goog.Uri.prototype.toString","out","scheme","getScheme","goog.Uri.encodeSpecialChars_","goog.Uri.reDisallowedInSchemeOrUserInfo_","domain","getDomain","userInfo","getUserInfo","doubleEncodedString","port","getPort","path","getPath","hasDomain","goog.Uri.reDisallowedInAbsolutePath_","goog.Uri.reDisallowedInRelativePath_","query","getEncodedQuery","fragment","getFragment","goog.Uri.reDisallowedInFragment_","goog.Uri.prototype.resolve","relativeUri","absoluteUri","overridden","hasPath","lastSlashIndex","substr","leadingSlash","segments","pos","segment","pop","goog.Uri.prototype.setScheme","newScheme","opt_decode","goog.Uri.prototype.setPort","newPort","isNaN","goog.Uri.prototype.setQueryData","queryData","setIgnoreCase","goog.Uri.reDisallowedInQuery_","goog.Uri.prototype.setParameterValue","goog.Uri.prototype.getParameterValue","paramName","goog.Uri.parse","goog.Uri.create","opt_domain","opt_path","fireauth.iframeclient.SCHEME","opt_preserveReserved","decodeURI","unescapedPart","extra","opt_removeDoubleEncoding","encoded","encodeURI","goog.Uri.encodeChar_","ch","n","charCodeAt","opt_query","keyMap_","encodedQuery_","goog.Uri.QueryData.prototype.ensureKeyMapInitialized_","goog.Uri.QueryData.createFromMap","setValues","goog.Uri.QueryData.prototype","goog.Uri.QueryData.prototype.add","ensureKeyMapInitialized_","invalidateCache_","getKeyName_","goog.Uri.QueryData.prototype.remove","goog.Uri.QueryData.prototype.clear","goog.Uri.QueryData.prototype.containsKey","goog.Uri.QueryData.prototype.forEach","opt_scope","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","param","goog.Uri.QueryData.prototype.clone","goog.Uri.QueryData.prototype.getKeyName_","keyName","goog.Uri.QueryData.prototype.setIgnoreCase","ignoreCase","lowerCase","serializeInternal","serialize","goog.json.Serializer","goog.json.Serializer.prototype.serializeInternal","sep","serializeArray","Boolean","valueOf","serializeString_","serializeObject_","isFinite","goog.json.Serializer.charToJsonCharCache_","goog.json.Serializer.charsToReplace_","goog.json.Serializer.prototype.serializeString_","c","fireauth.util.isLocalStorageNotSynchronized","ua","fireauth.util.getUserAgentString","fireauth.util.getCurrentUrl","fireauth.util.goTo","opt_window","finalUrl","href","fireauth.util.getKeyDiff","a","b","diff","k","fireauth.util.supportsCors","fireauth.util.getBrowserName","browserName","fireauth.util.BrowserName.CHROME","matches","chromeVersion","fireauth.util.isMobileBrowser","opt_userAgent","uaLower","fireauth.util.closeWindow","fireauth.util.popup","opt_url","opt_width","opt_height","opt_name","floor","width","height","top","screen","availHeight","availWidth","fireauth.util.BrowserName.FIREFOX","parentWin","safeLinkRef","linkRef","option","optionString","goog.dom.TagName.A","click","createEvent","initMouseEvent","newWin","sanitizedLinkRef","newDoc","opener","focus","fireauth.util.onPopupClose","repeat","fireauth.util.POPUP_WAIT_CYCLE_MS_","closed","fireauth.util.IP_ADDRESS_REGEXP_","fireauth.util.EMAIL_ADDRESS_REGEXP_","fireauth.util.onDomReady","readyState","LOAD","fireauth.util.checkIfCordova","fireauth.util.isAndroidOrIosCordovaScheme","timeoutId","fireauth.util.CORDOVA_ONDEVICEREADY_TIMEOUT_MS_","fireauth.util.getCurrentScheme","fireauth.util.isIframe","fireauth.util.isWorker","fireauth.util.getEnvironment","firebase","INTERNAL","REACT_NATIVE","NODE","WORKER","BROWSER","fireauth.util.isNativeEnvironment","environment","fireauth.util.generateRandomAlphaNumericString","numOfChars","chars","allowedChars","FIREFOX","CHROME","OPERA","IEMOBILE","IE","EDGE","SILK","BLACKBERRY","WEBOS","ANDROID","re","SAFARI","OTHER","fireauth.util.Framework","DEFAULT","FIREBASEUI","fireauth.util.getClientVersion","clientVersion","opt_frameworkVersion","frameworkVersion","frameworkSet","providedFrameworks","sort","reportedEnvironment","fireauth.util.getObjectRef","varStrName","pieces","last","fireauth.util.isWebStorageSupported","storage","fireauth.util.generateEventId","fireauth.util.isPopupRedirectSupported","fireauth.util.isHttpOrHttps","fireauth.util.runsInBackground","fireauth.util.stringifyJSON","goog.json.serialize","fireauth.util.copyWithoutNullsOrUndefined","trimmedObj","fireauth.util.parseJSON","json","parse","opt_prefix","fireauth.util.iframeCanSyncWebStorage","fireauth.util.resetUnloadedGapiModules","beacon","hint","fireauth.util.Delay","shortDelay","longDelay","shortDelay_","longDelay_","isMobile_","fireauth.util.Delay.prototype.get","min","fireauth.util.Delay.OFFLINE_DELAY_MS_","fireauth.util.isAppVisible","fireauth.util.onAppVisible","onVisibilityChange","fireauth.util.utcTimestampToDateString","utcTimestamp","date","getTime","toUTCString","fireauth.util.isAuthHandlerOrIframe","fireauth.util.getServiceWorkerController","serviceWorker","controller","fireauth.util.getActiveServiceWorker","ready","registration","active","fireauth.deprecation.shownMessages_","fireauth.deprecation.log","console","warn","fireauth.object.readonlyConfigurable_","configurable","enumerable","fireauth.object.setReadonlyProperty","fireauth.object.setReadonlyProperties","props","fireauth.object.makeReadonlyCopy","output","fireauth.object.makeWritableCopy","fireauth.object.hasNonEmptyFields","opt_fields","field","fireauth.object.unsafeCreateReadOnlyCopy","copy","fireauth.MultiFactorInfo","resp","factorId","fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO","PHONE","fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID","fireauth.MultiFactorInfo.MfaEnrollmentField.DISPLAY_NAME","enrollmentTime","fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT","fireauth.MultiFactorInfo.prototype.toPlainObject","fireauth.MultiFactorInfo.fromServerResponse","multiFactorInfo","fireauth.PhoneMultiFactorInfo","DISPLAY_NAME","ENROLLED_AT","MFA_ENROLLMENT_ID","PHONE_INFO","fireauth.MultiFactorInfo.call","fireauth.PhoneMultiFactorInfo.base","fireauth.PhoneMultiFactorInfo.prototype.toPlainObject","fireauth.PhoneMultiFactorInfo.superClass_.toPlainObject.call","base","fireauth.PhoneMultiFactorInfo.prototype.toPlainObject.base","fireauth.ActionCodeInfo","email","fireauth.ActionCodeInfo.ServerFieldName.EMAIL","newEmail","fireauth.ActionCodeInfo.ServerFieldName.NEW_EMAIL","operation","fireauth.ActionCodeInfo.ServerFieldName.REQUEST_TYPE","mfaInfo","fireauth.ActionCodeInfo.ServerFieldName.MFA_INFO","fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN","fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL","fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION","fireauth.ActionCodeInfo.DataField.FROM_EMAIL","fireauth.ActionCodeInfo.DataField.PREVIOUS_EMAIL","fireauth.ActionCodeInfo.DataField.EMAIL","fireauth.ActionCodeInfo.DataField.MULTI_FACTOR_INFO","fireauth.ActionCodeInfo.PropertyName.OPERATION","fireauth.ActionCodeInfo.PropertyName.DATA","REVERT_SECOND_FACTOR_ADDITION","EMAIL_SIGNIN","VERIFY_AND_CHANGE_EMAIL","EMAIL","MFA_INFO","NEW_EMAIL","REQUEST_TYPE","FROM_EMAIL","MULTI_FACTOR_INFO","PREVIOUS_EMAIL","DATA","OPERATION","fireauth.ActionCodeURL","actionLink","apiKey","getParameterValue","fireauth.ActionCodeURL.QueryField.API_KEY","fireauth.ActionCodeURL.QueryField.CODE","mode","fireauth.ActionCodeURL.QueryField.MODE","fireauth.ActionCodeURL.ModeToOperationMap_","fireauth.ActionCodeURL.QueryField.CONTINUE_URL","fireauth.ActionCodeURL.QueryField.LANGUAGE_CODE","fireauth.ActionCodeURL.QueryField.TENANT_ID","API_KEY","CODE","CONTINUE_URL","LANGUAGE_CODE","MODE","TENANT_ID","RECOVER_EMAIL","PASSWORD_RESET","VERIFY_EMAIL","fireauth.ActionCodeURL.parseLink","fireauth.ActionCodeSettings","settingsObj","continueUrl","fireauth.ActionCodeSettings.RawField.URL","initialize_","continueUrl_","amv_","apn_","installApp_","androidSettings","fireauth.ActionCodeSettings.RawField.ANDROID","apn","fireauth.ActionCodeSettings.AndroidRawField.PACKAGE_NAME","installApp","fireauth.ActionCodeSettings.AndroidRawField.INSTALL_APP","amv","fireauth.ActionCodeSettings.AndroidRawField.MINIMUM_VERSION","ibi_","iosSettings","fireauth.ActionCodeSettings.RawField.IOS","ibi","fireauth.ActionCodeSettings.IosRawField.BUNDLE_ID","canHandleCodeInApp","fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP","canHandleCodeInApp_","dynamicLinkDomain","fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN","dynamicLinkDomain_","DYNAMIC_LINK_DOMAIN","HANDLE_CODE_IN_APP","IOS","URL","INSTALL_APP","MINIMUM_VERSION","PACKAGE_NAME","BUNDLE_ID","fireauth.ActionCodeSettings.prototype.buildRequest","request","goog.crypt.byteArrayToHex","array","numByte","hexByte","goog.crypt.base64.charToByteMap_","goog.crypt.base64.decodeString","input","goog.crypt.base64.decodeStringInternal_","pushByte","fromCharCode","getByte","default_val","nextCharIndex","goog.crypt.base64.init_","byte1","byte2","byte3","byte4","commonChars","specialChars","char","existingByte","fireauth.IdToken","tokenString","token","fireauth.IdToken.parseIdTokenClaims","jwt_","exp_","localId_","providerId_","tenantId_","anonymous_","getTenantId","fireauth.IdToken.prototype.getTenantId","isAnonymous","fireauth.IdToken.prototype.isAnonymous","fireauth.IdToken.prototype.toString","fireauth.IdToken.parse","fields","jsonInfo","padLen","fireauth.idp.RESERVED_OAUTH1_PARAMS","fireauth.idp.RESERVED_OAUTH2_PARAMS","fireauth.idp.Settings","FACEBOOK","languageParam","popupWidth","popupHeight","providerId","reservedOAuthParameters","GITHUB","GOOGLE","TWITTER","APPLE","fireauth.idp.getIdpSettings","fireauth.AdditionalUserInfo.fromPlainObject","factory","fireauth.FacebookAdditionalUserInfo","fireauth.GoogleAdditionalUserInfo","fireauth.GithubAdditionalUserInfo","fireauth.TwitterAdditionalUserInfo","fireauth.AdditionalUserInfo.VerifyAssertionField.PROVIDER_ID","fireauth.FederatedAdditionalUserInfo","fireauth.AdditionalUserInfo.VerifyAssertionField.ID_TOKEN","fireauth.GenericAdditionalUserInfo","ID_TOKEN","PROVIDER_ID","info","idToken","ANONYMOUS","CUSTOM","isNewUser","fireauth.GenericAdditionalUserInfo.call","fireauth.FederatedAdditionalUserInfo.base","profile","fireauth.FederatedAdditionalUserInfo.call","fireauth.FacebookAdditionalUserInfo.base","fireauth.GithubAdditionalUserInfo.base","fireauth.GoogleAdditionalUserInfo.base","fireauth.TwitterAdditionalUserInfo.base","fireauth.DynamicLink.parseDeepLink","link","doubleDeepLink","iOSdeepLink","iOSDoubledeepLink","fireauth.MultiFactorSession","mfaPendingCredential","idToken_","mfaPendingCredential_","fireauth.MultiFactorSession.Type.ENROLL","fireauth.MultiFactorSession.Type.SIGN_IN","ENROLL","SIGN_IN","getRawSession","fireauth.MultiFactorSession.prototype.getRawSession","fireauth.MultiFactorSession.prototype.toPlainObject","fireauth.AuthCredential","getIdTokenProvider","fireauth.AuthCredential.prototype.getIdTokenProvider","linkToIdToken","fireauth.AuthCredential.prototype.linkToIdToken","matchIdTokenWithUid","fireauth.AuthCredential.prototype.matchIdTokenWithUid","fireauth.AuthCredential.prototype.toPlainObject","fireauth.AuthCredential.verifyTokenResponseUid","idTokenResolver","fireauth.RpcHandler.AuthServerField.ID_TOKEN","parsedIdToken","fireauth.SAMLAuthCredential","pendingToken","pendingToken_","fireauth.SAMLAuthCredential.prototype.getIdTokenProvider","rpcHandler","verifyAssertion","makeVerifyAssertionRequest_","fireauth.SAMLAuthCredential.prototype.linkToIdToken","verifyAssertionForLinking","fireauth.SAMLAuthCredential.prototype.matchIdTokenWithUid","verifyAssertionForExisting","fireauth.SAMLAuthCredential.prototype.makeVerifyAssertionRequest_","fireauth.SAMLAuthCredential.prototype.toPlainObject","fireauth.SAMLAuthCredential.fromJSON","fireauth.constants.SAML_PREFIX","fireauth.OAuthCredential","oauthResponse","signInMethod","fireauth.OAuthCredential.prototype.getIdTokenProvider","fireauth.OAuthCredential.prototype.linkToIdToken","fireauth.OAuthCredential.prototype.matchIdTokenWithUid","fireauth.OAuthCredential.prototype.makeVerifyAssertionRequest_","postBody","fireauth.OAuthCredential.prototype.toPlainObject","fireauth.OAuthCredential.fromJSON","fireauth.FederatedProvider","opt_reservedParams","reservedParams_","customParameters_","languageParameter","defaultLanguageCode","setCustomParameters","fireauth.FederatedProvider.prototype.setCustomParameters","customParameters","fireauth.SAMLAuthProvider","fireauth.FederatedProvider.call","fireauth.SAMLAuthProvider.base","fireauth.OAuthProvider","fireauth.OAuthProvider.base","scopes_","addScope","fireauth.OAuthProvider.prototype.addScope","getScopes","fireauth.OAuthProvider.prototype.getScopes","credential","fireauth.OAuthProvider.prototype.credential","optionsOrIdToken","opt_accessToken","fireauth.FacebookAuthProvider","fireauth.OAuthProvider.call","fireauth.FacebookAuthProvider.base","fireauth.FacebookAuthProvider.credential","accessTokenOrObject","accessToken","fireauth.GithubAuthProvider","fireauth.GithubAuthProvider.base","fireauth.GithubAuthProvider.credential","fireauth.GoogleAuthProvider","fireauth.GoogleAuthProvider.base","fireauth.GoogleAuthProvider.credential","idTokenOrObject","fireauth.TwitterAuthProvider","fireauth.TwitterAuthProvider.base","fireauth.TwitterAuthProvider.credential","tokenOrObject","secret","tokenObject","fireauth.EmailAuthCredential","password","opt_signInMethod","email_","password_","PASSWORD","fireauth.EmailAuthProvider","fireauth.EmailAuthCredential.prototype.getIdTokenProvider","invokeRpc","fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN","fireauth.RpcHandler.ApiMethod.VERIFY_PASSWORD","fireauth.EmailAuthCredential.prototype.linkToIdToken","fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN_FOR_LINKING","fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO_SENSITIVE","fireauth.EmailAuthCredential.prototype.matchIdTokenWithUid","fireauth.EmailAuthCredential.prototype.toPlainObject","fireauth.EmailAuthCredential.fromJSON","fireauth.EmailAuthProvider.credentialWithLink","emailLink","actionCodeUrl","fireauth.EmailAuthProvider.getActionCodeUrlFromSignInEmailLink","EMAIL_LINK","EMAIL_PASSWORD","fireauth.PhoneAuthCredential","params","verificationId","verificationCode","temporaryProof","phoneNumber","params_","fireauth.PhoneAuthCredential.prototype.getIdTokenProvider","verifyPhoneNumber","makeVerifyPhoneNumberRequest_","fireauth.PhoneAuthCredential.prototype.linkToIdToken","fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER_FOR_LINKING","fireauth.PhoneAuthCredential.prototype.matchIdTokenWithUid","fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER_FOR_EXISTING","fireauth.PhoneAuthCredential.prototype.toPlainObject","fireauth.PhoneAuthCredential.fromJSON","allowedKeys","fireauth.PhoneAuthCredential.prototype.makeVerifyPhoneNumberRequest_","fireauth.PhoneAuthProvider","opt_auth","auth_","fireauth.PhoneAuthProvider.prototype.verifyPhoneNumber","phoneInfoOptions","applicationVerifier","rpcHandler_","assertion","session","verifyPromise","rawSession","startPhoneMfaEnrollment","startPhoneMfaSignIn","sendVerificationCode","fireauth.PhoneAuthProvider.credential","fireauth.AuthProvider.getCredentialFromResponse","accessTokenSecret","rawNonce","fireauth.AuthProvider.checkIfOAuthSupported","provider","fireauth.AuthEvent","opt_eventId","opt_urlResponse","opt_sessionId","opt_error","opt_postBody","opt_tenantId","type_","eventId_","urlResponse_","sessionId_","postBody_","error_","getUid","fireauth.AuthEvent.prototype.getUid","components","fireauth.AuthEvent.prototype.getTenantId","fireauth.AuthEvent.prototype.toPlainObject","fireauth.AuthEvent.fromPlainObject","rawResponse","fireauth.UniversalLinkSubscriber","masterCb_","cb_","fireauth.UniversalLinkSubscriber.instance_","fireauth.UniversalLinkSubscriber.prototype.subscribe","this.masterCb_","event","subscribe","fireauth.InvalidOriginError","fireauth.InvalidOriginError.CHROME_EXTENSION_MESSAGE_TEMPLATE_","fireauth.InvalidOriginError.HTTP_MESSAGE_TEMPLATE_","fireauth.AuthError.call","fireauth.InvalidOriginError.base","fireauth.AuthErrorWithCredential","opt_credentialInfo","fireauth.AuthErrorWithCredential.base","credentialInfo","tenantId","fireauth.AuthErrorWithCredential.prototype.toPlainObject","fireauth.AuthErrorWithCredential.prototype.toJSON","fireauth.AuthErrorWithCredential.fromPlainObject","goog.net.XmlHttpFactory","cachedOptions_","goog.net.XmlHttpFactory.prototype.getOptions","internalGetOptions","goog.net.DefaultXmlHttpFactory","createInstance","goog.net.DefaultXmlHttpFactory.prototype.createInstance","progId","getProgId_","ActiveXObject","XMLHttpRequest","goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions","USE_NULL_FUNCTION","LOCAL_REQUEST_ERROR","goog.net.DefaultXmlHttpFactory.prototype.getProgId_","ieProgId_","ACTIVE_X_IDENTS","candidate","goog.net.XmlHttp.factory_","goog.net.CorsXmlHttpFactory","goog.net.CorsXmlHttpFactory.prototype.createInstance","xhr","XDomainRequest","goog.net.IeCorsXhrAdapter","goog.net.CorsXmlHttpFactory.prototype.internalGetOptions","xdr_","UNINITIALIZED","onreadystatechange","responseType","responseText","status","statusText","onload","handleLoad_","onerror","handleError_","onprogress","handleProgress_","ontimeout","handleTimeout_","goog.net.IeCorsXhrAdapter.prototype","goog.net.IeCorsXhrAdapter.prototype.open","method","opt_async","send","goog.net.IeCorsXhrAdapter.prototype.send","abort","goog.net.IeCorsXhrAdapter.prototype.abort","setRequestHeader","goog.net.IeCorsXhrAdapter.prototype.setRequestHeader","getResponseHeader","goog.net.IeCorsXhrAdapter.prototype.getResponseHeader","goog.net.IeCorsXhrAdapter.prototype.handleLoad_","OK","setReadyState_","COMPLETE","goog.net.IeCorsXhrAdapter.prototype.handleError_","INTERNAL_SERVER_ERROR","goog.net.IeCorsXhrAdapter.prototype.handleTimeout_","goog.net.IeCorsXhrAdapter.prototype.handleProgress_","LOADING","goog.net.IeCorsXhrAdapter.prototype.setReadyState_","getAllResponseHeaders","goog.net.IeCorsXhrAdapter.prototype.getAllResponseHeaders","goog.debug.LogRecord","level","msg","loggerName","opt_time","opt_sequenceNumber","exception_","goog.debug.LogRecord.nextSequenceNumber_","goog.debug.LogRecord.prototype.reset","goog.debug.Logger","name_","children_","level_","goog.debug.Logger.Level","goog.debug.Logger.Level.prototype.toString","goog.debug.Logger.Level.SEVERE","goog.debug.Logger.Level.WARNING","goog.debug.Logger.Level.CONFIG","goog.debug.Logger.Level.FINE","goog.debug.Logger.prototype.getEffectiveLevel","getEffectiveLevel","log","goog.debug.Logger.prototype.log","opt_exception","isLoggable","logRecord","doLogRecord_","goog.debug.LogManager.loggers_","goog.debug.LogManager.rootLogger_","goog.debug.LogManager.getLogger","goog.debug.Logger.ROOT_LOGGER_NAME","goog.debug.LogManager.rootLogger_.setLevel","ret","logger","lastDotIndex","leafName","parentLogger","parentName","goog.log.fine","goog.net.FetchXmlHttpFactory","worker","worker_","goog.net.FetchXmlHttpFactory.prototype.createInstance","instance","goog.net.FetchXmlHttp","goog.functions.constant","retValue","goog.events.EventTarget.call","goog.net.FetchXmlHttp.base","goog.net.FetchXmlHttp.RequestState.UNSENT","requestHeaders_","Headers","responseHeaders_","method_","url_","inProgress_","logger_","textDecoder_","currentReader_","fetchResponse_","UNSENT","goog.net.FetchXmlHttp.prototype","goog.net.FetchXmlHttp.prototype.open","OPENED","dispatchCallback_","goog.net.FetchXmlHttp.prototype.send","opt_data","requestInit","headers","credentials","cache","fetch","Request","handleResponse_","handleSendFailure_","goog.net.FetchXmlHttp.prototype.abort","DONE","requestDone_","goog.net.FetchXmlHttp.prototype.handleResponse_","HEADER_RECEIVED","arrayBuffer","handleResponseArrayBuffer_","goog.global.ReadableStream","ReadableStream","body","getReader","TextDecoder","readInputFromFetch_","text","handleResponseText_","goog.net.FetchXmlHttp.prototype.readInputFromFetch_","read","handleDataFromStream_","catch","goog.net.FetchXmlHttp.prototype.handleDataFromStream_","newText","decode","dataPacket","Uint8Array","stream","done","goog.net.FetchXmlHttp.prototype.handleResponseText_","goog.net.FetchXmlHttp.prototype.handleResponseArrayBuffer_","responseArrayBuffer","goog.net.FetchXmlHttp.prototype.handleSendFailure_","goog.net.FetchXmlHttp.prototype.requestDone_","setStatus","goog.net.FetchXmlHttp.prototype.setRequestHeader","header","append","goog.net.FetchXmlHttp.prototype.getResponseHeader","goog.net.FetchXmlHttp.prototype.getAllResponseHeaders","lines","iter","entries","pair","goog.net.FetchXmlHttp.prototype.dispatchCallback_","goog.net.XhrIo","opt_xmlHttpFactory","goog.net.XhrIo.base","xmlHttpFactory_","active_","xhrOptions_","xhr_","lastError_","lastMethod_","lastUri_","inAbort_","inOpen_","inSend_","errorDispatched_","timeoutInterval_","timeoutId_","responseType_","goog.net.XhrIo.ResponseType.DEFAULT","useXhr2Timeout_","withCredentials_","goog.net.XhrIo.HTTP_SCHEME_PATTERN","goog.net.XhrIo.METHODS_WITH_FORM_DATA","goog.net.XhrIo.prototype.send","opt_method","opt_headers","toUpperCase","createXhr","goog.net.XmlHttp.factory_.createInstance","getOptions","goog.net.XmlHttp.factory_.getOptions","onReadyStateChange_","formatMsg_","content","contentTypeKey","contentIsFormData","goog.net.XhrIo.CONTENT_TYPE_HEADER","goog.net.XhrIo.FORM_CONTENT_TYPE","withCredentials","cleanUpTimeoutTimer_","goog.net.XhrIo.shouldUseXhr2Timeout_","timeout_","goog.net.XhrIo.prototype","goog.net.XhrIo.prototype.timeout_","goog.net.XhrIo.prototype.error_","dispatchErrors_","cleanUpXhr_","goog.net.XhrIo.prototype.dispatchErrors_","ERROR","goog.net.XhrIo.prototype.abort","ABORT","goog.net.XhrIo.prototype.disposeInternal","goog.net.XhrIo.superClass_.disposeInternal.call","goog.net.XhrIo.prototype.disposeInternal.base","goog.net.XhrIo.prototype.onReadyStateChange_","isDisposed","onReadyStateChangeHelper_","onReadyStateChangeEntryPoint_","goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_","goog.net.XhrIo.prototype.onReadyStateChangeHelper_","getReadyState","getStatus","READY_STATE_CHANGE","isComplete","isSuccess","CREATED","ACCEPTED","NO_CONTENT","PARTIAL_CONTENT","NOT_MODIFIED","QUIRK_IE_NO_CONTENT","goog.global.self","goog.global.self.location","goog.global.self.location.protocol","goog.net.XhrIo.HTTP_SCHEME_PATTERN.test","SUCCESS","LOADED","getStatusText","goog.net.XhrIo.prototype.cleanUpXhr_","opt_fromDispose","clearedOnReadyStateChange","READY","goog.net.XhrIo.prototype.cleanUpTimeoutTimer_","goog.net.XhrIo.prototype.getReadyState","goog.net.XhrIo.prototype.getStatus","goog.net.XhrIo.prototype.getResponseText","getResponse","goog.net.XhrIo.prototype.getResponse","TEXT","ARRAY_BUFFER","mozResponseArrayBuffer","goog.net.XhrIo.prototype.formatMsg_","goog.async.Deferred","opt_defaultScope","opt_onCancelFunction","goog.net.jsloader.cancel_","sequence_","onCancelFunction_","defaultScope_","hadError_","fired_","silentlyCanceled_","blocking_","blocked_","unhandledErrorId_","branches_","goog.async.Deferred.prototype.cancel","opt_deepCancel","hasFired","goog.async.Deferred.CanceledError","check_","errback","updateResult_","continue_","goog.async.Deferred.prototype.continue_","goog.async.Deferred.prototype.updateResult_","fire_","goog.async.Deferred.prototype.check_","goog.async.Deferred.AlreadyCalledError","goog.async.Deferred.prototype.addErrback","eb","addCallbacks","goog.async.Deferred.prototype.addCallbacks","goog.async.Deferred.prototype.then","rej","goog.async.Deferred.prototype.hasErrback_","sequenceRow","goog.async.Deferred.prototype.fire_","hasErrback_","goog.async.Deferred.errorMap_","id_","isNewlyBlocked","unhandledException","sequenceEntry","onCallback","onErrback","deferredError","goog.async.Deferred.Error_","throwError","goog.async.Deferred.Error_.prototype.throwError","goog.net.jsloader.safeLoad","trustedUri","goog.dom.TagName.SCRIPT","script_","deferred","timeout","timeoutDuration","goog.net.jsloader.DEFAULT_TIMEOUT","goog.net.jsloader.cleanup_","goog.net.jsloader.Error","goog.net.jsloader.ErrorCode.TIMEOUT","script.onreadystatechange","cleanupWhenDone","script.onerror","goog.net.jsloader.ErrorCode.LOAD_ERROR","goog.net.jsloader.getScriptParentElement_","scriptParent","headElements","getElementsByTagName","scriptNode","removeScriptNode","opt_timeout","removeChild","LOAD_ERROR","goog.net.jsloader.Error.base","fireauth.XmlHttpFactory","xmlHttpRequest","xmlHttpRequest_","fireauth.XmlHttpFactory.prototype.createInstance","fireauth.XmlHttpFactory.prototype.internalGetOptions","fireauth.RpcHandler","opt_config","opt_firebaseClientVersion","apiKey_","config","secureTokenEndpoint_","fireauth.RpcHandler.SECURE_TOKEN_ENDPOINT_","secureTokenTimeout_","fireauth.RpcHandler.DEFAULT_SECURE_TOKEN_TIMEOUT_","secureTokenHeaders_","fireauth.RpcHandler.DEFAULT_SECURE_TOKEN_HEADERS_","firebaseEndpoint_","fireauth.RpcHandler.FIREBASE_ENDPOINT_","identityPlatformEndpoint_","fireauth.RpcHandler.IDENTITY_PLATFORM_ENDPOINT_","firebaseTimeout_","fireauth.RpcHandler.DEFAULT_FIREBASE_TIMEOUT_","firebaseHeaders_","fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_","isNode","rpcHandlerXhrFactory_","fireauth.RpcHandler.prototype.updateCustomLocaleHeader","languageCode","fireauth.RpcHandler.FIREBASE_LOCALE_KEY_","fireauth.RpcHandler.prototype.updateClientVersion","fireauth.RpcHandler.prototype.getTenantId","fireauth.RpcHandler.prototype.sendXhr_","opt_callback","opt_httpMethod","sendXhr","sendXhrUsingXhrIo_","fireauth.RpcHandler.loadGApi_","fireauth.RpcHandler.loadGApiJs_","sendXhrUsingGApiClient_","fireauth.RpcHandler.prototype.sendXhrUsingXhrIo_","xhrIo","requestTimeout","getResponseText","dispose","fireauth.RpcHandler.GAPI_SRC_","fireauth.RpcHandler.GAPI_CALLBACK_NAME_","addErrback","fireauth.RpcHandler.prototype.sendXhrUsingGApiClient_","fireauth.RpcHandler.loadGApi_.then","oauth2Token","fireauth.RpcHandler.prototype.requestStsToken","sendXhr_","fireauth.RpcHandler.getDeveloperError_","POST","fireauth.RpcHandler.prototype.requestAuthEndpoint_","httpMethod","opt_customErrorMap","opt_cachebuster","setParameterValue","getApiKey","isGet","GET","fireauth.RpcHandler.validateRequestHasEmail_","fireauth.util.EMAIL_ADDRESS_REGEXP_.test","fireauth.RpcHandler.validateEmailIfPresent_","fireauth.RpcHandler.prototype.fetchSignInMethodsForIdentifier","identifier","fireauth.RpcHandler.ApiMethod.CREATE_AUTH_URI","continueUri","fireauth.RpcHandler.prototype.getAuthorizedDomains","fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG","fireauth.RpcHandler.validateIdTokenResponse_","fireauth.RpcHandler.validateVerifyPhoneNumberRequest_","signInAnonymously","fireauth.RpcHandler.prototype.signInAnonymously","fireauth.RpcHandler.ApiMethod.SIGN_IN_ANONYMOUSLY","updateEmail","fireauth.RpcHandler.prototype.updateEmail","fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO","updatePassword","fireauth.RpcHandler.prototype.updatePassword","newPassword","fireauth.RpcHandler.PROFILE_FIELD_TO_ENUM_NAME_","fireauth.RpcHandler.prototype","updateProfile","fireauth.RpcHandler.prototype.updateProfile","profileData","fieldsToDelete","enumName","fieldName","fieldValue","sendPasswordResetEmail","fireauth.RpcHandler.prototype.sendPasswordResetEmail","additionalRequestData","fireauth.RpcHandler.ApiMethod.GET_OOB_CODE","sendSignInLinkToEmail","fireauth.RpcHandler.prototype.sendSignInLinkToEmail","fireauth.RpcHandler.ApiMethod.GET_EMAIL_SIGNIN_CODE","sendEmailVerification","fireauth.RpcHandler.prototype.sendEmailVerification","fireauth.RpcHandler.ApiMethod.GET_EMAIL_VERIFICATION_CODE","verifyBeforeUpdateEmail","fireauth.RpcHandler.prototype.verifyBeforeUpdateEmail","fireauth.RpcHandler.ApiMethod.GET_EMAIL_VERIFICATION_CODE_BEFORE_UPDATE","fireauth.RpcHandler.prototype.sendVerificationCode","fireauth.RpcHandler.ApiMethod.SEND_VERIFICATION_CODE","fireauth.RpcHandler.prototype.verifyPhoneNumber","fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER","fireauth.RpcHandler.prototype.startPhoneMfaEnrollment","fireauth.RpcHandler.ApiMethod.START_PHONE_MFA_ENROLLMENT","fireauth.RpcHandler.validateFinalizePhoneMfaRequest_","fireauth.RpcHandler.prototype.startPhoneMfaSignIn","fireauth.RpcHandler.ApiMethod.START_PHONE_MFA_SIGN_IN","fireauth.RpcHandler.prototype.deleteLinkedAccounts","providersToDelete","fireauth.RpcHandler.ApiMethod.DELETE_LINKED_ACCOUNTS","fireauth.RpcHandler.validateVerifyAssertionRequest_","fireauth.RpcHandler.processVerifyAssertionResponse_","fireauth.constants.OIDC_PREFIX","NONCE","fireauth.RpcHandler.validateVerifyAssertionResponse_","FEDERATED_USER_ID_ALREADY_LINKED","fireauth.RpcHandler.getDeveloperErrorFromCode_","fireauth.RpcHandler.prototype.verifyAssertion","fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION","fireauth.RpcHandler.prototype.verifyAssertionForLinking","fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION_FOR_LINKING","fireauth.RpcHandler.prototype.verifyAssertionForExisting","fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION_FOR_EXISTING","fireauth.RpcHandler.validateApplyActionCodeRequest_","confirmPasswordReset","fireauth.RpcHandler.prototype.confirmPasswordReset","fireauth.RpcHandler.ApiMethod.RESET_PASSWORD","checkActionCode","fireauth.RpcHandler.prototype.checkActionCode","fireauth.RpcHandler.ApiMethod.CHECK_ACTION_CODE","applyActionCode","fireauth.RpcHandler.prototype.applyActionCode","fireauth.RpcHandler.ApiMethod.APPLY_OOB_CODE","APPLY_OOB_CODE","requestValidator","responseField","requireTenantId","CHECK_ACTION_CODE","responseValidator","fireauth.RpcHandler.validateCheckActionCodeResponse_","CREATE_ACCOUNT","fireauth.RpcHandler.validateCreateAccountRequest_","returnSecureToken","CREATE_AUTH_URI","DELETE_ACCOUNT","requestRequiredFields","DELETE_LINKED_ACCOUNTS","fireauth.RpcHandler.validateDeleteLinkedAccountsRequest_","EMAIL_LINK_SIGNIN","EMAIL_LINK_SIGNIN_FOR_LINKING","FINALIZE_PHONE_MFA_ENROLLMENT","useIdentityPlatformEndpoint","FINALIZE_PHONE_MFA_SIGN_IN","GET_ACCOUNT_INFO","GET_EMAIL_SIGNIN_CODE","fireauth.RpcHandler.validateEmailSignInCodeRequest_","GET_EMAIL_VERIFICATION_CODE","fireauth.RpcHandler.validateEmailVerificationCodeRequest_","GET_EMAIL_VERIFICATION_CODE_BEFORE_UPDATE","fireauth.RpcHandler.validateEmailVerificationCodeBeforeUpdateRequest_","GET_OOB_CODE","fireauth.RpcHandler.validateOobCodeRequest_","GET_PROJECT_CONFIG","cachebuster","GET_RECAPTCHA_PARAM","fireauth.RpcHandler.validateGetRecaptchaParamResponse_","RESET_PASSWORD","SEND_VERIFICATION_CODE","SESSION_INFO","SET_ACCOUNT_INFO","SET_ACCOUNT_INFO_SENSITIVE","fireauth.RpcHandler.validateSetAccountInfoSensitive_","SIGN_IN_ANONYMOUSLY","START_PHONE_MFA_ENROLLMENT","fireauth.RpcHandler.validateStartPhoneMfaEnrollmentRequest_","fireauth.RpcHandler.validateStartPhoneMfaEnrollmentResponse_","START_PHONE_MFA_SIGN_IN","fireauth.RpcHandler.validateStartPhoneMfaSignInRequest_","fireauth.RpcHandler.validateStartPhoneMfaSignInResponse_","VERIFY_ASSERTION","responsePreprocessor","VERIFY_ASSERTION_FOR_EXISTING","fireauth.RpcHandler.validateVerifyAssertionForExistingResponse_","USER_NOT_FOUND","VERIFY_ASSERTION_FOR_LINKING","fireauth.RpcHandler.validateVerifyAssertionLinkRequest_","VERIFY_CUSTOM_TOKEN","fireauth.RpcHandler.validateVerifyCustomTokenRequest_","VERIFY_PASSWORD","fireauth.RpcHandler.validateVerifyPasswordRequest_","VERIFY_PHONE_NUMBER","VERIFY_PHONE_NUMBER_FOR_LINKING","fireauth.RpcHandler.validateVerifyPhoneNumberLinkRequest_","fireauth.RpcHandler.validateVerifyPhoneNumberForLinkingResponse_","VERIFY_PHONE_NUMBER_FOR_EXISTING","customErrorMap","fireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_","WITHDRAW_MFA","fireauth.RpcHandler.validateWithdrawMfaResponse_","hasIdToken","hasRefreshToken","fireauth.RpcHandler.prototype.invokeRpc","requestAuthEndpoint_","tempResponse","serverErrorCode","errorReasonMap","apiaryError","errorMap","MISSING_CUSTOM_TOKEN","INVALID_IDENTIFIER","MISSING_PASSWORD","PASSWORD_LOGIN_DISABLED","INVALID_PENDING_TOKEN","EMAIL_NOT_FOUND","RESET_PASSWORD_EXCEED_LIMIT","MISSING_OOB_CODE","INVALID_ID_TOKEN","INVALID_TEMPORARY_PROOF","SESSION_EXPIRED","prefixCode","errorMessage","fireauth.iframeclient.IframeWrapper","iframe_","onIframeOpen_","open_","fireauth.iframeclient.IframeWrapper.prototype.open_","fireauth.iframeclient.IframeWrapper.loadGApiJs_","onOpen","clearTimerAndResolve","networkErrorTimer","restyle","fireauth.iframeclient.IframeWrapper.PING_TIMEOUT_.get","ping","fireauth.iframeclient.IframeWrapper.prototype.sendMessage","fireauth.iframeclient.IframeWrapper.prototype.registerEvent","register","AUTH_EVENT","fireauth.iframeclient.IframeWrapper.GAPI_LOADER_SRC_","fireauth.iframeclient.IframeWrapper.NETWORK_TIMEOUT_","fireauth.iframeclient.IframeWrapper.PING_TIMEOUT_","fireauth.iframeclient.IframeWrapper.cachedGApiLoader_","onGapiLoad","loader","fireauth.iframeclient.IframeWrapper.NETWORK_TIMEOUT_.get","cbName","fireauth.iframeclient.IframeUrlBuilder","authDomain","appName","authDomain_","appName_","v_","uri_","endpointId_","frameworks_","fireauth.iframeclient.IframeUrlBuilder.prototype.toString","fireauth.iframeclient.OAuthUrlBuilder","authType","authType_","redirectUrl_","provider_","setTenantId","fireauth.iframeclient.OAuthUrlBuilder.prototype.setTenantId","fireauth.iframeclient.OAuthUrlBuilder.prototype.toString","getAuthLanguage_","getLanguageCode","scopes","additionalParams_","frameworks","fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_","getAuthFrameworks_","getFramework","fireauth.iframeclient.IfcHandler","opt_clientVersion","opt_endpointId","clientVersion_","iframeUrl_","fullClientVersion_","authEventListeners_","isInitialized_","originValidator_","fireauth.iframeclient.IfcHandler.getOriginValidator_","getAuthorizedDomains","authorizedDomains","domainPattern","chromeExtUri","fireauth.util.IP_ADDRESS_REGEXP_.test","escapedDomainPattern","RegExp","fireauth.iframeclient.IfcHandler.prototype.initialize","builder","setEndpointId","opt_frameworks","iframeWrapper_","registerEvents_","fireauth.iframeclient.IfcHandler.prototype","fireauth_CordovaHandler_prototype$startPopupTimeout","fireauth.iframeclient.IfcHandler.prototype.startPopupTimeout","popupWin","onError","popupClosedByUserError","webStorageNotSupportedError","isResolved","initializeAndWait","isWebStorageSupported","isSupported","shouldBeInitializedEarly","fireauth.iframeclient.IfcHandler.prototype.shouldBeInitializedEarly","hasVolatileStorage","fireauth.iframeclient.IfcHandler.prototype.hasVolatileStorage","fireauth_CordovaHandler_prototype$processPopup","fireauth.iframeclient.IfcHandler.prototype.processPopup","onInitialize","opt_alreadyRedirected","getRpcHandler_","onReady","oauthHelperWidgetUrl","fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl","fireauth.iframeclient.IfcHandler.prototype.getRpcHandler_","fireauth_CordovaHandler_prototype$processRedirect","fireauth.iframeclient.IfcHandler.prototype.processRedirect","fireauth.iframeclient.IfcHandler.prototype.initializeAndWait","initialize","unloadsOnRedirect","fireauth.iframeclient.IfcHandler.prototype.unloadsOnRedirect","opt_redirectUrl","opt_additionalParams","setEventId","fireauth.iframeclient.IfcHandler.prototype.registerEvents_","registerEvent","resolveResponse","isHandled","authEvent","ACK","fireauth.iframeclient.IfcHandler.prototype.isWebStorageSupported","WEB_STORAGE_SUPPORT_EVENT","sendMessage","fireauth_CordovaHandler_prototype$addAuthEventListener","fireauth.iframeclient.IfcHandler.prototype.addAuthEventListener","fireauth_CordovaHandler_prototype$removeAuthEventListener","fireauth.iframeclient.IfcHandler.prototype.removeAuthEventListener","ele","fireauth.storage.AsyncStorage","opt_asyncStorage","storage_","ASYNC_STORAGE","fireauth.storage.AsyncStorage.prototype","fireauth.storage.AsyncStorage.prototype.get","fireauth.storage.AsyncStorage.prototype.set","fireauth_storage_AsyncStorage_prototype$remove","fireauth.storage.AsyncStorage.prototype.remove","addStorageListener","fireauth.storage.AsyncStorage.prototype.addStorageListener","removeStorageListener","fireauth.storage.AsyncStorage.prototype.removeStorageListener","fireauth.messagechannel.Receiver","eventTarget","eventTarget_","eventHandlers_","messageEventHandler_","handleEvent_","fireauth.messagechannel.Receiver.receivers_","fireauth.messagechannel.Receiver.getInstance","receiver","fireauth.messagechannel.Receiver.receivers_.push","fireauth.messagechannel.Receiver.prototype.handleEvent_","eventType","eventId","handlers","ports","allResponses","fireauth.messagechannel.Receiver.prototype.subscribe","fireauth.messagechannel.WorkerClientPostMessager","fireauth.messagechannel.WorkerClientPostMessager.prototype.postMessage","transfer","fireauth.messagechannel.Sender","postMessager","postMessager_","closed_","messageHandlers_","fireauth.messagechannel.Sender.prototype.send","opt_useLongTimeout","onMessage","ackTimer","completionTimer","CONNECTION_UNAVAILABLE","ackTimeout","LONG_ACK","messageChannel","MessageChannel","pow","digits","port1","start","UNSUPPORTED_EVENT","COMPLETION","UNKNOWN","INVALID_RESPONSE","port2","removeMessageHandler_","fireauth.messagechannel.Sender.prototype.removeMessageHandler_","messageHandler","fireauth.messagechannel.Sender.prototype.close","fireauth.storage.IndexedDB","fireauth.storage.IndexedDB.isAvailable","localMap_","storageListeners_","pendingOpsTracker_","indexedDB_","goog.global.indexedDB","indexedDB","INDEXEDDB","sender_","receiver_","pollTimerId_","poll_","serviceWorkerReceiverAvailable_","activeServiceWorker_","sync_","sw","fireauth.storage.IndexedDB.prototype.deleteDb_","deleteDatabase","fireauth.storage.IndexedDB.DB_NAME_","onsuccess","request.onsuccess","request.onerror","fireauth.storage.IndexedDB.prototype.initializeDb_","fireauth.storage.IndexedDB.VERSION_","onupgradeneeded","request.onupgradeneeded","db","createObjectStore","fireauth.storage.IndexedDB.DATA_OBJECT_STORE_NAME_","fireauth.storage.IndexedDB.DATA_KEY_PATH_","objectStoreNames","contains","deleteDb_","initializeDb_","newDb","fireauth.storage.IndexedDB.prototype.initializeDbAndRun_","initPromise_","fireauth.storage.IndexedDB.prototype.getDataObjectStore_","tx","objectStore","fireauth.storage.IndexedDB.prototype.getTransaction_","isReadWrite","transaction","fireauth.storage.IndexedDB.prototype.onIDBRequest_","fireauth.storage.IndexedDB.prototype","fireauth.storage.IndexedDB.prototype.set","isLocked","dbTemp","initializeDbAndRun_","getDataObjectStore_","getTransaction_","onIDBRequest_","notifySW_","fireauth.storage.IndexedDB.prototype.notifySW_","fireauth.storage.IndexedDB.prototype.get","fireauth.storage.IndexedDB.prototype.remove","fireauth.storage.IndexedDB.prototype.sync_","openCursor","cursor","centralCopy","diffKeys","fireauth.storage.IndexedDB.prototype.addStorageListener","startListeners_","fireauth.storage.IndexedDB.prototype.removeStorageListener","stopListeners_","fireauth.storage.IndexedDB.prototype.startListeners_","fireauth.storage.IndexedDB.STOP_ERROR_","fireauth.storage.IndexedDB.POLLING_DELAY_","fireauth.storage.IndexedDB.prototype.stopListeners_","fireauth.storage.HybridIndexedDB","fallbackStorage","fallbackStorage_","underlyingStoragePromise_","randomId","randomKey","fireauth.storage.HybridIndexedDB.KEY_","fireauth.storage.IndexedDB.managerInstance_","fireauth.storage.HybridIndexedDB.prototype","fireauth.storage.HybridIndexedDB.prototype.get","fireauth.storage.HybridIndexedDB.prototype.set","fireauth.storage.HybridIndexedDB.prototype.remove","fireauth.storage.HybridIndexedDB.prototype.addStorageListener","fireauth.storage.HybridIndexedDB.prototype.removeStorageListener","fireauth.storage.InMemoryStorage","IN_MEMORY","fireauth.storage.InMemoryStorage.prototype","fireauth.storage.InMemoryStorage.prototype.get","fireauth.storage.InMemoryStorage.prototype.set","fireauth.storage.InMemoryStorage.prototype.remove","fireauth.storage.InMemoryStorage.prototype.addStorageListener","fireauth.storage.InMemoryStorage.prototype.removeStorageListener","fireauth.storage.LocalStorage","fireauth.storage.LocalStorage.isAvailable","fireauth.storage.LocalStorage.getGlobalStorage","LOCAL_STORAGE","setItem","fireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_","removeItem","fireauth.storage.LocalStorage.prototype","fireauth.storage.LocalStorage.prototype.get","getItem","fireauth.storage.LocalStorage.prototype.set","fireauth.storage.LocalStorage.prototype.remove","fireauth.storage.LocalStorage.prototype.addStorageListener","fireauth.storage.LocalStorage.prototype.removeStorageListener","fireauth.storage.NullStorage","NULL_STORAGE","fireauth.storage.NullStorage.prototype","fireauth.storage.NullStorage.prototype.get","fireauth.storage.NullStorage.prototype.set","fireauth.storage.NullStorage.prototype.remove","fireauth.storage.NullStorage.prototype.addStorageListener","fireauth.storage.NullStorage.prototype.removeStorageListener","fireauth.storage.SessionStorage","fireauth.storage.SessionStorage.isAvailable","fireauth.storage.SessionStorage.getGlobalStorage","SESSION_STORAGE","fireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_","fireauth.storage.SessionStorage.prototype","fireauth.storage.SessionStorage.prototype.get","fireauth.storage.SessionStorage.prototype.set","fireauth.storage.SessionStorage.prototype.remove","fireauth.storage.SessionStorage.prototype.addStorageListener","fireauth.storage.SessionStorage.prototype.removeStorageListener","fireauth.storage.Factory","envMap","fireauth.storage.Factory.EnvConfig.BROWSER","fireauth.storage.Factory.EnvConfig.NODE","fireauth.storage.Factory.EnvConfig.REACT_NATIVE","fireauth.storage.Factory.EnvConfig.WORKER","env_","env","persistent","temporary","fireauth.authStorage.Persistence","LOCAL","NONE","SESSION","fireauth.authStorage.validatePersistenceArgument","invalidTypeError","unsupportedTypeError","fireauth.authStorage.Manager","safariLocalStorageNotSynced","runsInBackground","webStorageSupported","safariLocalStorageNotSynced_","runsInBackground_","webStorageSupported_","listeners_","fireauth.storage.Factory.instance_","persistentStorage_","storageFactory","temporaryStorage_","inMemoryStorage_","storageChangeEventHandler_","storageChangeEvent_","fireauth.authStorage.Manager.getInstance","fireauth.authStorage.Manager.instance_","fireauth.authStorage.Manager.prototype.getStorage_","fireauth.authStorage.Manager.prototype.getKeyName_","dataKey","fireauth.authStorage.SEPARATOR_","fireauth.authStorage.Manager.prototype.migrateFromLocalStorage","getStorage_","oldStorageValue","fireauth.authStorage.Manager.prototype","fireauth.authStorage.Manager.prototype.get","fireauth.authStorage.Manager.prototype.remove","fireauth.authStorage.Manager.prototype.set","serializedValue","fireauth.authStorage.Manager.prototype.addListener","startManualListeners_","fireauth.authStorage.Manager.prototype.removeListener","stopManualListeners_","fireauth.authStorage.Manager.prototype.startManualListeners_","manualListenerTimer_","setInterval","currentValue","oldValue","newValue","poll","fireauth.authStorage.Manager.LOCAL_STORAGE_POLLING_TIMER_","fireauth.authStorage.Manager.prototype.stopManualListeners_","clearInterval","fireauth.authStorage.Manager.prototype.storageChangeEvent_","storedValue","realValue","callListeners_","triggerListeners","fireauth.authStorage.IE10_LOCAL_STORAGE_SYNC_DELAY","fireauth.authStorage.Manager.prototype.callListeners_","fireauth.storage.AuthEventManager","appId","appId_","manager_","fireauth.storage.AuthEventManager.prototype.getAuthEvent","fireauth.storage.AuthEventManager.Keys.AUTH_EVENT","fireauth.storage.OAuthHandlerManager","goog.crypt.Hash","blockSize","goog.crypt.Sha2","numHashBlocks","initHashBlocks","goog.crypt.Sha2.BLOCKSIZE_","chunk_","total_","inChunk_","hash_","numHashBlocks_","initHashBlocks_","w_","Int32Array","goog.crypt.Sha2.Kx_","goog.crypt.Sha2.K_","goog.crypt.Sha2.PADDING_","goog.crypt.Sha2.prototype.reset","goog.crypt.Sha2.prototype.computeChunk_","chunk","w","offset","rounds","w_15","w_2","partialSum1","partialSum2","d","g","h","t2","t1","goog.crypt.Sha2.prototype.update","opt_length","inChunk","computeChunk_","goog.crypt.Sha256","goog.crypt.Sha2.call","goog.crypt.Sha256.base","goog.crypt.Sha256.INIT_HASH_BLOCK_","fireauth.CordovaHandler","storageKey_","fireauth.util.STORAGE_KEY_SEPARATOR_","savePartialEventManager_","getAndDeletePartialEventManager_","initialAuthEvent_","inAppBrowserRef_","pendingRedirect_","fireauth.CordovaHandler.getError_","fireauth.CordovaHandler.prototype","fireauth.CordovaHandler.prototype.initializeAndWait","isReady_","appIdentifier","openUrl","openInAppBrowser","fireauth.CordovaHandler.prototype.generateSessionId_","fireauth.CordovaHandler.SESSION_ID_TOTAL_CHARS_","fireauth.CordovaHandler.prototype.computeSecureHash_","sha256","update","digest","totalBits","fireauth.CordovaHandler.prototype.startPopupTimeout","fireauth.CordovaHandler.prototype.processPopup","fireauth.CordovaHandler.prototype.unloadsOnRedirect","fireauth.CordovaHandler.prototype.shouldBeInitializedEarly","fireauth.CordovaHandler.prototype.hasVolatileStorage","fireauth.CordovaHandler.prototype.processRedirect","onClose","authEventCallback","onResume","getInitialAuthEvent_","processRedirectInternal_","closeBrowsertab","addAuthEventListener","fireauth.CordovaHandler.REDIRECT_TIMEOUT_MS_","getPartialStoredEvent_","cleanup","removeAuthEventListener","fireauth.CordovaHandler.prototype.processRedirectInternal_","sessionId","generateSessionId_","appDisplayName","additionalParams","hashedSessionId","computeSecureHash_","isAvailable","fireauth.CordovaHandler.prototype.dispatchEvent_","fireauth.CordovaHandler.prototype.getInitialAuthEvent_","setAuthEventListener_","fireauth.CordovaHandler.prototype.getPartialStoredEvent_","getAuthEvent","fireauth.CordovaHandler.prototype.setAuthEventListener_","universalLinkCb","eventData","initialResolve","noEventTimer","noEvent","callbackUrl","errorObject","dispatchEvent_","fireauth.CordovaHandler.INITIAL_TIMEOUT_MS_","existingHandlerOpenURL","fireauth.CordovaHandler.prototype.addAuthEventListener","fireauth.CordovaHandler.prototype.removeAuthEventListener","fireauth.storage.PendingRedirectManager","fireauth.storage.PendingRedirectManager.PENDING_REDIRECT_KEY_","fireauth.storage.PendingRedirectManager.prototype.setPendingStatus","fireauth.storage.PendingRedirectManager.PENDING_FLAG_","fireauth.storage.PendingRedirectManager.prototype.removePendingStatus","fireauth.storage.PendingRedirectManager.prototype.getPendingStatus","fireauth.AuthEventManager","processedEvents_","lastProcessedEventTime_","subscribedHandlers_","initialized_","authEventHandler_","handleAuthEvent_","redirectAuthEventProcessor_","fireauth.RedirectAuthEventProcessor","popupAuthEventProcessor_","fireauth.PopupAuthEventProcessor","pendingRedirectStorageManager_","fireauth.AuthEventManager.KEY_SEPARATOR_","typeToManager_","oauthSignInHandler_","fireauth.AuthEventManager.instantiateOAuthSignInHandler","fireauth.constants.clientEndpoint","SDK_VERSION","fireauth.AuthEventManager.prototype.reset","fireauth.AuthEventManager.prototype.initialize","previousOauthSignInHandler","fireauth.AuthEventManager.prototype.initializeWithNoPendingRedirectResult_","notSupportedEvent","fireauth.AuthEventManager.isCordovaFalsePositive_","defaultToEmptyResponse","fireauth.AuthEventManager.prototype.subscribe","getPendingStatus","removePendingStatus","initializeWithNoPendingRedirectResult_","fireauth.AuthEventManager.prototype.unsubscribe","fireauth.AuthEventManager.prototype.handleAuthEvent_","fireauth.AuthEventManager.EVENT_DUPLICATION_CACHE_DURATION","hasProcessedAuthEvent_","processed","potentialHandler","canHandleAuthEvent","eventManager","processAuthEvent","saveProcessedAuthEvent_","fireauth.AuthEventManager.POPUP_TIMEOUT_MS_","fireauth.AuthEventManager.REDIRECT_TIMEOUT_MS_","getRedirectResult","fireauth.AuthEventManager.prototype.getRedirectResult","fireauth.AuthEventManager.prototype.processPopup","processPopup","fireauth.AuthEventManager.prototype.processRedirect","setPendingStatus","processRedirect","fireauth.AuthEventManager.prototype.startPopupTimeout","owner","startPopupTimeout","resolvePendingPopupEvent","fireauth.AuthEventManager.POPUP_TIMEOUT_MS_.get","fireauth.AuthEventManager.manager_","fireauth.AuthEventManager.getManager","redirectedUserPromise_","redirectResolve_","redirectReject_","redirectTimeoutPromise_","unrecoverableErrorDetected_","redirectResultResolved_","fireauth.RedirectAuthEventProcessor.prototype.reset","fireauth.RedirectAuthEventProcessor.prototype.processAuthEvent","isWebStorageNotSupported","isOperationNotSupported","setRedirectResult_","processErrorEvent_","getAuthEventHandlerFinisher","processSuccessEvent_","processUnknownEvent_","fireauth.RedirectAuthEventProcessor.prototype.defaultToEmptyResponse","fireauth.RedirectAuthEventProcessor.prototype.clearRedirectResult","fireauth.RedirectAuthEventProcessor.prototype.processSuccessEvent_","requestUri","isRedirect","popupRedirectResponse","fireauth.RedirectAuthEventProcessor.prototype.setRedirectReject_","this.redirectedUserPromise_","fireauth.RedirectAuthEventProcessor.prototype.setRedirectResolve_","popupRedirectResult","fireauth.RedirectAuthEventProcessor.prototype.setRedirectResult_","setRedirectReject_","setRedirectResolve_","fireauth.RedirectAuthEventProcessor.prototype.getRedirectResult","startRedirectTimeout_","fireauth.RedirectAuthEventProcessor.prototype.startRedirectTimeout_","fireauth.AuthEventManager.REDIRECT_TIMEOUT_MS_.get","fireauth.PopupAuthEventProcessor.prototype.processAuthEvent","fireauth.PopupAuthEventProcessor.prototype.processSuccessEvent_","fireauth.AuthSettings","appVerificationDisabledForTesting_","getAppVerificationDisabledForTesting","setAppVerificationDisabledForTesting","fireauth.ConfirmationResult","credentialResolver","credentialResolver_","confirm","fireauth.ConfirmationResult.prototype.confirm","fireauth.ConfirmationResult.initialize","auth","appVerifier","phoneAuthProvider","fireauth.IdTokenResult","fireauth.MultiFactorResolver","errorResponse","onIdTokenResolver","pendingCredential","fireauth.MultiFactorResolver.SignInResponseField.MFA_PENDING_CREDENTIAL","errorResponse_","onIdTokenResolver_","session_","hints_","fireauth.MultiFactorResolver.SignInResponseField.MFA_INFO","mfaEnrollment","MFA_PENDING_CREDENTIAL","resolveSignIn","fireauth.MultiFactorResolver.prototype.resolveSignIn","process","newSignInResponse","fireauth.MultiFactorError","fireauth.MultiFactorError.base","resolver_","fireauth.MultiFactorError.fromPlainObject","fireauth.MultiFactorAssertion","fireauth.MultiFactorAssertion.prototype.process","finalizeMfaEnrollment_","finalizeMfaSignIn_","fireauth.MultiFactorAssertion.prototype.finalizeMfaEnrollment_","multiFactorAuthCredential","fireauth.RpcHandler.ApiMethod.FINALIZE_PHONE_MFA_ENROLLMENT","fireauth.MultiFactorAssertion.prototype.finalizeMfaSignIn_","signInRequest","fireauth.RpcHandler.ApiMethod.FINALIZE_PHONE_MFA_SIGN_IN","fireauth.AuthCredentialMultiFactorAssertion","fireauth.PhoneMultiFactorAssertion","phoneAuthCredential","fireauth.AuthCredentialMultiFactorAssertion.call","fireauth.PhoneMultiFactorAssertion.base","fireauth.UserEvent","fireauth.MultiFactorUser","user","accountInfo","user_","enrolledFactors_","userReloadedListener_","handleUserReload_","USER_RELOADED","enrolledFactors","enrolledFactorsPlainObject","toISOString","updateEnrolledFactors_","fireauth.MultiFactorUser.extractEnrolledFactors_","fireauth.MultiFactorUser.prototype","fireauth.MultiFactorUser.prototype.handleUserReload_","userServerResponse","fireauth.MultiFactorUser.prototype.updateEnrolledFactors_","getSession","fireauth.MultiFactorUser.prototype.getSession","getIdToken","enroll","fireauth.MultiFactorUser.prototype.enroll","tokenResponse","updateTokensIfPresent","reload","unenroll","fireauth.MultiFactorUser.prototype.unenroll","fireauth.RpcHandler.ApiMethod.WITHDRAW_MFA","fireauth.MultiFactorUser.prototype.toPlainObject","fireauth.ProactiveRefresh","retryPolicy","getWaitDuration","operation_","retryPolicy_","getWaitDuration_","lowerBound_","RETRIAL_MIN_WAIT","upperBound_","RETRIAL_MAX_WAIT","pending_","nextErrorWaitInterval_","fireauth.ProactiveRefresh.prototype.start","process_","fireauth.ProactiveRefresh.prototype.getNextRun_","hasSucceeded","currentErrorWaitInterval","fireauth.ProactiveRefresh.prototype.process_","stop","getNextRun_","fireauth.ProactiveRefresh.prototype.stop","fireauth.StsTokenManager","accessToken_","refreshToken_","fireauth.StsTokenManager.prototype.toPlainObject","getExpirationTime","fireauth.StsTokenManager.prototype.getExpirationTime","fireauth.StsTokenManager.prototype.parseServerResponse","refreshToken","setAccessToken","setRefreshToken","fireauth.StsTokenManager.prototype.copy","tokenManagerToCopy","fireauth.StsTokenManager.prototype.requestToken_","requestStsToken","getToken","fireauth.StsTokenManager.prototype.getToken","opt_forceRefresh","forceRefresh","isRefreshTokenExpired","isExpired_","fireauth.StsTokenManager.TOKEN_REFRESH_BUFFER","requestToken_","exchangeRefreshToken_","fireauth.UserMetadata","opt_createdAt","opt_lastLoginAt","createdAt_","lastLoginAt_","fireauth.UserMetadata.prototype.clone","fireauth.UserMetadata.prototype.toPlainObject","fireauth.AuthUserInfo","opt_email","opt_displayName","opt_photoURL","opt_phoneNumber","fireauth.AuthUser","appOptions","stsTokenResponse","opt_accountInfo","pendingPromises_","clientFullVersion","stsTokenManager_","setLastAccessToken_","parseServerResponse","setAccountInfo","fireauth.AuthUser.base","popupRedirectEnabled_","authEventManager_","stateChangeListeners_","userInvalidatedError_","proactiveRefresh_","initializeProactiveRefreshUtility_","userTokenChangeListener_","handleUserTokenChange_","languageCode_","onLanguageCodeChanged_","this.onLanguageCodeChanged_","setLanguageCode","languageCodeChangeEventDispatcher_","onFrameworkChanged_","this.onFrameworkChanged_","setFramework","frameworkChangeEventDispatcher_","multiFactorUser_","fireauth.AuthUser.prototype.setLanguageCode","updateCustomLocaleHeader","fireauth.AuthUser.prototype.getLanguageCode","fireauth.AuthUser.prototype.setLanguageCodeChangeDispatcher","dispatcher","LANGUAGE_CODE_CHANGED","fireauth.AuthUser.prototype.setFramework","framework","updateClientVersion","fireauth.AuthUser.prototype.getFramework","fireauth.AuthUser.prototype.setFrameworkChangeDispatcher","FRAMEWORK_CHANGED","fireauth.AuthUser.prototype.handleUserTokenChange_","fireauth.AuthUser.prototype.getAuth_","fireauth.AuthUser.prototype.initializeProactiveRefreshUtility_","waitInterval","OFFSET_DURATION","fireauth.AuthUser.prototype.startProactiveRefresh","destroyed_","TOKEN_CHANGED","fireauth.AuthUser.prototype.stopProactiveRefresh","fireauth.AuthUser.prototype.setLastAccessToken_","lastAccessToken","lastAccessToken_","fireauth.AuthUser.prototype.removeStateChangeListener","fireauth.AuthUser.prototype.notifyStateChangeListeners_","fireauth.AuthUser.prototype.enablePopupRedirect","fireauth.AuthUser.prototype.setAccountInfo","FIREBASE","fireauth.AuthUser.returnNothing_","fireauth.AuthUser.prototype.checkDestroyed_","fireauth.AuthUser.prototype.getProviderIds","fireauth.AuthUser.prototype.addProviderData","providerData","removeProviderData","fireauth.AuthUser.prototype.removeProviderData","fireauth.AuthUser.prototype.updateProperty","propName","fireauth.AuthUser.prototype.copy","userToCopy","addProviderData","fireauth.AuthUser.prototype","fireauth.AuthUser.prototype.reload","registerPendingPromise_","checkDestroyed_","reloadWithoutSaving_","notifyStateChangeListeners_","fireauth.AuthUser.prototype.reloadWithoutSaving_","setUserAccountInfoFromToken_","updateProperty","getIdTokenResult","fireauth.AuthUser.prototype.getIdTokenResult","fireauth.AuthUser.prototype.getIdToken","fireauth.AuthUser.prototype.updateTokensIfPresent","notifyAuthListeners_","fireauth.AuthUser.prototype.setUserAccountInfoFromToken_","fireauth.RpcHandler.ApiMethod.GET_ACCOUNT_INFO","parseAccountInfo_","fireauth.AuthUser.prototype.parseAccountInfo_","users","linkedAccounts","extractLinkedAccounts_","fireauth.AuthUser.prototype.extractLinkedAccounts_","providerInfo","reauthenticateAndRetrieveDataWithCredential","fireauth.AuthUser.prototype.reauthenticateAndRetrieveDataWithCredential","REAUTH_WITH_CREDENTIAL","reauthenticateWithCredential","fireauth.AuthUser.prototype.reauthenticateWithCredential","userCredential","getUserCredential_","REAUTHENTICATE","fireauth.AuthUser.prototype.checkIfAlreadyLinked_","getProviderIds","linkAndRetrieveDataWithCredential","fireauth.AuthUser.prototype.linkAndRetrieveDataWithCredential","LINK_WITH_CREDENTIAL","linkWithCredential","fireauth.AuthUser.prototype.linkWithCredential","checkIfAlreadyLinked_","LINK","finalizeLinking_","linkWithPhoneNumber","fireauth.AuthUser.prototype.linkWithPhoneNumber","getAuth_","reauthenticateWithPhoneNumber","fireauth.AuthUser.prototype.reauthenticateWithPhoneNumber","fireauth.AuthUser.prototype.getUserCredential_","idTokenResponse","operationType","additionalUserInfo","fireauth.AuthUser.prototype.finalizeLinking_","fireauth.AuthUser.prototype.updateEmail","updatePhoneNumber","fireauth.AuthUser.prototype.updatePhoneNumber","phoneCredential","fireauth.AuthUser.prototype.updatePassword","fireauth.AuthUser.prototype.updateProfile","profileRequest","unlink","fireauth.AuthUser.prototype.unlink","deleteLinkedAccounts","remainingProviderIds","pId","delete","fireauth.AuthUser.prototype.delete","fireauth.RpcHandler.ApiMethod.DELETE_ACCOUNT","setLanguageCodeChangeDispatcher","setFrameworkChangeDispatcher","stopProactiveRefresh","unsubscribe","fireauth.AuthUser.prototype.canHandleAuthEvent","LINK_VIA_POPUP","getPopupEventId","popupEventId_","pendingPopupResolvePromise_","REAUTH_VIA_POPUP","LINK_VIA_REDIRECT","getRedirectEventId","redirectEventId_","REAUTH_VIA_REDIRECT","fireauth.AuthUser.prototype.resolvePendingPopupEvent","pendingPopupRejectPromise_","popupTimeoutPromise_","fireauth.AuthUser.prototype.getAuthEventHandlerFinisher","finishPopupAndRedirectLink","finishPopupAndRedirectReauth","linkWithPopup","fireauth.AuthUser.prototype.linkWithPopup","runOperationWithPopup_","additionalCheck","reauthenticateWithPopup","fireauth.AuthUser.prototype.reauthenticateWithPopup","fireauth.AuthUser.prototype.runOperationWithPopup_","isReauthOperation","settings","generateEventId_","getAuthEventManager","linkWithRedirect","fireauth.AuthUser.prototype.linkWithRedirect","runOperationWithRedirect_","reauthenticateWithRedirect","fireauth.AuthUser.prototype.reauthenticateWithRedirect","fireauth.AuthUser.prototype.runOperationWithRedirect_","errorThrown","redirectStorageManager_","fireauth.storage.RedirectUserManager.REDIRECT_USER_KEY_","redirectUser","removeRedirectUser","fireauth.AuthUser.prototype.getAuthEventManager","fireauth.AuthUser.prototype.finishPopupAndRedirectLink","fireauth.AuthUser.prototype.finishPopupAndRedirectReauth","fireauth.AuthUser.prototype.sendEmailVerification","opt_actionCodeSettings","latestIdToken","buildRequest","fireauth.AuthUser.prototype.verifyBeforeUpdateEmail","fireauth.AuthUser.prototype.registerPendingPromise_","opt_skipInvalidationCheck","processedP","checkIfInvalidated_","multiFactorError","handleMultiFactorIdTokenResolver_","fireauth_AuthUser_prototype$handleMultiFactorIdTokenResolver_","fireauth.AuthUser.prototype.handleMultiFactorIdTokenResolver_","fireauth.AuthUser.prototype.checkIfInvalidated_","USER_INVALIDATED","fireauth.AuthUser.prototype.toJSON","fireauth.AuthUser.prototype.toPlainObject","fireauth.AuthUser.fromPlainObject","stsTokenManagerResponse","firebaseUser","fireauth.AuthUser.initializeFromIdTokenResponse","opt_redirectStorageManager","fireauth.AuthUser.copyUser","opt_appOptions","getRefreshToken","newUser","fireauth.storage.RedirectUserManager","fireauth.storage.RedirectUserManager.prototype.removeRedirectUser","fireauth.storage.RedirectUserManager.prototype.getRedirectUser","opt_authDomain","fireauth.storage.UserManager","currentAuthUserKey_","onReady_","fireauth.storage.UserManager.getAuthUserKey_","switchToLocalOnExternalEvent_","fireauth.storage.UserManager.prototype.switchToLocalOnExternalEvent_","localKey","waitForReady_","removeAllExcept_","fireauth.storage.UserManager.prototype.removeAllExcept_","persistence","storageKey","fireauth.storage.UserManager.PERSISTENCE_KEY_","fireauth.storage.UserManager.prototype.initialize_","sessionKey","inMemoryKey","migrateFromLocalStorage","currentKey","fireauth.storage.UserManager.AUTH_USER_KEY_NAME_","setPersistence","fireauth.storage.UserManager.prototype.setPersistence","currentUser","fireauth.storage.UserManager.prototype.savePersistenceForRedirect","fireauth.storage.UserManager.prototype.setCurrentUser","fireauth.storage.UserManager.prototype.removeCurrentUser","fireauth.storage.UserManager.prototype.getCurrentUser","fireauth.storage.UserManager.prototype.waitForReady_","fireauth.Auth","app","deleted_","app_","authListeners_","userChangeListeners_","onIdTokenChanged_","createSubscribe","initIdTokenChangeObserver_","userStateChangeUid_","onUserStateChanged_","initUserStateObserver_","setCurrentUser_","userStorageManager_","getStorageKey","redirectUserStorageManager_","authStateLoaded_","initAuthState_","redirectStateIsReady_","initAuthRedirectState_","isStateResolved_","getSyncAuthUserChanges_","syncAuthUserChanges_","userStateChangeListener_","handleUserStateChange_","userDeleteListener_","handleUserDelete_","userInvalidatedListener_","handleUserInvalidated_","initAuthEventManager_","logFramework","firebaseServices_","fireauth.Auth.base","initializeReadableWritableProps_","fireauth.Auth.LanguageCodeChangeEvent","fireauth.Auth.FrameworkChangeEvent","fireauth.Auth.prototype","fireauth.Auth.prototype.setPersistence","fireauth.Auth.prototype.setLanguageCode","notifyLanguageCodeListeners_","fireauth.Auth.prototype.getLanguageCode","useDeviceLanguage","fireauth.Auth.prototype.useDeviceLanguage","fireauth.Auth.prototype.logFramework","frameworkId","fireauth.Auth.prototype.getFramework","fireauth.Auth.prototype.setTenantId","fireauth.Auth.prototype.getTenantId","fireauth.Auth.prototype.initializeReadableWritableProps_","fireauth.Auth.prototype.toJSON","currentUser_","fireauth.Auth.prototype.getAuthEventManager_","eventManagerProviderPromise_","fireauth.Auth.prototype.initAuthEventManager_","enablePopupRedirect","redirectUser_","fireauth.Auth.prototype.canHandleAuthEvent","SIGN_IN_VIA_REDIRECT","SIGN_IN_VIA_POPUP","fireauth.Auth.prototype.resolvePendingPopupEvent","fireauth.Auth.prototype.getAuthEventHandlerFinisher","finishPopupAndRedirectSignIn","fireauth.Auth.prototype.finishPopupAndRedirectSignIn","signInWithIdTokenProvider_","signInWithPopup","fireauth.Auth.prototype.signInWithPopup","getAuthEventManager_","manager","signInWithRedirect","fireauth.Auth.prototype.signInWithRedirect","savePersistenceForRedirect","fireauth.Auth.prototype.getRedirectResultWithoutClearing_","fireauth.Auth.prototype.getRedirectResult","getRedirectResultWithoutClearing_","clearRedirectResult","updateCurrentUser","fireauth.Auth.prototype.updateCurrentUser","fireauth.Auth.prototype.signInWithIdTokenResponse","fireauth.Auth.prototype.setCurrentUser_","attachEventListeners_","removeStateChangeListener","startProactiveRefresh","setUserLanguage_","setUserFramework_","signOut","fireauth.Auth.prototype.signOut","removeCurrentUser","fireauth.Auth.prototype.initRedirectUser_","getRedirectUser","fireauth.Auth.prototype.initAuthState_","initRedirectUser_","getCurrentUser","setCurrentUser","fireauth.Auth.prototype.initAuthRedirectState_","fireauth.Auth.prototype.syncAuthUserChanges_","thisId","thatId","otherUser","fireauth.Auth.prototype.handleUserStateChange_","fireauth_Auth_prototype$handleUserTokenChange_","fireauth.Auth.prototype.handleUserTokenChange_","fireauth.Auth.prototype.handleUserDelete_","fireauth.Auth.prototype.handleUserInvalidated_","fireauth.Auth.prototype.signInWithIdTokenProvider_","idTokenPromise","signInWithIdTokenResponse","fireauth_Auth_prototype$handleMultiFactorIdTokenResolver_","fireauth.Auth.prototype.handleMultiFactorIdTokenResolver_","fireauth.Auth.prototype.initIdTokenChangeObserver_","observer","addAuthTokenListener","fireauth.Auth.prototype.initUserStateObserver_","addUserChangeListener_","onIdTokenChanged","fireauth.Auth.prototype.onIdTokenChanged","nextOrObserver","opt_completed","onAuthStateChanged","fireauth.Auth.prototype.onAuthStateChanged","getIdTokenInternal","fireauth.Auth.prototype.getIdTokenInternal","stsAccessToken","signInWithCustomToken","fireauth.Auth.prototype.signInWithCustomToken","fireauth.RpcHandler.ApiMethod.VERIFY_CUSTOM_TOKEN","signInWithEmailAndPassword","fireauth.Auth.prototype.signInWithEmailAndPassword","createUserWithEmailAndPassword","fireauth.Auth.prototype.createUserWithEmailAndPassword","fireauth.RpcHandler.ApiMethod.CREATE_ACCOUNT","signInWithCredential","fireauth.Auth.prototype.signInWithCredential","signInAndRetrieveDataWithCredential","fireauth.Auth.prototype.signInAndRetrieveDataWithCredential","SIGN_IN_WITH_CREDENTIAL","fireauth.Auth.prototype.signInAnonymously","fireauth.Auth.prototype.app_","fireauth.Auth.prototype.currentUser_","fireauth.Auth.prototype.getUid","fireauth.Auth.prototype.getLastAccessToken_","fireauth.Auth.prototype.notifyAuthListeners_","getLastAccessToken_","addAuthTokenListenerInternal","fireauth.Auth.prototype.addAuthTokenListenerInternal","removeAuthTokenListenerInternal","fireauth.Auth.prototype.removeAuthTokenListenerInternal","removeAuthTokenListener","fireauth.Auth.prototype.addAuthTokenListener","fireauth.Auth.prototype.removeAuthTokenListener","fireauth.Auth.prototype.addUserChangeListener_","fireauth.Auth.prototype.delete","fireauth.Auth.prototype.registerPendingPromise_","fetchSignInMethodsForEmail","fireauth.Auth.prototype.fetchSignInMethodsForEmail","fetchSignInMethodsForIdentifier","getRpcHandler","isSignInWithEmailLink","fireauth.Auth.prototype.isSignInWithEmailLink","fireauth.Auth.prototype.sendSignInLinkToEmail","actionCodeSettings","actionCodeSettingsBuilder","verifyPasswordResetCode","fireauth.Auth.prototype.verifyPasswordResetCode","fireauth.Auth.prototype.confirmPasswordReset","fireauth.Auth.prototype.checkActionCode","fireauth.Auth.prototype.applyActionCode","fireauth.Auth.prototype.sendPasswordResetEmail","signInWithPhoneNumber","fireauth.Auth.prototype.signInWithPhoneNumber","signInWithEmailLink","fireauth.Auth.prototype.signInWithEmailLink","opt_link","fireauth.grecaptcha","render","fireauth.grecaptcha.prototype.render","fireauth.grecaptcha.prototype.reset","fireauth.grecaptcha.prototype.getResponse","execute","fireauth.grecaptcha.prototype.execute","fireauth.GRecaptchaMockFactory","counter_","fireauth.GRecaptchaMockFactory.START_INSTANCE_ID","fireauth.GRecaptchaMockFactory.instance_","fireauth.GRecaptchaMockFactory.prototype.render","elementOrId","fireauth.RecaptchaMock","fireauth.GRecaptchaMockFactory.prototype.reset","mock","getMock_","getId_","fireauth.GRecaptchaMockFactory.prototype.getResponse","fireauth.GRecaptchaMockFactory.prototype.execute","fireauth.GRecaptchaMockFactory.prototype.getMock_","fireauth.GRecaptchaMockFactory.prototype.getId_","timerId_","responseToken_","isVisible_","element_","onClickHandler_","this.onClickHandler_","CLICK","fireauth.RecaptchaMock.prototype.getResponse","checkIfDeleted_","fireauth.RecaptchaMock.prototype.execute","expirationCallback","fireauth.GRecaptchaMockFactory.EXPIRATION_TIME_MS","fireauth.GRecaptchaMockFactory.SOLVE_TIME_MS","fireauth.RecaptchaMock.prototype.delete","fireauth.RecaptchaMock.prototype.checkIfDeleted_","fireauth.PhoneMultiFactorGenerator","fireauth.RecaptchaMockLoader","loadRecaptchaDeps","fireauth.RecaptchaMockLoader.prototype.loadRecaptchaDeps","clearSingleRecaptcha","fireauth.RecaptchaMockLoader.prototype.clearSingleRecaptcha","fireauth.RecaptchaMockLoader.instance_","fireauth.RecaptchaRealLoader","Infinity","hl_","cbName_","fireauth.RecaptchaRealLoader.RECAPTCHA_SRC_","fireauth.RecaptchaRealLoader.DEFAULT_DEPENDENCY_TIMEOUT_","fireauth.RecaptchaRealLoader.prototype.loadRecaptchaDeps","hl","timer","fireauth.RecaptchaRealLoader.DEFAULT_DEPENDENCY_TIMEOUT_.get","container","parameters","widgetId","fireauth.RecaptchaRealLoader.prototype.clearSingleRecaptcha","fireauth.RecaptchaRealLoader.instance_","fireauth.BaseRecaptchaVerifier","opt_parameters","opt_getLanguageCode","opt_rpcHandlerConfig","opt_isTestingMode","widgetId_","cachedReadyPromise_","container_","grecaptcha_","recaptchaLoader_","parameters_","fireauth.BaseRecaptchaVerifier.ParamName.SITEKEY","isInvisible_","fireauth.BaseRecaptchaVerifier.ParamName.SIZE","hasChildNodes","getLanguageCode_","tokenListeners_","existingCallback","fireauth.BaseRecaptchaVerifier.ParamName.CALLBACK","existingExpiredCallback","fireauth.BaseRecaptchaVerifier.ParamName.EXPIRED_CALLBACK","CALLBACK","EXPIRED_CALLBACK","SITEKEY","SIZE","fireauth.BaseRecaptchaVerifier.prototype.dispatchEvent_","fireauth.BaseRecaptchaVerifier.prototype.removeTokenChangeListener_","fireauth.BaseRecaptchaVerifier.prototype.registerPendingPromise_","fireauth.BaseRecaptchaVerifier.prototype","fireauth.BaseRecaptchaVerifier.prototype.isReady_","grecaptcha","fireauth.RpcHandler.ApiMethod.GET_RECAPTCHA_PARAM","fireauth.BaseRecaptchaVerifier.prototype.render","checkIfDestroyed_","outerContainer","goog.dom.TagName.DIV","verify","fireauth.BaseRecaptchaVerifier.prototype.verify","recaptchaToken","removeTokenChangeListener_","fireauth.BaseRecaptchaVerifier.prototype.reset","fireauth.BaseRecaptchaVerifier.prototype.checkIfDestroyed_","fireauth.BaseRecaptchaVerifier.prototype.clear","node","firstChild","fireauth.RecaptchaVerifier","opt_app","isTestingMode","fireauth.BaseRecaptchaVerifier.call","fireauth.RecaptchaVerifier.base","fireauth.args.validate","apiName","expected","actual","opt_isSetter","actualAsArray","numRequiredArgs","isOptionalSection","optional","maxNumArgs","minNumArgs","numExpectedString","optionalUndefined","validator","fireauth.args.ORDINAL_NUMBERS_.length","fireauth.args.ORDINAL_NUMBERS_","errorPrefix","ordinal","expectedType","argName","typeLabel","fireauth.args.string","opt_optional","fireauth.args.bool","fireauth.args.object","fireauth.args.func","fireauth.args.null","fireauth.args.element","fireauth.args.firebaseAuth","fireauth.args.firebaseApp","App","fireauth.args.authCredential","opt_requiredProviderId","matchesRequiredProvider","fireauth.args.multiFactorAssertion","fireauth.args.authProvider","fireauth.args.validateMultiFactorSession_","fireauth.args.validateMultiFactorInfo_","fireauth.args.applicationVerifier","fireauth.args.or","optionA","optionB","fireauth.exportlib.exportPrototypeMethods","protObj","fnMap","obfuscatedFnName","unobfuscatedFnName","fireauth.exportlib.wrapMethodWithArgumentVerifier_","fireauth.exportlib.exportPrototypeProperties","propMap","obfuscatedPropName","unobfuscatedPropName","getter","setter","expectedArg","fireauth.exportlib.exportFunction","parentObj","func","opt_expectedArgs","methodName","wrapper","argumentsAsArray","shortName","fireauth.exportlib.extractMethodNameFromFullPath_","fireauth.args.firebaseUser","fireauth.AuthProvider.getCredentialFromJSON","fromJSON","fireauth.EmailAuthProvider.credential","fireauth.args.phoneInfoOptions","fireauth.PhoneMultiFactorGenerator.assertion","registerComponent","namespace","authComponent","fireauth.exportlib.AUTH_TYPE","instanceFactory","authInteropComponent","registerVersion","AUTH_NPM_PACKAGE_VERSION","extendNamespace"],"mappings":"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E2hFZ,CA/6EW+C,yBhE7DAA,0BgE4+EX,CAt8EUzB,wBhE/DAA,yBgEqgFV,CA97EUU,wBhE7DAA,yBgE2/EV,CA77ECC,ehE7DAA,gBgE0/ED,CAp9EEs6D,gBhEMH13D,gBgE88EC,CAx6Ec23D,4BhE7CAl4D,mBgEq9Ed;AAn9EGhE,iBhElEAA,qBgEqhFH,CAn8EGqB,iBhE9DAA,qBgEigFH,CAh7EG86D,iBhEnGFj8D,gBgEmhFD,CA/7EMuB,oBhE7DAA,qBgE4/EN,CAx9EiB7B,+BhEjEAA,uBgEyhFjB,CAz8EGw8D,iBhEtEJ/7D,oBgE+gFC,CAl6EA0D,chEpDAA,oBgEs9EA,CA15ECo2D,ehE5DDp2D,oBgEs9EA,CA19EGtE,iBhElEAA,kBgE4hFH,CAv9EaI,2BhEjEAA,4BgEwhFb,CAh9ECO,ehEhEAA,gBgEghFD,CAj6Ec4D,4BhEpDAA,mBgEq9Ed,CAz5EAW,chEjDAA,egE08EA;AA36EQzB,sBhExDAA,uBgEm+ER,CA55ECoB,ehEnDAA,gBgE+8ED,CA39EOhF,qBhEpEAA,sBgE+hFP,CAj9ESa,uBhEhEAA,wBgEihFT,CA98EDI,ahE9DAA,2BgE4gFC,CAh8EOiB,qBhE7DAA,sBgE6/EP,CA57EOI,qBhE7DAA,yBgEy/EP,CA37EUy6D,wBhE3EHt7D,oBgEsgFP,CAv7ESmB,uBhE7DAA,wBgEo/ET,CAt7EDC,ahE5DAA,2BgEk/EC,CA76EOO,qBhE9DAA,sBgE2+EP,CA56EOC,qBhE9DAA,yBgE0+EP;AAz6ECY,ehErDAA,gBgE89ED,CAp6EE+4D,gBhE1HH/8D,cgE8hFC,CAv6EMmE,oBhEpDAA,qBgE29EN,CA78EOlD,qBhE9DAA,sBgE2gFP,CAx7EewB,6BhE7DAA,0BgEq/Ef,CAn7EQM,sBhE5DAA,uBgE++ER,CA75EM2B,oBhEvDAA,2BgEo9EN,CA38EctD,4BhE7DAA,6BgEwgFd,CAp8EUQ,wBhE/DAA,yBgEmgFV,CA/8EIL,kBhE9DAA,mBgE6gFJ,CA/5EesD,6BhElDAA,8BgEi9Ef;AA17EIvC,kBhE9DAA,mBgEw/EJ,CAn6EKgC,mBhErDAA,oBgEw9EL,CA59EO3E,q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","file":"auth.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 * @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 * @type {Object<string, (string|number|boolean)>|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 name of the object that this file defines.\n * @param {*=} opt_object the object to expose at the end of the path.\n * @param {Object=} opt_objectToExportTo The object to add the path to; default\n * is `goog.global`.\n * @private\n */\ngoog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {\n var parts = name.split('.');\n var cur = opt_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 && opt_object !== undefined) {\n // last part and we have an object; use it\n cur[part] = opt_object;\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 a project is expected to be running in strict mode.\n *\n * This define can be used to trigger alternate implementations compatible with\n * running in EcmaScript Strict mode or warn about unavailable functionality.\n * @see https://goo.gl/PudQ4y\n *\n */\ngoog.STRICT_MODE_COMPATIBLE = goog.define('goog.STRICT_MODE_COMPATIBLE', false);\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 */\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=} opt_obj The object to embed in the namespace.\n * @private\n */\ngoog.constructNamespace_ = function(name, opt_obj) {\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, opt_obj);\n};\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 */\ngoog.getScriptNonce = function(opt_window) {\n if (opt_window && opt_window != goog.global) {\n return goog.getScriptNonce_(opt_window.document);\n }\n if (goog.cspNonce_ === null) {\n goog.cspNonce_ = goog.getScriptNonce_(goog.global.document);\n }\n return goog.cspNonce_;\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 * @private {?string}\n */\ngoog.cspNonce_ = null;\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {!Document} doc\n * @return {string} CSP nonce or empty string if no nonce is present.\n * @private\n */\ngoog.getScriptNonce_ = function(doc) {\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/**\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 * Globalizes a whole namespace, such as goog or goog.lang.\n *\n * @param {!Object} obj The namespace to globalize.\n * @param {Object=} opt_global The object to add the properties to.\n * @deprecated Properties may be explicitly exported to the global scope, but\n * this should no longer be done in bulk.\n */\ngoog.globalize = function(obj, opt_global) {\n var global = opt_global || goog.global;\n for (var x in obj) {\n global[x] = obj[x];\n }\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', true);\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 * Null function used for default values of callbacks, etc.\n * @return {void} Nothing.\n */\ngoog.nullFunction = function() {};\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} If a file needs to be transpiled what the output language\n * should be. By default this is the highest language level this file detects\n * the current environment supports. Generally this flag should not be set, but\n * it could be useful to override. Example: If the current environment supports\n * ES6 then by default ES7+ files will be transpiled to ES6, unless this is\n * overridden.\n *\n * Valid values include: es3, es5, es6, es7, and es8. Anything not recognized\n * is treated as es3.\n *\n * Note that setting this value does not force transpilation. Just if\n * transpilation occurs this will be the output. So this is most useful when\n * goog.TRANSPILE is set to 'always' and then forcing the language level to be\n * something lower than what the environment detects.\n */\ngoog.TRANSPILE_TO_LANGUAGE = goog.define('goog.TRANSPILE_TO_LANGUAGE', '');\n\n\n/**\n * @define {string} Path to the transpiler. Executing the script at this\n * path (relative to base.js) should define a function $jscomp.transpile.\n */\ngoog.TRANSPILER = goog.define('goog.TRANSPILER', 'transpile.js');\n\n\n/**\n * @package {?boolean}\n * Visible for testing.\n */\ngoog.hasBadLetScoping = null;\n\n\n/**\n * @return {boolean}\n * @package Visible for testing.\n */\ngoog.useSafari10Workaround = function() {\n if (goog.hasBadLetScoping == null) {\n var hasBadLetScoping;\n try {\n hasBadLetScoping = !eval(\n '\"use strict\";' +\n 'let x = 1; function f() { return typeof x; };' +\n 'f() == \"number\";');\n } catch (e) {\n // Assume that ES6 syntax isn't supported.\n hasBadLetScoping = false;\n }\n goog.hasBadLetScoping = hasBadLetScoping;\n }\n return goog.hasBadLetScoping;\n};\n\n\n/**\n * @param {string} moduleDef\n * @return {string}\n * @package Visible for testing.\n */\ngoog.workaroundSafari10EvalBug = function(moduleDef) {\n return '(function(){' + moduleDef +\n '\\n' + // Terminate any trailing single line comment.\n ';' + // Terminate any trailing expression.\n '})();\\n';\n};\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 exports;\n if (goog.isFunction(moduleDef)) {\n exports = moduleDef.call(undefined, {});\n } else if (typeof moduleDef === 'string') {\n if (goog.useSafari10Workaround()) {\n moduleDef = goog.workaroundSafari10EvalBug(moduleDef);\n }\n\n exports = goog.loadModuleFromSource_.call(undefined, 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 goog.constructNamespace_(moduleName, exports);\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_ = /** @type {function(string):?} */ (function() {\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 var exports = {};\n eval(arguments[0]);\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/**\n * Lazily retrieves the transpiler and applies it to the source.\n * @param {string} code JS code.\n * @param {string} path Path to the code.\n * @param {string} target Language level output.\n * @return {string} The transpiled code.\n * @private\n */\ngoog.transpile_ = function(code, path, target) {\n var jscomp = goog.global['$jscomp'];\n if (!jscomp) {\n goog.global['$jscomp'] = jscomp = {};\n }\n var transpile = jscomp.transpile;\n if (!transpile) {\n var transpilerPath = goog.basePath + goog.TRANSPILER;\n var transpilerCode = goog.loadFileSync_(transpilerPath);\n if (transpilerCode) {\n // This must be executed synchronously, since by the time we know we\n // need it, we're about to load and write the ES6 code synchronously,\n // so a normal script-tag load will be too slow. Wrapped in a function\n // so that code is eval'd in the global scope.\n (function() {\n (0, eval)(transpilerCode + '\\n//# sourceURL=' + transpilerPath);\n }).call(goog.global);\n // Even though the transpiler is optional, if $gwtExport is found, it's\n // a sign the transpiler was loaded and the $jscomp.transpile *should*\n // be there.\n if (goog.global['$gwtExport'] && goog.global['$gwtExport']['$jscomp'] &&\n !goog.global['$gwtExport']['$jscomp']['transpile']) {\n throw new Error(\n 'The transpiler did not properly export the \"transpile\" ' +\n 'method. $gwtExport: ' + JSON.stringify(goog.global['$gwtExport']));\n }\n // transpile.js only exports a single $jscomp function, transpile. We\n // grab just that and add it to the existing definition of $jscomp which\n // contains the polyfills.\n goog.global['$jscomp'].transpile =\n goog.global['$gwtExport']['$jscomp']['transpile'];\n jscomp = goog.global['$jscomp'];\n transpile = jscomp.transpile;\n }\n }\n if (!transpile) {\n // The transpiler is an optional component. If it's not available then\n // replace it with a pass-through function that simply logs.\n var suffix = ' requires transpilation but no transpiler was found.';\n transpile = jscomp.transpile = function(code, path) {\n // TODO(sdh): figure out some way to get this error to show up\n // in test results, noting that the failure may occur in many\n // different ways, including in loadModule() before the test\n // runner even comes up.\n goog.logToConsole_(path + suffix);\n return code;\n };\n }\n // Note: any transpilation errors/warnings will be logged to the console.\n return transpile(code, path, target);\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 if (s == 'object') {\n if (value) {\n // Check these first, so we can avoid calling Object.prototype.toString if\n // possible.\n //\n // IE improperly marshals typeof across execution contexts, but a\n // cross-context object will still return false for \"instanceof Object\".\n if (value instanceof Array) {\n return 'array';\n } else if (value instanceof Object) {\n return s;\n }\n\n // HACK: In order to use an Object prototype method on the arbitrary\n // value, the compiler requires the value be cast to type Object,\n // even though the ECMA spec explicitly allows it.\n var className = Object.prototype.toString.call(\n /** @type {!Object} */ (value));\n // In Firefox 3.6, attempting to access iframe window objects' length\n // property throws an NS_ERROR_FAILURE, so we need to special-case it\n // here.\n if (className == '[object Window]') {\n return 'object';\n }\n\n // We cannot always use constructor == Array or instanceof Array because\n // different frames have different Array objects. In IE6, if the iframe\n // where the array was created is destroyed, the array loses its\n // prototype. Then dereferencing val.splice here throws an exception, so\n // we can't use goog.isFunction. Calling typeof directly returns 'unknown'\n // so that will work. In this case, this function will return false and\n // most array functions will still work because the array is still\n // array-like (supports length and []) even though it has lost its\n // prototype.\n // Mark Miller noticed that Object.prototype.toString\n // allows access to the unforgeable [[Class]] property.\n // 15.2.4.2 Object.prototype.toString ( )\n // When the toString method is called, the following steps are taken:\n // 1. Get the [[Class]] property of this object.\n // 2. Compute a string value by concatenating the three strings\n // \"[object \", Result(1), and \"]\".\n // 3. Return Result(2).\n // and this behavior survives the destruction of the execution context.\n if ((className == '[object Array]' ||\n // In IE all non value types are wrapped as objects across window\n // boundaries (not iframe though) so we have to do object detection\n // for this edge case.\n typeof value.length == 'number' &&\n typeof value.splice != 'undefined' &&\n typeof value.propertyIsEnumerable != 'undefined' &&\n !value.propertyIsEnumerable('splice')\n\n )) {\n return 'array';\n }\n // HACK: There is still an array case that fails.\n // function ArrayImpostor() {}\n // ArrayImpostor.prototype = [];\n // var impostor = new ArrayImpostor;\n // this can be fixed by getting rid of the fast path\n // (value instanceof Array) and solely relying on\n // (value && Object.prototype.toString.vall(value) === '[object Array]')\n // but that would require many more function calls and is not warranted\n // unless closure code is receiving objects from untrusted sources.\n\n // IE in cross-window calls does not correctly marshal the function type\n // (it appears just as an object) so we cannot use just typeof val ==\n // 'function'. However, if the object has a call property, it is a\n // function.\n if ((className == '[object Function]' ||\n typeof value.call != 'undefined' &&\n typeof value.propertyIsEnumerable != 'undefined' &&\n !value.propertyIsEnumerable('call'))) {\n return 'function';\n }\n\n } else {\n return 'null';\n }\n\n } else if (s == 'function' && typeof value.call == 'undefined') {\n // In Safari typeof nodeList returns 'function', and on Firefox typeof\n // behaves similarly for HTML{Applet,Embed,Object}, Elements and RegExps. We\n // would like to return object for those and we can detect an invalid\n // function by making sure that the function object has a call method.\n return 'object';\n }\n return s;\n};\n\n\n/**\n * Returns true if the specified value is an array.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an array.\n */\ngoog.isArray = function(val) {\n return goog.typeOf(val) == 'array';\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 a function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a function.\n */\ngoog.isFunction = function(val) {\n return goog.typeOf(val) == '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 * Adds a hash code field to an object. The hash code is unique for the\n * given object.\n * @param {Object} obj The object to get the hash code for.\n * @return {number} The hash code for the object.\n * @deprecated Use goog.getUid instead.\n */\ngoog.getHashCode = goog.getUid;\n\n\n/**\n * Removes the hash code field from an object.\n * @param {Object} obj The object to remove the field from.\n * @deprecated Use goog.removeUid instead.\n */\ngoog.removeHashCode = goog.removeUid;\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 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 */\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 * Copies all the members of a source object to a target object. This method\n * does not work on all browsers for all objects that contain keys such as\n * toString or hasOwnProperty. Use goog.object.extend for this purpose.\n *\n * NOTE: Some have advocated for the use of goog.mixin to setup classes\n * with multiple inheritence (traits, mixins, etc). However, as it simply\n * uses \"for in\", this is not compatible with ES6 classes whose methods are\n * non-enumerable. Changing this, would break cases where non-enumerable\n * properties are not expected.\n *\n * @param {Object} target Target.\n * @param {Object} source Source.\n * @deprecated Prefer Object.assign\n */\ngoog.mixin = function(target, source) {\n for (var x in source) {\n target[x] = source[x];\n }\n\n // For IE7 or lower, the for-in-loop does not contain any properties that are\n // not enumerable on the prototype object (for example, isPrototypeOf from\n // Object.prototype) but also it will 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\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 = (goog.TRUSTED_SITE && Date.now) || (function() {\n // Unary plus operator converts its operand to a number which in\n // the case of\n // a date is done by calling getTime().\n return +new Date();\n });\n\n\n/**\n * Evals JavaScript in the global scope. In IE this uses execScript, other\n * browsers use goog.global.eval. If goog.global.eval does not evaluate in the\n * global scope (for example, in Safari), appends a script tag instead.\n * Throws an exception if neither execScript or eval is defined.\n * @param {string} script JavaScript string.\n */\ngoog.globalEval = function(script) {\n if (goog.global.execScript) {\n goog.global.execScript(script, 'JavaScript');\n } else if (goog.global.eval) {\n // Test to see if eval works\n if (goog.evalWorksForGlobals_ == null) {\n try {\n goog.global.eval('var _evalTest_ = 1;');\n } catch (ignore) {\n }\n if (typeof goog.global['_evalTest_'] != 'undefined') {\n try {\n delete goog.global['_evalTest_'];\n } catch (ignore) {\n // Microsoft edge fails the deletion above in strict mode.\n }\n goog.evalWorksForGlobals_ = true;\n } else {\n goog.evalWorksForGlobals_ = false;\n }\n }\n\n if (goog.evalWorksForGlobals_) {\n goog.global.eval(script);\n } else {\n /** @type {!Document} */\n var doc = goog.global.document;\n var scriptElt =\n /** @type {!HTMLScriptElement} */ (doc.createElement('script'));\n scriptElt.type = 'text/javascript';\n scriptElt.defer = false;\n // Note(user): can't use .innerHTML since \"t('<test>')\" will fail and\n // .text doesn't work in Safari 2. Therefore we append a text node.\n scriptElt.appendChild(doc.createTextNode(script));\n doc.head.appendChild(scriptElt);\n doc.head.removeChild(scriptElt);\n }\n } else {\n throw new Error('goog.globalEval not available');\n }\n};\n\n\n/**\n * Indicates whether or not we can call 'eval' directly to eval code in the\n * global scope. Set to a Boolean by the first call to goog.globalEval (which\n * empirically tests whether eval works for globals). @see goog.globalEval\n * @type {?boolean}\n * @private\n */\ngoog.evalWorksForGlobals_ = null;\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/**\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 {{html: boolean}=} opt_options Options:\n * html: Escape '<' in str to '<'. Used by Closure Templates where the\n * generated code size and performance is critical which is why {@link\n * goog.html.SafeHtmlFormatter} is not used. The value must be literal true\n * or false.\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_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=} opt_objectToExportTo The object to add the path to; default\n * is goog.global.\n */\ngoog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {\n goog.exportPath_(publicPath, object, opt_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 */\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 ES6 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 // Compute whether the constructor is sealable at definition time, rather\n // than when the instance is being constructed.\n var superclassSealable = !goog.defineClass.isUnsealable_(superClass);\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 if (this.constructor === wrappedCtr && superclassSealable &&\n Object.seal instanceof Function) {\n Object.seal(instance);\n }\n return instance;\n };\n\n return wrappedCtr;\n};\n\n\n/**\n * @param {Function} ctr The constructor to test.\n * @return {boolean} Whether the constructor has been tagged as unsealable\n * using goog.tagUnsealableClass.\n * @private\n */\ngoog.defineClass.isUnsealable_ = function(ctr) {\n return ctr && ctr.prototype &&\n ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_];\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/**\n * Sealing classes breaks the older idiom of assigning properties on the\n * prototype rather than in the constructor. As such, goog.defineClass\n * must not seal subclasses of these old-style classes until they are fixed.\n * Until then, this marks a class as \"broken\", instructing defineClass\n * not to seal subclasses.\n * @param {!Function} ctr The legacy constructor to tag as unsealable.\n */\ngoog.tagUnsealableClass = function(ctr) {\n if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {\n ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;\n }\n};\n\n\n/**\n * Name for unsealable tag property.\n * @const @private {string}\n */\ngoog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = 'goog_defineClass_legacy_unsealable';\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 * 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.substr(l - 7, 7) == 'base.js') {\n goog.basePath = src.substr(0, l - 7);\n return;\n }\n }\n };\n\n goog.findBasePath_();\n\n /** @struct @constructor @final */\n goog.Transpiler = function() {\n /** @private {?Object<string, boolean>} */\n this.requiresTranspilation_ = null;\n /** @private {string} */\n this.transpilationTarget_ = goog.TRANSPILE_TO_LANGUAGE;\n };\n /**\n * Returns a newly created map from language mode string to a boolean\n * indicating whether transpilation should be done for that mode as well as\n * the highest level language that this environment supports.\n *\n * Guaranteed invariant:\n * For any two modes, l1 and l2 where l2 is a newer mode than l1,\n * `map[l1] == true` implies that `map[l2] == true`.\n *\n * Note this method is extracted and used elsewhere, so it cannot rely on\n * anything external (it should easily be able to be transformed into a\n * standalone, top level function).\n *\n * @private\n * @return {{\n * target: string,\n * map: !Object<string, boolean>\n * }}\n */\n goog.Transpiler.prototype.createRequiresTranspilation_ = function() {\n var transpilationTarget = 'es3';\n var /** !Object<string, boolean> */ requiresTranspilation = {'es3': false};\n var transpilationRequiredForAllLaterModes = false;\n\n /**\n * Adds an entry to requiresTranspliation for the given language mode.\n *\n * IMPORTANT: Calls must be made in order from oldest to newest language\n * mode.\n * @param {string} modeName\n * @param {function(): boolean} isSupported Returns true if the JS engine\n * supports the given mode.\n */\n function addNewerLanguageTranspilationCheck(modeName, isSupported) {\n if (transpilationRequiredForAllLaterModes) {\n requiresTranspilation[modeName] = true;\n } else if (isSupported()) {\n transpilationTarget = modeName;\n requiresTranspilation[modeName] = false;\n } else {\n requiresTranspilation[modeName] = true;\n transpilationRequiredForAllLaterModes = true;\n }\n }\n\n /**\n * Does the given code evaluate without syntax errors and return a truthy\n * result?\n */\n function /** boolean */ evalCheck(/** string */ code) {\n try {\n return !!eval(code);\n } catch (ignored) {\n return false;\n }\n }\n\n var userAgent = goog.global.navigator && goog.global.navigator.userAgent ?\n goog.global.navigator.userAgent :\n '';\n\n // Identify ES3-only browsers by their incorrect treatment of commas.\n addNewerLanguageTranspilationCheck('es5', function() {\n return evalCheck('[1,].length==1');\n });\n addNewerLanguageTranspilationCheck('es6', function() {\n // Edge has a non-deterministic (i.e., not reproducible) bug with ES6:\n // https://github.com/Microsoft/ChakraCore/issues/1496.\n var re = /Edge\\/(\\d+)(\\.\\d)*/i;\n var edgeUserAgent = userAgent.match(re);\n if (edgeUserAgent) {\n // The Reflect.construct test below is flaky on Edge. It can sometimes\n // pass or fail on 40 15.15063, so just exit early for Edge and treat\n // it as ES5. Until we're on a more up to date version just always use\n // ES5. See https://github.com/Microsoft/ChakraCore/issues/3217.\n return false;\n }\n // Test es6: [FF50 (?), Edge 14 (?), Chrome 50]\n // (a) default params (specifically shadowing locals),\n // (b) destructuring, (c) block-scoped functions,\n // (d) for-of (const), (e) new.target/Reflect.construct\n var es6fullTest =\n 'class X{constructor(){if(new.target!=String)throw 1;this.x=42}}' +\n 'let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof ' +\n 'String))throw 1;for(const a of[2,3]){if(a==2)continue;function ' +\n 'f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()' +\n '==3}';\n\n return evalCheck('(()=>{\"use strict\";' + es6fullTest + '})()');\n });\n // ** and **= are the only new features in 'es7'\n addNewerLanguageTranspilationCheck('es7', function() {\n return evalCheck('2 ** 2 == 4');\n });\n // async functions are the only new features in 'es8'\n addNewerLanguageTranspilationCheck('es8', function() {\n return evalCheck('async () => 1, true');\n });\n addNewerLanguageTranspilationCheck('es9', function() {\n return evalCheck('({...rest} = {}), true');\n });\n addNewerLanguageTranspilationCheck('es_next', function() {\n return false; // assume it always need to transpile\n });\n return {target: transpilationTarget, map: requiresTranspilation};\n };\n\n\n /**\n * Determines whether the given language needs to be transpiled.\n * @param {string} lang\n * @param {string|undefined} module\n * @return {boolean}\n */\n goog.Transpiler.prototype.needsTranspile = function(lang, module) {\n if (goog.TRANSPILE == 'always') {\n return true;\n } else if (goog.TRANSPILE == 'never') {\n return false;\n } else if (!this.requiresTranspilation_) {\n var obj = this.createRequiresTranspilation_();\n this.requiresTranspilation_ = obj.map;\n this.transpilationTarget_ = this.transpilationTarget_ || obj.target;\n }\n if (lang in this.requiresTranspilation_) {\n if (this.requiresTranspilation_[lang]) {\n return true;\n } else if (\n goog.inHtmlDocument_() && module == 'es6' &&\n !('noModule' in goog.global.document.createElement('script'))) {\n return true;\n } else {\n return false;\n }\n } else {\n throw new Error('Unknown language mode: ' + lang);\n }\n };\n\n\n /**\n * Lazily retrieves the transpiler and applies it to the source.\n * @param {string} code JS code.\n * @param {string} path Path to the code.\n * @return {string} The transpiled code.\n */\n goog.Transpiler.prototype.transpile = function(code, path) {\n // TODO(johnplaisted): We should delete goog.transpile_ and just have this\n // function. But there's some compile error atm where goog.global is being\n // stripped incorrectly without this.\n return goog.transpile_(code, path, this.transpilationTarget_);\n };\n\n\n /** @private @final {!goog.Transpiler} */\n goog.transpiler_ = new goog.Transpiler();\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(goog.transpiler_);\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 false));\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\n goog.logToConsole_(errorMessage);\n throw Error(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 transpiled non-goog.module files {@see goog.TranspiledDependency}.\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 if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&\n goog.isDocumentLoading_()) {\n var key = goog.Dependency.registerCallback_(function(script) {\n if (!goog.DebugLoader_.IS_OLD_IE_ || script.readyState == 'complete') {\n goog.Dependency.unregisterCallback_(key);\n controller.loaded();\n }\n });\n var nonceAttr = !goog.DebugLoader_.IS_OLD_IE_ && goog.getScriptNonce() ?\n ' nonce=\"' + goog.getScriptNonce() + '\"' :\n '';\n var event =\n goog.DebugLoader_.IS_OLD_IE_ ? 'onreadystatechange' : 'onload';\n var defer = goog.Dependency.defer_ ? 'defer' : '';\n var script = '<script src=\"' + this.path + '\" ' + event +\n '=\"goog.Dependency.callback_(\\'' + key +\n '\\', this)\" type=\"text/javascript\" ' + defer + nonceAttr + '><' +\n '/script>';\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 scriptEl.type = 'text/javascript';\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.setAttribute('nonce', nonce);\n }\n\n if (goog.DebugLoader_.IS_OLD_IE_) {\n // Execution order is not guaranteed on old IE, halt loading and write\n // these scripts one at a time, after each loads.\n controller.pause();\n scriptEl.onreadystatechange = function() {\n if (scriptEl.readyState == 'loaded' ||\n scriptEl.readyState == 'complete') {\n controller.loaded();\n controller.resume();\n }\n };\n } else {\n scriptEl.onload = function() {\n scriptEl.onload = null;\n controller.loaded();\n };\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 /** @override */\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 if (contents) {\n var script = '<script type=\"module\" crossorigin>' + 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 '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.setAttribute('nonce', nonce);\n }\n\n if (contents) {\n scriptEl.textContent = 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 /** @override */\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(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 script = '<script type=\"text/javascript\">' +\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 // If anything else is loading we need to lazy load due to bugs in old IE.\n // Specifically script tags with src and script tags with contents could\n // execute out of order if document.write is used, so we cannot use\n // document.write. Do not pause here; it breaks old IE as well.\n var useOldIeWorkAround =\n anythingElsePending && goog.DebugLoader_.IS_OLD_IE_;\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 (useOldIeWorkAround || 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 isInternetExplorer =\n goog.inHtmlDocument_() && 'ActiveXObject' in goog.global;\n\n // Don't delay in any version of IE. There's bug around this that will\n // cause out of order script execution. This means that on older IE ES6\n // modules will load too early (while the document is still loading + the\n // dom is not available). The other option is to load too late (when the\n // document is complete and the onload even will never fire). This seems\n // to be the lesser of two evils as scripts already act like the former.\n if (isEs6 && goog.inHtmlDocument_() && goog.isDocumentLoading_() &&\n !isInternetExplorer) {\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 (goog.isFunction(oldCallback)) {\n oldCallback.apply(undefined, arguments);\n }\n };\n } else {\n // Always eval on old IE.\n if (goog.DebugLoader_.IS_OLD_IE_ || !goog.inHtmlDocument_() ||\n !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 * Any non-goog.module dependency which needs to be transpiled before eval.\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 * @param {!goog.Transpiler} transpiler\n * @struct @constructor\n * @extends {goog.TransformedDependency}\n */\n goog.TranspiledDependency = function(\n path, relativePath, provides, requires, loadFlags, transpiler) {\n goog.TranspiledDependency.base(\n this, 'constructor', path, relativePath, provides, requires, loadFlags);\n /** @protected @const*/\n this.transpiler = transpiler;\n };\n goog.inherits(goog.TranspiledDependency, goog.TransformedDependency);\n\n\n /** @override */\n goog.TranspiledDependency.prototype.transform = function(contents) {\n // Transpile with the pathname so that ES6 modules are domain agnostic.\n return this.transpiler.transpile(contents, this.getPathName());\n };\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 /** @override */\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 * @param {boolean} needsTranspile\n * @param {!goog.Transpiler} transpiler\n * @struct @constructor\n * @extends {goog.TransformedDependency}\n */\n goog.GoogModuleDependency = function(\n path, relativePath, provides, requires, loadFlags, needsTranspile,\n transpiler) {\n goog.GoogModuleDependency.base(\n this, 'constructor', path, relativePath, provides, requires, loadFlags);\n /** @private @const */\n this.needsTranspile_ = needsTranspile;\n /** @private @const */\n this.transpiler_ = transpiler;\n };\n goog.inherits(goog.GoogModuleDependency, goog.TransformedDependency);\n\n\n /** @override */\n goog.GoogModuleDependency.prototype.transform = function(contents) {\n if (this.needsTranspile_) {\n contents = this.transpiler_.transpile(contents, this.getPathName());\n }\n\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 * Whether the browser is IE9 or earlier, which needs special handling\n * for deferred modules.\n * @const @private {boolean}\n */\n goog.DebugLoader_.IS_OLD_IE_ = !!(\n !goog.global.atob && goog.global.document && goog.global.document['all']);\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 goog.transpiler_.needsTranspile(\n opt_loadFlags['lang'] || 'es3', opt_loadFlags['module']));\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 * @param {!goog.Transpiler} transpiler\n * @struct @constructor\n */\n goog.DependencyFactory = function(transpiler) {\n /** @protected @const */\n this.transpiler = transpiler;\n };\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 * @param {boolean} needsTranspile True if the file needs to be transpiled\n * per the goog.Transpiler.\n * @return {!goog.Dependency}\n */\n goog.DependencyFactory.prototype.createDependency = function(\n path, relativePath, provides, requires, loadFlags, needsTranspile) {\n\n if (loadFlags['module'] == goog.ModuleType.GOOG) {\n return new goog.GoogModuleDependency(\n path, relativePath, provides, requires, loadFlags, needsTranspile,\n this.transpiler);\n } else if (needsTranspile) {\n return new goog.TranspiledDependency(\n path, relativePath, provides, requires, loadFlags, this.transpiler);\n } else {\n if (loadFlags['module'] == goog.ModuleType.ES6) {\n if (goog.TRANSPILE == 'never' && 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 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\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', '');\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 // TODO(koto): Remove window.TrustedTypes variant when the newer API ships.\n var policyFactory = goog.global.trustedTypes || 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 createURL: goog.identity_\n });\n } catch (e) {\n goog.logToConsole_(e.message);\n }\n return policy;\n};\n\n\n/** @private @const {?TrustedTypePolicy} */\ngoog.TRUSTED_TYPES_POLICY_ = goog.TRUSTED_TYPES_POLICY_NAME ?\n goog.createTrustedTypesPolicy(goog.TRUSTED_TYPES_POLICY_NAME + '#base') :\n null;\n",null,null,null,null,null,null,"/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines developer-visible errors for Firebase Auth APIs.\n */\n\n\ngoog.provide('fireauth.AuthError');\ngoog.provide('fireauth.authenum');\ngoog.provide('fireauth.authenum.Error');\n\n\n\n/**\n * Error that can be returned to the developer.\n * @param {!fireauth.authenum.Error} code The short error code.\n * @param {?string=} message The human-readable message.\n * @param {?Object=} serverResponse The raw server response.\n * @constructor\n * @extends {Error}\n */\nfireauth.AuthError = function(code, message, serverResponse) {\n this['code'] = fireauth.AuthError.ERROR_CODE_PREFIX + code;\n this.message = message || fireauth.AuthError.MESSAGES_[code] || '';\n this.serverResponse = serverResponse || null;\n};\ngoog.inherits(fireauth.AuthError, Error);\n\n\n/**\n * @return {!Object} The plain object form of the error.\n */\nfireauth.AuthError.prototype.toPlainObject = function() {\n var obj = {\n 'code': this['code'],\n 'message': this.message\n };\n if (this.serverResponse) {\n obj['serverResponse'] = this.serverResponse;\n }\n return obj;\n};\n\n\n/**\n * @return {!Object} The plain object form of the error. This is used by\n * JSON.toStringify() to return the stringified representation of the error;\n * @override\n */\nfireauth.AuthError.prototype.toJSON = function() {\n // Return the plain object representation in case JSON.stringify is called on\n // an auth error instance.\n return this.toPlainObject();\n};\n\n\n/**\n * @param {?Object|undefined} response The object response to convert to a\n * fireauth.AuthError.\n * @return {?fireauth.AuthError} The error representation of the response.\n */\nfireauth.AuthError.fromPlainObject = function(response) {\n var fullCode = response && response['code'];\n if (fullCode) {\n // Remove prefix from name.\n var code = fullCode.substring(\n fireauth.AuthError.ERROR_CODE_PREFIX.length);\n return new fireauth.AuthError(\n /** @type {!fireauth.authenum.Error} */ (code),\n response['message'],\n response['serverResponse']);\n }\n return null;\n};\n\n\n/**\n * Takes in an error and translates a specific error code to another one if\n * found in the current error.\n * @param {*} error The error thrown.\n * @param {!fireauth.authenum.Error} fromCode The error code to translate from.\n * @param {!fireauth.authenum.Error} toCode The error code to translate to.\n * @return {*} The mapped error message.\n */\nfireauth.AuthError.translateError = function(error, fromCode, toCode) {\n if (error &&\n error['code'] &&\n error['code'] == fireauth.AuthError.ERROR_CODE_PREFIX + fromCode) {\n // Translate the error to the new one.\n return new fireauth.AuthError(toCode);\n }\n // Return the same error if the fromCode is not found.\n return error;\n};\n\n\n/**\n * The error prefix for fireauth.Auth errors.\n * @protected {string}\n */\nfireauth.AuthError.ERROR_CODE_PREFIX = 'auth/';\n\n\n/**\n * Developer facing Firebase Auth error codes.\n * @enum {string}\n */\nfireauth.authenum.Error = {\n ADMIN_ONLY_OPERATION: 'admin-restricted-operation',\n ARGUMENT_ERROR: 'argument-error',\n APP_NOT_AUTHORIZED: 'app-not-authorized',\n APP_NOT_INSTALLED: 'app-not-installed',\n CAPTCHA_CHECK_FAILED: 'captcha-check-failed',\n CODE_EXPIRED: 'code-expired',\n CORDOVA_NOT_READY: 'cordova-not-ready',\n CORS_UNSUPPORTED: 'cors-unsupported',\n CREDENTIAL_ALREADY_IN_USE: 'credential-already-in-use',\n CREDENTIAL_MISMATCH: 'custom-token-mismatch',\n CREDENTIAL_TOO_OLD_LOGIN_AGAIN: 'requires-recent-login',\n DYNAMIC_LINK_NOT_ACTIVATED: 'dynamic-link-not-activated',\n EMAIL_CHANGE_NEEDS_VERIFICATION: 'email-change-needs-verification',\n EMAIL_EXISTS: 'email-already-in-use',\n EXPIRED_OOB_CODE: 'expired-action-code',\n EXPIRED_POPUP_REQUEST: 'cancelled-popup-request',\n INTERNAL_ERROR: 'internal-error',\n INVALID_API_KEY: 'invalid-api-key',\n INVALID_APP_CREDENTIAL: 'invalid-app-credential',\n INVALID_APP_ID: 'invalid-app-id',\n INVALID_AUTH: 'invalid-user-token',\n INVALID_AUTH_EVENT: 'invalid-auth-event',\n INVALID_CERT_HASH: 'invalid-cert-hash',\n INVALID_CODE: 'invalid-verification-code',\n INVALID_CONTINUE_URI: 'invalid-continue-uri',\n INVALID_CORDOVA_CONFIGURATION: 'invalid-cordova-configuration',\n INVALID_CUSTOM_TOKEN: 'invalid-custom-token',\n INVALID_DYNAMIC_LINK_DOMAIN: 'invalid-dynamic-link-domain',\n INVALID_EMAIL: 'invalid-email',\n INVALID_IDP_RESPONSE: 'invalid-credential',\n INVALID_MESSAGE_PAYLOAD: 'invalid-message-payload',\n INVALID_MFA_PENDING_CREDENTIAL: 'invalid-multi-factor-session',\n INVALID_OAUTH_CLIENT_ID: 'invalid-oauth-client-id',\n INVALID_OAUTH_PROVIDER: 'invalid-oauth-provider',\n INVALID_OOB_CODE: 'invalid-action-code',\n INVALID_ORIGIN: 'unauthorized-domain',\n INVALID_PASSWORD: 'wrong-password',\n INVALID_PERSISTENCE: 'invalid-persistence-type',\n INVALID_PHONE_NUMBER: 'invalid-phone-number',\n INVALID_PROVIDER_ID: 'invalid-provider-id',\n INVALID_RECIPIENT_EMAIL: 'invalid-recipient-email',\n INVALID_SENDER: 'invalid-sender',\n INVALID_SESSION_INFO: 'invalid-verification-id',\n INVALID_TENANT_ID: 'invalid-tenant-id',\n MFA_ENROLLMENT_NOT_FOUND: 'multi-factor-info-not-found',\n MFA_REQUIRED: 'multi-factor-auth-required',\n MISSING_ANDROID_PACKAGE_NAME: 'missing-android-pkg-name',\n MISSING_APP_CREDENTIAL: 'missing-app-credential',\n MISSING_AUTH_DOMAIN: 'auth-domain-config-required',\n MISSING_CODE: 'missing-verification-code',\n MISSING_CONTINUE_URI: 'missing-continue-uri',\n MISSING_IFRAME_START: 'missing-iframe-start',\n MISSING_IOS_BUNDLE_ID: 'missing-ios-bundle-id',\n MISSING_MFA_ENROLLMENT_ID: 'missing-multi-factor-info',\n MISSING_MFA_PENDING_CREDENTIAL: 'missing-multi-factor-session',\n MISSING_OR_INVALID_NONCE: 'missing-or-invalid-nonce',\n MISSING_PHONE_NUMBER: 'missing-phone-number',\n MISSING_SESSION_INFO: 'missing-verification-id',\n MODULE_DESTROYED: 'app-deleted',\n NEED_CONFIRMATION: 'account-exists-with-different-credential',\n NETWORK_REQUEST_FAILED: 'network-request-failed',\n NULL_USER: 'null-user',\n NO_AUTH_EVENT: 'no-auth-event',\n NO_SUCH_PROVIDER: 'no-such-provider',\n OPERATION_NOT_ALLOWED: 'operation-not-allowed',\n OPERATION_NOT_SUPPORTED: 'operation-not-supported-in-this-environment',\n POPUP_BLOCKED: 'popup-blocked',\n POPUP_CLOSED_BY_USER: 'popup-closed-by-user',\n PROVIDER_ALREADY_LINKED: 'provider-already-linked',\n QUOTA_EXCEEDED: 'quota-exceeded',\n REDIRECT_CANCELLED_BY_USER: 'redirect-cancelled-by-user',\n REDIRECT_OPERATION_PENDING: 'redirect-operation-pending',\n REJECTED_CREDENTIAL: 'rejected-credential',\n SECOND_FACTOR_EXISTS: 'second-factor-already-in-use',\n SECOND_FACTOR_LIMIT_EXCEEDED: 'maximum-second-factor-count-exceeded',\n TENANT_ID_MISMATCH: 'tenant-id-mismatch',\n TIMEOUT: 'timeout',\n TOKEN_EXPIRED: 'user-token-expired',\n TOO_MANY_ATTEMPTS_TRY_LATER: 'too-many-requests',\n UNAUTHORIZED_DOMAIN: 'unauthorized-continue-uri',\n UNSUPPORTED_FIRST_FACTOR: 'unsupported-first-factor',\n UNSUPPORTED_PERSISTENCE: 'unsupported-persistence-type',\n UNSUPPORTED_TENANT_OPERATION: 'unsupported-tenant-operation',\n UNVERIFIED_EMAIL: 'unverified-email',\n USER_CANCELLED: 'user-cancelled',\n USER_DELETED: 'user-not-found',\n USER_DISABLED: 'user-disabled',\n USER_MISMATCH: 'user-mismatch',\n USER_SIGNED_OUT: 'user-signed-out',\n WEAK_PASSWORD: 'weak-password',\n WEB_STORAGE_UNSUPPORTED: 'web-storage-unsupported'\n};\n\n\n/**\n * Map from developer error codes to human-readable error messages.\n * @private {!Object<string, string>}\n */\nfireauth.AuthError.MESSAGES_ = {};\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.ADMIN_ONLY_OPERATION] =\n 'This operation is restricted to administrators only.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.ARGUMENT_ERROR] = '';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.APP_NOT_AUTHORIZED] =\n 'This app, identified by the domain where it\\'s hosted, is not ' +\n 'authorized to use Firebase Authentication with the provided API key. ' +\n 'Review your key configuration in the Google API console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.APP_NOT_INSTALLED] =\n 'The requested mobile application corresponding to the identifier (' +\n 'Android package name or iOS bundle ID) provided is not installed on ' +\n 'this device.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CAPTCHA_CHECK_FAILED] =\n 'The reCAPTCHA response token provided is either invalid, expired, ' +\n 'already used or the domain associated with it does not match the list ' +\n 'of whitelisted domains.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CODE_EXPIRED] =\n 'The SMS code has expired. Please re-send the verification code to try ' +\n 'again.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CORDOVA_NOT_READY] =\n 'Cordova framework is not ready.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CORS_UNSUPPORTED] =\n 'This browser is not supported.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE] =\n 'This credential is already associated with a different user account.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.CREDENTIAL_MISMATCH] =\n 'The custom token corresponds to a different audience.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.CREDENTIAL_TOO_OLD_LOGIN_AGAIN] =\n 'This operation is sensitive and requires recent authentication. Log in ' +\n 'again before retrying this request.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.DYNAMIC_LINK_NOT_ACTIVATED] = 'Please activate ' +\n 'Dynamic Links in the Firebase Console and agree to the terms and ' +\n 'conditions.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.EMAIL_CHANGE_NEEDS_VERIFICATION] =\n 'Multi-factor users must always have a verified email.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.EMAIL_EXISTS] =\n 'The email address is already in use by another account.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.EXPIRED_OOB_CODE] =\n 'The action code has expired. ';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.EXPIRED_POPUP_REQUEST] =\n 'This operation has been cancelled due to another conflicting popup ' +\n 'being opened.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INTERNAL_ERROR] =\n 'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_APP_CREDENTIAL] =\n 'The phone verification request contains an invalid application verifier.' +\n ' The reCAPTCHA token response is either invalid or expired.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_APP_ID] =\n 'The mobile app identifier is not registed for the current project.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_AUTH] =\n 'This user\\'s credential isn\\'t valid for this project. This can happen ' +\n 'if the user\\'s token has been tampered with, or if the user isn\\'t for ' +\n 'the project associated with this API key.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_AUTH_EVENT] =\n 'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CODE] =\n 'The SMS verification code used to create the phone auth credential is ' +\n 'invalid. Please resend the verification code sms and be sure use the ' +\n 'verification code provided by the user.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CONTINUE_URI] =\n 'The continue URL provided in the request is invalid.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION] = 'The following' +\n ' Cordova plugins must be installed to enable OAuth sign-in: ' +\n 'cordova-plugin-buildinfo, cordova-universal-links-plugin, ' +\n 'cordova-plugin-browsertab, cordova-plugin-inappbrowser and ' +\n 'cordova-plugin-customurlscheme.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CUSTOM_TOKEN] =\n 'The custom token format is incorrect. Please check the documentation.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN] = 'The provided ' +\n 'dynamic link domain is not configured or authorized for the current ' +\n 'project.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_EMAIL] =\n 'The email address is badly formatted.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_API_KEY] =\n 'Your API key is invalid, please check you have copied it correctly.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CERT_HASH] =\n 'The SHA-1 certificate hash provided is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_IDP_RESPONSE] =\n 'The supplied auth credential is malformed or has expired.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_MESSAGE_PAYLOAD] =\n 'The email template corresponding to this action contains invalid charac' +\n 'ters in its message. Please fix by going to the Auth email templates se' +\n 'ction in the Firebase Console.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.INVALID_MFA_PENDING_CREDENTIAL] =\n 'The request does not contain a valid proof of first factor successful ' +\n 'sign-in.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_OAUTH_PROVIDER] =\n 'EmailAuthProvider is not supported for this operation. This operation ' +\n 'only supports OAuth providers.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_OAUTH_CLIENT_ID] =\n 'The OAuth client ID provided is either invalid or does not match the ' +\n 'specified API key.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_ORIGIN] =\n 'This domain is not authorized for OAuth operations for your Firebase ' +\n 'project. Edit the list of authorized domains from the Firebase console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_OOB_CODE] =\n 'The action code is invalid. This can happen if the code is malformed, ' +\n 'expired, or has already been used.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PASSWORD] =\n 'The password is invalid or the user does not have a password.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PERSISTENCE] =\n 'The specified persistence type is invalid. It can only be local, ' +\n 'session or none.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PHONE_NUMBER] =\n 'The format of the phone number provided is incorrect. Please enter the ' +\n 'phone number in a format that can be parsed into E.164 format. E.164 ' +\n 'phone numbers are written in the format [+][country code][subscriber ' +\n 'number including area code].';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_PROVIDER_ID] =\n 'The specified provider ID is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_RECIPIENT_EMAIL] =\n 'The email corresponding to this action failed to send as the provided ' +\n 'recipient email address is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_SENDER] =\n 'The email template corresponding to this action contains an invalid sen' +\n 'der email or name. Please fix by going to the Auth email templates sect' +\n 'ion in the Firebase Console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_SESSION_INFO] =\n 'The verification ID used to create the phone auth credential is invalid.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_TENANT_ID] =\n 'The Auth instance\\'s tenant ID is invalid.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.MFA_ENROLLMENT_NOT_FOUND] = 'The user does not ' +\n 'have a second factor matching the identifier provided.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MFA_REQUIRED] =\n 'Proof of ownership of a second factor is required to complete sign-in.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME] = 'An Android ' +\n 'Package Name must be provided if the Android App is required to be ' +\n 'installed.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_AUTH_DOMAIN] =\n 'Be sure to include authDomain when calling firebase.initializeApp(), ' +\n 'by following the instructions in the Firebase console.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_APP_CREDENTIAL] =\n 'The phone verification request is missing an application verifier ' +\n 'assertion. A reCAPTCHA response token needs to be provided.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_CODE] =\n 'The phone auth credential was created with an empty SMS verification ' +\n 'code.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_CONTINUE_URI] =\n 'A continue URL must be provided in the request.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_IFRAME_START] =\n 'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID] =\n 'An iOS Bundle ID must be provided if an App Store ID is provided.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.MISSING_MFA_ENROLLMENT_ID] =\n 'No second factor identifier is provided.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.MISSING_MFA_PENDING_CREDENTIAL] =\n 'The request is missing proof of first factor successful sign-in.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_OR_INVALID_NONCE] =\n 'The request does not contain a valid nonce. This can occur if the ' +\n 'SHA-256 hash of the provided raw nonce does not match the hashed nonce ' +\n 'in the ID token payload.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_PHONE_NUMBER] =\n 'To send verification codes, provide a phone number for the recipient.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MISSING_SESSION_INFO] =\n 'The phone auth credential was created with an empty verification ID.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.MODULE_DESTROYED] =\n 'This instance of FirebaseApp has been deleted.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NEED_CONFIRMATION] =\n 'An account already exists with the same email address but different ' +\n 'sign-in credentials. Sign in using a provider associated with this ' +\n 'email address.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NETWORK_REQUEST_FAILED] =\n 'A network error (such as timeout, interrupted connection or ' +\n 'unreachable host) has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NO_AUTH_EVENT] =\n 'An internal error has occurred.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NO_SUCH_PROVIDER] =\n 'User was not linked to an account with the given provider.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.NULL_USER] =\n 'A null user object was provided as the argument for an operation which ' +\n 'requires a non-null user object.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.OPERATION_NOT_ALLOWED] =\n 'The given sign-in provider is disabled for this Firebase project. ' +\n 'Enable it in the Firebase console, under the sign-in method tab of the ' +\n 'Auth section.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.OPERATION_NOT_SUPPORTED] =\n 'This operation is not supported in the environment this application is ' +\n 'running on. \"location.protocol\" must be http, https or chrome-extension' +\n ' and web storage must be enabled.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.POPUP_BLOCKED] =\n 'Unable to establish a connection with the popup. It may have been ' +\n 'blocked by the browser.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.POPUP_CLOSED_BY_USER] =\n 'The popup has been closed by the user before finalizing the operation.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.PROVIDER_ALREADY_LINKED] =\n 'User can only be linked to one identity for the given provider.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.QUOTA_EXCEEDED] =\n 'The project\\'s quota for this operation has been exceeded.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.REDIRECT_CANCELLED_BY_USER] =\n 'The redirect operation has been cancelled by the user before finalizing.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.REDIRECT_OPERATION_PENDING] =\n 'A redirect sign-in operation is already pending.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.REJECTED_CREDENTIAL] =\n 'The request contains malformed or mismatching credentials.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.SECOND_FACTOR_EXISTS] =\n 'The second factor is already enrolled on this account.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.SECOND_FACTOR_LIMIT_EXCEEDED] =\n 'The maximum allowed number of second factors on a user has been exceeded.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.TENANT_ID_MISMATCH] =\n 'The provided tenant ID does not match the Auth instance\\'s tenant ID';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.TIMEOUT] =\n 'The operation has timed out.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.TOKEN_EXPIRED] =\n 'The user\\'s credential is no longer valid. The user must sign in again.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER] =\n 'We have blocked all requests from this device due to unusual activity. ' +\n 'Try again later.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.UNAUTHORIZED_DOMAIN] =\n 'The domain of the continue URL is not whitelisted. Please whitelist ' +\n 'the domain in the Firebase console.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.UNSUPPORTED_FIRST_FACTOR] = 'Enrolling a second ' +\n 'factor or signing in with a multi-factor account requires sign-in with ' +\n 'a supported first factor.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.UNSUPPORTED_PERSISTENCE] =\n 'The current environment does not support the specified persistence type.';\nfireauth.AuthError.MESSAGES_[\n fireauth.authenum.Error.UNSUPPORTED_TENANT_OPERATION] =\n 'This operation is not supported in a multi-tenant context.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.UNVERIFIED_EMAIL] =\n 'The operation requires a verified email.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_CANCELLED] =\n 'The user did not grant your application the permissions it requested.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_DELETED] =\n 'There is no user record corresponding to this identifier. The user may ' +\n 'have been deleted.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_DISABLED] =\n 'The user account has been disabled by an administrator.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_MISMATCH] =\n 'The supplied credentials do not correspond to the previously signed in ' +\n 'user.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.USER_SIGNED_OUT] = '';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.WEAK_PASSWORD] =\n 'The password must be 6 characters long or more.';\nfireauth.AuthError.MESSAGES_[fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED] =\n 'This browser is not supported or 3rd party cookies and data may be ' +\n 'disabled.';\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines all common constants and enums used by firebase-auth.\n */\n\ngoog.provide('fireauth.constants');\ngoog.provide('fireauth.constants.AuthEventType');\n\n\n/**\n * Enums for authentication operation types.\n * @enum {string}\n */\nfireauth.constants.OperationType = {\n LINK: 'link',\n REAUTHENTICATE: 'reauthenticate',\n SIGN_IN: 'signIn'\n};\n\n\n/**\n * Events dispatched firebase.auth.Auth.\n * @enum {string}\n */\nfireauth.constants.AuthEventType = {\n /** Dispatched when Firebase framework is changed. */\n FRAMEWORK_CHANGED: 'frameworkChanged',\n /** Dispatched when language code is changed. */\n LANGUAGE_CODE_CHANGED: 'languageCodeChanged'\n};\n\n\n/**\n * Enums for all second factor types.\n * @enum {string}\n */\nfireauth.constants.SecondFactorType = {\n PHONE: 'phone'\n};\n\n\n/**\n * The settings of an Auth endpoint. The fields are:\n * <ul>\n * <li>firebaseAuthEndpoint: defines the Firebase Auth backend endpoint for\n * specified endpoint type.</li>\n * <li>secureTokenEndpoint: defines the secure token backend endpoint for\n * specified endpoint type.</li>\n * <li>identityPlatformEndpoint: defines the Identity Platform backend endpoint\n * for specified endpoint type.</li>\n * <li>id: defines the endpoint identifier.</li>\n * </ul>\n * @typedef {{\n * firebaseAuthEndpoint: string,\n * secureTokenEndpoint: string,\n * identityPlatformEndpoint: string,\n * id: string\n * }}\n */\nfireauth.constants.EndpointSettings;\n\n\n/**\n * The different endpoints for Firebase Auth backend.\n * @enum {!fireauth.constants.EndpointSettings}\n */\nfireauth.constants.Endpoint = {\n // TODO: this is no longer needed now that client endpoint migration is\n // completed.\n BOQ: {\n firebaseAuthEndpoint: 'https://staging-identitytoolkit.sandbox.googleapi' +\n 's.com/identitytoolkit/v3/relyingparty/',\n secureTokenEndpoint: 'https://staging-securetoken.sandbox.googleapis.com' +\n '/v1/token',\n identityPlatformEndpoint:\n 'https://staging-identitytoolkit.sandbox.googleapis.com/v2/',\n id: 'b'\n },\n PRODUCTION: {\n firebaseAuthEndpoint: 'https://www.googleapis.com/identitytoolkit/v3/' +\n 'relyingparty/',\n secureTokenEndpoint: 'https://securetoken.googleapis.com/v1/token',\n identityPlatformEndpoint:\n 'https://identitytoolkit.googleapis.com/v2/',\n id: 'p'\n },\n STAGING: {\n firebaseAuthEndpoint: 'https://staging-www.sandbox.googleapis.com/' +\n 'identitytoolkit/v3/relyingparty/',\n secureTokenEndpoint: 'https://staging-securetoken.sandbox.googleapis.com' +\n '/v1/token',\n identityPlatformEndpoint:\n 'https://staging-identitytoolkit.sandbox.googleapis.com/v2/',\n id: 's'\n },\n TEST: {\n firebaseAuthEndpoint: 'https://www-googleapis-test.sandbox.google.com/' +\n 'identitytoolkit/v3/relyingparty/',\n secureTokenEndpoint: 'https://test-securetoken.sandbox.googleapis.com/v1' +\n '/token',\n identityPlatformEndpoint:\n 'https://test-identitytoolkit.sandbox.googleapis.com/v2/',\n id: 't'\n }\n};\n\n\n/**\n * Returns the endpoint specific RpcHandler configuration.\n * @param {?string=} opt_id The identifier of the endpoint type if available.\n * @return {?Object|undefined} The RpcHandler endpoint configuration object.\n */\nfireauth.constants.getEndpointConfig = function(opt_id) {\n for (var endpointKey in fireauth.constants.Endpoint) {\n if (fireauth.constants.Endpoint[endpointKey].id === opt_id) {\n var endpoint = fireauth.constants.Endpoint[endpointKey];\n return {\n 'firebaseEndpoint': endpoint.firebaseAuthEndpoint,\n 'secureTokenEndpoint': endpoint.secureTokenEndpoint,\n 'identityPlatformEndpoint': endpoint.identityPlatformEndpoint\n };\n }\n }\n return null;\n};\n\n\n/**\n * Returns the validated endpoint identifier. Undefined if the provided one is\n * invalid.\n * @param {?string=} opt_id The identifier of the endpoint type if available.\n * @return {string|undefined} The validated endpoint ID. If not valid,\n * undefined.\n */\nfireauth.constants.getEndpointId = function(opt_id) {\n if (opt_id && fireauth.constants.getEndpointConfig(opt_id)) {\n return opt_id;\n }\n return undefined;\n};\n\n\n/** @const {string|undefined} The current client endpoint. */\nfireauth.constants.clientEndpoint = fireauth.constants.getEndpointId('__EID__');\n\n\n/** @const {string} The required SAML provider ID prefix. */\nfireauth.constants.SAML_PREFIX = 'saml.';\n\n\n/** @const {string} The required OIDC provider ID prefix. */\nfireauth.constants.OIDC_PREFIX = 'oidc.';\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.Thenable');\n\n/** @suppress {extraRequire} used in complex type */\ngoog.requireType('goog.Promise'); // for the type reference.\n\n\n\n/**\n * Provides a more strict interface for Thenables in terms of\n * http://promisesaplus.com for interop with {@see goog.Promise}.\n *\n * @interface\n * @extends {IThenable<TYPE>}\n * @template TYPE\n */\ngoog.Thenable = function() {};\n\n\n/**\n * Adds callbacks that will operate on the result of the Thenable, returning a\n * new child Promise.\n *\n * If the Thenable is fulfilled, the `onFulfilled` callback will be\n * invoked with the fulfillment value as argument, and the child Promise will\n * be fulfilled with the return value of the callback. If the callback throws\n * an exception, the child Promise will be rejected with the thrown value\n * instead.\n *\n * If the Thenable is rejected, the `onRejected` callback will be invoked\n * with the rejection reason as argument, and the child Promise will be rejected\n * with the return value of the callback or thrown value.\n *\n * @param {?(function(this:THIS, TYPE): VALUE)=} opt_onFulfilled A\n * function that will be invoked with the fulfillment value if the Promise\n * is fulfilled.\n * @param {?(function(this:THIS, *): *)=} opt_onRejected A function that will\n * be invoked with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * with the default this.\n *\n * @return {RESULT} A new Promise that will receive the result\n * of the fulfillment or rejection callback.\n * @template VALUE\n * @template THIS\n *\n * When a Promise (or thenable) is returned from the fulfilled callback,\n * the result is the payload of that promise, not the promise itself.\n *\n * @template RESULT := type('goog.Promise',\n * cond(isUnknown(VALUE), unknown(),\n * mapunion(VALUE, (V) =>\n * cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'),\n * templateTypeOf(V, 0),\n * cond(sub(V, 'Thenable'),\n * unknown(),\n * V)))))\n * =:\n *\n */\ngoog.Thenable.prototype.then = function(\n opt_onFulfilled, opt_onRejected, opt_context) {};\n\n\n/**\n * An expando property to indicate that an object implements\n * `goog.Thenable`.\n *\n * {@see addImplementation}.\n *\n * @const\n */\ngoog.Thenable.IMPLEMENTED_BY_PROP = '$goog_Thenable';\n\n\n/**\n * Marks a given class (constructor) as an implementation of Thenable, so\n * that we can query that fact at runtime. The class must have already\n * implemented the interface.\n * Exports a 'then' method on the constructor prototype, so that the objects\n * also implement the extern {@see goog.Thenable} interface for interop with\n * other Promise implementations.\n * @param {function(new:goog.Thenable,...?)} ctor The class constructor. The\n * corresponding class must have already implemented the interface.\n */\ngoog.Thenable.addImplementation = function(ctor) {\n if (COMPILED) {\n ctor.prototype[goog.Thenable.IMPLEMENTED_BY_PROP] = true;\n } else {\n // Avoids dictionary access in uncompiled mode.\n ctor.prototype.$goog_Thenable = true;\n }\n};\n\n\n/**\n * @param {?} object\n * @return {boolean} Whether a given instance implements `goog.Thenable`.\n * The class/superclass of the instance must call `addImplementation`.\n */\ngoog.Thenable.isImplementedBy = function(object) {\n if (!object) {\n return false;\n }\n try {\n if (COMPILED) {\n return !!object[goog.Thenable.IMPLEMENTED_BY_PROP];\n }\n return !!object.$goog_Thenable;\n } catch (e) {\n // Property access seems to be forbidden.\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 a base class for custom Error objects such that the\n * stack is correctly maintained.\n *\n * You should never need to throw goog.debug.Error(msg) directly, Error(msg) is\n * sufficient.\n */\n\ngoog.provide('goog.debug.Error');\n\n\n\n/**\n * Base class for custom error objects.\n * @param {*=} opt_msg The message associated with the error.\n * @constructor\n * @extends {Error}\n */\ngoog.debug.Error = function(opt_msg) {\n\n // Attempt to ensure there is a stack trace.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, goog.debug.Error);\n } else {\n const stack = new Error().stack;\n if (stack) {\n /** @override */\n this.stack = stack;\n }\n }\n\n if (opt_msg) {\n /** @override */\n this.message = String(opt_msg);\n }\n\n /**\n * Whether to report this error to the server. Setting this to false will\n * cause the error reporter to not report the error back to the server,\n * which can be useful if the client knows that the error has already been\n * logged on the server.\n * @type {boolean}\n */\n this.reportErrorToServer = true;\n};\ngoog.inherits(goog.debug.Error, Error);\n\n\n/** @override */\ngoog.debug.Error.prototype.name = 'CustomError';\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities to check the preconditions, postconditions and\n * invariants runtime.\n *\n * Methods in this package are given special treatment by the compiler\n * for type-inference. For example, <code>goog.asserts.assert(foo)</code>\n * will make the compiler treat <code>foo</code> as non-nullable. Similarly,\n * <code>goog.asserts.assertNumber(foo)</code> informs the compiler about the\n * type of <code>foo</code>. Where applicable, such assertions are preferable to\n * casts by jsdoc with <code>@type</code>.\n *\n * The compiler has an option to disable asserts. So code like:\n * <code>\n * var x = goog.asserts.assert(foo());\n * goog.asserts.assert(bar());\n * </code>\n * will be transformed into:\n * <code>\n * var x = foo();\n * </code>\n * The compiler will leave in foo() (because its return value is used),\n * but it will remove bar() because it assumes it does not have side-effects.\n *\n * Additionally, note the compiler will consider the type to be \"tightened\" for\n * all statements <em>after</em> the assertion. For example:\n * <code>\n * const /** ?Object &#ast;/ value = foo();\n * goog.asserts.assert(value);\n * // \"value\" is of type {!Object} at this point.\n * </code>\n */\n\ngoog.provide('goog.asserts');\ngoog.provide('goog.asserts.AssertionError');\n\ngoog.require('goog.debug.Error');\ngoog.require('goog.dom.NodeType');\n\n\n/**\n * @define {boolean} Whether to strip out asserts or to leave them in.\n */\ngoog.asserts.ENABLE_ASSERTS =\n goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG);\n\n\n\n/**\n * Error object for failed assertions.\n * @param {string} messagePattern The pattern that was used to form message.\n * @param {!Array<*>} messageArgs The items to substitute into the pattern.\n * @constructor\n * @extends {goog.debug.Error}\n * @final\n */\ngoog.asserts.AssertionError = function(messagePattern, messageArgs) {\n goog.debug.Error.call(this, goog.asserts.subs_(messagePattern, messageArgs));\n\n /**\n * The message pattern used to format the error message. Error handlers can\n * use this to uniquely identify the assertion.\n * @type {string}\n */\n this.messagePattern = messagePattern;\n};\ngoog.inherits(goog.asserts.AssertionError, goog.debug.Error);\n\n\n/** @override */\ngoog.asserts.AssertionError.prototype.name = 'AssertionError';\n\n\n/**\n * The default error handler.\n * @param {!goog.asserts.AssertionError} e The exception to be handled.\n */\ngoog.asserts.DEFAULT_ERROR_HANDLER = function(e) {\n throw e;\n};\n\n\n/**\n * The handler responsible for throwing or logging assertion errors.\n * @private {function(!goog.asserts.AssertionError)}\n */\ngoog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;\n\n\n/**\n * Does simple python-style string substitution.\n * subs(\"foo%s hot%s\", \"bar\", \"dog\") becomes \"foobar hotdog\".\n * @param {string} pattern The string containing the pattern.\n * @param {!Array<*>} subs 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 * @private\n */\ngoog.asserts.subs_ = function(pattern, subs) {\n var splitParts = pattern.split('%s');\n var returnString = '';\n\n // Replace up to the last split part. We are inserting in the\n // positions between split parts.\n var subLast = splitParts.length - 1;\n for (var i = 0; i < subLast; i++) {\n // keep unsupplied as '%s'\n var sub = (i < subs.length) ? subs[i] : '%s';\n returnString += splitParts[i] + sub;\n }\n return returnString + splitParts[subLast];\n};\n\n\n/**\n * Throws an exception with the given message and \"Assertion failed\" prefixed\n * onto it.\n * @param {string} defaultMessage The message to use if givenMessage is empty.\n * @param {Array<*>} defaultArgs The substitution arguments for defaultMessage.\n * @param {string|undefined} givenMessage Message supplied by the caller.\n * @param {Array<*>} givenArgs The substitution arguments for givenMessage.\n * @throws {goog.asserts.AssertionError} When the value is not a number.\n * @private\n */\ngoog.asserts.doAssertFailure_ = function(\n defaultMessage, defaultArgs, givenMessage, givenArgs) {\n var message = 'Assertion failed';\n if (givenMessage) {\n message += ': ' + givenMessage;\n var args = givenArgs;\n } else if (defaultMessage) {\n message += ': ' + defaultMessage;\n args = defaultArgs;\n }\n // The '' + works around an Opera 10 bug in the unit tests. Without it,\n // a stack trace is added to var message above. With this, a stack trace is\n // not added until this line (it causes the extra garbage to be added after\n // the assertion message instead of in the middle of it).\n var e = new goog.asserts.AssertionError('' + message, args || []);\n goog.asserts.errorHandler_(e);\n};\n\n\n/**\n * Sets a custom error handler that can be used to customize the behavior of\n * assertion failures, for example by turning all assertion failures into log\n * messages.\n * @param {function(!goog.asserts.AssertionError)} errorHandler\n */\ngoog.asserts.setErrorHandler = function(errorHandler) {\n if (goog.asserts.ENABLE_ASSERTS) {\n goog.asserts.errorHandler_ = errorHandler;\n }\n};\n\n\n/**\n * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is\n * true.\n * @template T\n * @param {T} condition The condition to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {T} The value of the condition.\n * @throws {goog.asserts.AssertionError} When the condition evaluates to false.\n * @closurePrimitive {asserts.truthy}\n */\ngoog.asserts.assert = function(condition, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && !condition) {\n goog.asserts.doAssertFailure_(\n '', null, opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return condition;\n};\n\n\n/**\n * Checks if `value` is `null` or `undefined` if goog.asserts.ENABLE_ASSERTS is\n * true.\n *\n * @param {T} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {R} `value` with its type narrowed to exclude `null` and `undefined`.\n *\n * @template T\n * @template R :=\n * mapunion(T, (V) =>\n * cond(eq(V, 'null'),\n * none(),\n * cond(eq(V, 'undefined'),\n * none(),\n * V)))\n * =:\n *\n * @throws {!goog.asserts.AssertionError} When `value` is `null` or `undefined`.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertExists = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && value == null) {\n goog.asserts.doAssertFailure_(\n 'Expected to exist: %s.', [value], opt_message,\n Array.prototype.slice.call(arguments, 2));\n }\n return value;\n};\n\n\n/**\n * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case\n * when we want to add a check in the unreachable area like switch-case\n * statement:\n *\n * <pre>\n * switch(type) {\n * case FOO: doSomething(); break;\n * case BAR: doSomethingElse(); break;\n * default: goog.asserts.fail('Unrecognized type: ' + type);\n * // We have only 2 types - \"default:\" section is unreachable code.\n * }\n * </pre>\n *\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @throws {goog.asserts.AssertionError} Failure.\n * @closurePrimitive {asserts.fail}\n */\ngoog.asserts.fail = function(opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS) {\n goog.asserts.errorHandler_(new goog.asserts.AssertionError(\n 'Failure' + (opt_message ? ': ' + opt_message : ''),\n Array.prototype.slice.call(arguments, 1)));\n }\n};\n\n\n/**\n * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {number} The value, guaranteed to be a number when asserts enabled.\n * @throws {goog.asserts.AssertionError} When the value is not a number.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertNumber = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && typeof value !== 'number') {\n goog.asserts.doAssertFailure_(\n 'Expected number but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {number} */ (value);\n};\n\n\n/**\n * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {string} The value, guaranteed to be a string when asserts enabled.\n * @throws {goog.asserts.AssertionError} When the value is not a string.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertString = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && typeof value !== 'string') {\n goog.asserts.doAssertFailure_(\n 'Expected string but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {string} */ (value);\n};\n\n\n/**\n * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {!Function} The value, guaranteed to be a function when asserts\n * enabled.\n * @throws {goog.asserts.AssertionError} When the value is not a function.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertFunction = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {\n goog.asserts.doAssertFailure_(\n 'Expected function but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {!Function} */ (value);\n};\n\n\n/**\n * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {!Object} The value, guaranteed to be a non-null object.\n * @throws {goog.asserts.AssertionError} When the value is not an object.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertObject = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {\n goog.asserts.doAssertFailure_(\n 'Expected object but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {!Object} */ (value);\n};\n\n\n/**\n * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {!Array<?>} The value, guaranteed to be a non-null array.\n * @throws {goog.asserts.AssertionError} When the value is not an array.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertArray = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && !Array.isArray(value)) {\n goog.asserts.doAssertFailure_(\n 'Expected array but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {!Array<?>} */ (value);\n};\n\n\n/**\n * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {boolean} The value, guaranteed to be a boolean when asserts are\n * enabled.\n * @throws {goog.asserts.AssertionError} When the value is not a boolean.\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertBoolean = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && typeof value !== 'boolean') {\n goog.asserts.doAssertFailure_(\n 'Expected boolean but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {boolean} */ (value);\n};\n\n\n/**\n * Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @return {!Element} The value, likely to be a DOM Element when asserts are\n * enabled.\n * @throws {goog.asserts.AssertionError} When the value is not an Element.\n * @closurePrimitive {asserts.matchesReturn}\n * @deprecated Use goog.asserts.dom.assertIsElement instead.\n */\ngoog.asserts.assertElement = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS &&\n (!goog.isObject(value) ||\n /** @type {!Node} */ (value).nodeType != goog.dom.NodeType.ELEMENT)) {\n goog.asserts.doAssertFailure_(\n 'Expected Element but got %s: %s.', [goog.typeOf(value), value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {!Element} */ (value);\n};\n\n\n/**\n * Checks if the value is an instance of the user-defined type if\n * goog.asserts.ENABLE_ASSERTS is true.\n *\n * The compiler may tighten the type returned by this function.\n *\n * Do not use this to ensure a value is an HTMLElement or a subclass! Cross-\n * document DOM inherits from separate - though identical - browser classes, and\n * such a check will unexpectedly fail. Please use the methods in\n * goog.asserts.dom for these purposes.\n *\n * @param {?} value The value to check.\n * @param {function(new: T, ...)} type A user-defined constructor.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @throws {goog.asserts.AssertionError} When the value is not an instance of\n * type.\n * @return {T}\n * @template T\n * @closurePrimitive {asserts.matchesReturn}\n */\ngoog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {\n goog.asserts.doAssertFailure_(\n 'Expected instanceof %s but got %s.',\n [goog.asserts.getType_(type), goog.asserts.getType_(value)],\n opt_message, Array.prototype.slice.call(arguments, 3));\n }\n return value;\n};\n\n\n/**\n * Checks whether the value is a finite number, if goog.asserts.ENABLE_ASSERTS\n * is true.\n *\n * @param {*} value The value to check.\n * @param {string=} opt_message Error message in case of failure.\n * @param {...*} var_args The items to substitute into the failure message.\n * @throws {goog.asserts.AssertionError} When the value is not a number, or is\n * a non-finite number such as NaN, Infinity or -Infinity.\n * @return {number} The value initially passed in.\n */\ngoog.asserts.assertFinite = function(value, opt_message, var_args) {\n if (goog.asserts.ENABLE_ASSERTS &&\n (typeof value != 'number' || !isFinite(value))) {\n goog.asserts.doAssertFailure_(\n 'Expected %s to be a finite number but it is not.', [value],\n opt_message, Array.prototype.slice.call(arguments, 2));\n }\n return /** @type {number} */ (value);\n};\n\n/**\n * Checks that no enumerable keys are present in Object.prototype. Such keys\n * would break most code that use {@code for (var ... in ...)} loops.\n */\ngoog.asserts.assertObjectPrototypeIsIntact = function() {\n for (var key in Object.prototype) {\n goog.asserts.fail(key + ' should not be enumerable in Object.prototype.');\n }\n};\n\n\n/**\n * Returns the type of a value. If a constructor is passed, and a suitable\n * string cannot be found, 'unknown type name' will be returned.\n * @param {*} value A constructor, object, or primitive.\n * @return {string} The best display name for the value, or 'unknown type name'.\n * @private\n */\ngoog.asserts.getType_ = function(value) {\n if (value instanceof Function) {\n return value.displayName || value.name || 'unknown type name';\n } else if (value instanceof Object) {\n return /** @type {string} */ (value.constructor.displayName) ||\n value.constructor.name || Object.prototype.toString.call(value);\n } else {\n return value === null ? 'null' : typeof value;\n }\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 */\n\ngoog.provide('goog.async.FreeList');\n\n\n/**\n * @template ITEM\n */\ngoog.async.FreeList = class {\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 /**\n * @return {ITEM}\n */\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 /**\n * @param {ITEM} item An item available for possible future reuse.\n */\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 * @package\n * @return {number}\n */\n occupants() {\n return this.occupants_;\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.async.WorkItem');\ngoog.provide('goog.async.WorkQueue');\n\ngoog.require('goog.asserts');\ngoog.require('goog.async.FreeList');\n\n\n// TODO(johnlenz): generalize the WorkQueue if this is used by more\n// than goog.async.run.\n\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 * @constructor\n * @final\n * @struct\n */\ngoog.async.WorkQueue = function() {\n this.workHead_ = null;\n this.workTail_ = null;\n};\n\n\n/** @define {number} The maximum number of entries to keep for recycling. */\ngoog.async.WorkQueue.DEFAULT_MAX_UNUSED =\n goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);\n\n\n/** @const @private {goog.async.FreeList<goog.async.WorkItem>} */\ngoog.async.WorkQueue.freelist_ = new goog.async.FreeList(\n function() { return new goog.async.WorkItem(); },\n function(item) { item.reset(); }, goog.async.WorkQueue.DEFAULT_MAX_UNUSED);\n\n\n/**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\ngoog.async.WorkQueue.prototype.add = function(fn, scope) {\n var 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 goog.asserts.assert(!this.workHead_);\n this.workHead_ = item;\n this.workTail_ = item;\n }\n};\n\n\n/**\n * @return {goog.async.WorkItem}\n */\ngoog.async.WorkQueue.prototype.remove = function() {\n var 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/**\n * @param {goog.async.WorkItem} item\n */\ngoog.async.WorkQueue.prototype.returnUnused = function(item) {\n goog.async.WorkQueue.freelist_.put(item);\n};\n\n\n/**\n * @return {goog.async.WorkItem}\n * @private\n */\ngoog.async.WorkQueue.prototype.getUnusedItem_ = function() {\n return goog.async.WorkQueue.freelist_.get();\n};\n\n\n\n/**\n * @constructor\n * @final\n * @struct\n */\ngoog.async.WorkItem = function() {\n /** @type {?function()} */\n this.fn = null;\n /** @type {?Object|null|undefined} */\n this.scope = null;\n /** @type {?goog.async.WorkItem} */\n this.next = null;\n};\n\n\n/**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\ngoog.async.WorkItem.prototype.set = function(fn, scope) {\n this.fn = fn;\n this.scope = scope;\n this.next = null;\n};\n\n\n/** Reset the work item so they don't prevent GC before reuse */\ngoog.async.WorkItem.prototype.reset = function() {\n this.fn = null;\n this.scope = null;\n this.next = null;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.async.run');\n\ngoog.require('goog.async.WorkQueue');\ngoog.require('goog.async.nextTick');\ngoog.require('goog.async.throwException');\n\n/**\n * @define {boolean} If true, use the global Promise to implement goog.async.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 * 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=} opt_context Object to use as the \"this value\" when calling\n * the provided function.\n * @template THIS\n */\ngoog.async.run = function(callback, opt_context) {\n if (!goog.async.run.schedule_) {\n goog.async.run.initializeRunner_();\n }\n if (!goog.async.run.workQueueScheduled_) {\n // Nothing is currently scheduled, schedule it now.\n goog.async.run.schedule_();\n goog.async.run.workQueueScheduled_ = true;\n }\n\n goog.async.run.workQueue_.add(callback, opt_context);\n};\n\n\n/**\n * Initializes the function to use to process the work queue.\n * @private\n */\ngoog.async.run.initializeRunner_ = function() {\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 var promise = goog.global.Promise.resolve(undefined);\n goog.async.run.schedule_ = function() {\n promise.then(goog.async.run.processWorkQueue);\n };\n } else {\n goog.async.run.schedule_ = function() {\n goog.async.nextTick(goog.async.run.processWorkQueue);\n };\n }\n};\n\n\n/**\n * Forces goog.async.run to use nextTick instead of Promise.\n *\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 *\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 *\n * @param {function(function())=} opt_realSetTimeout\n */\ngoog.async.run.forceNextTick = function(opt_realSetTimeout) {\n goog.async.run.schedule_ = function() {\n goog.async.nextTick(goog.async.run.processWorkQueue);\n if (opt_realSetTimeout) {\n opt_realSetTimeout(goog.async.run.processWorkQueue);\n }\n };\n};\n\n\n/**\n * The function used to schedule work asynchronousely.\n * @private {function()}\n */\ngoog.async.run.schedule_;\n\n\n/** @private {boolean} */\ngoog.async.run.workQueueScheduled_ = false;\n\n\n/** @private {!goog.async.WorkQueue} */\ngoog.async.run.workQueue_ = new goog.async.WorkQueue();\n\n\nif (goog.DEBUG) {\n /**\n * Reset the work queue. Only available for tests in debug mode.\n */\n goog.async.run.resetQueue = function() {\n goog.async.run.workQueueScheduled_ = false;\n goog.async.run.workQueue_ = new goog.async.WorkQueue();\n };\n}\n\n\n/**\n * Run any pending goog.async.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 * goog.async.nextTick.\n */\ngoog.async.run.processWorkQueue = function() {\n // NOTE: additional work queue items may be added while processing.\n var item = null;\n while (item = goog.async.run.workQueue_.remove()) {\n try {\n item.fn.call(item.scope);\n } catch (e) {\n goog.async.throwException(e);\n }\n goog.async.run.workQueue_.returnUnused(item);\n }\n\n // There are no more work items, allow processing to be scheduled again.\n goog.async.run.workQueueScheduled_ = 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.provide('goog.array');\n\ngoog.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 */\ngoog.array.ASSUME_NATIVE_FUNCTIONS = goog.define(\n 'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as goog.array.last.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\ngoog.array.peek = function(array) {\n return array[array.length - 1];\n};\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as goog.array.peek.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\ngoog.array.last = goog.array.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 */\ngoog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\n function(arr, obj, opt_fromIndex) {\n goog.asserts.assert(arr.length != null);\n\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n var 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 (var i = fromIndex; i < arr.length; i++) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\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 */\ngoog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\n function(arr, obj, opt_fromIndex) {\n goog.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 var 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 var 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 (var i = fromIndex; i >= 0; i--) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\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 */\ngoog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\n function(arr, f, opt_obj) {\n goog.asserts.assert(arr.length != null);\n\n Array.prototype.forEach.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var i = 0; i < l; i++) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n };\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 */\ngoog.array.forEachRight = function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var i = l - 1; i >= 0; --i) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n};\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 */\ngoog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\n function(arr, f, opt_obj) {\n goog.asserts.assert(arr.length != null);\n\n return Array.prototype.filter.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var res = [];\n var resLength = 0;\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var i = 0; i < l; i++) {\n if (i in arr2) {\n var 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 };\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 */\ngoog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\n function(arr, f, opt_obj) {\n goog.asserts.assert(arr.length != null);\n\n return Array.prototype.map.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var res = new Array(l);\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var 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 };\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 *\n * For example:\n * var a = [1, 2, 3, 4];\n * goog.array.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 */\ngoog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\n function(arr, f, val, opt_obj) {\n goog.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 var rval = val;\n goog.array.forEach(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\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 * goog.array.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 */\ngoog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\n function(arr, f, val, opt_obj) {\n goog.asserts.assert(arr.length != null);\n goog.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 var rval = val;\n goog.array.forEachRight(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\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 */\ngoog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\n function(arr, f, opt_obj) {\n goog.asserts.assert(arr.length != null);\n\n return Array.prototype.some.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var 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 };\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 */\ngoog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&\n (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\n function(arr, f, opt_obj) {\n goog.asserts.assert(arr.length != null);\n\n return Array.prototype.every.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var 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 };\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 */\ngoog.array.count = function(arr, f, opt_obj) {\n var count = 0;\n goog.array.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};\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 */\ngoog.array.find = function(arr, f, opt_obj) {\n var i = goog.array.findIndex(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n};\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 */\ngoog.array.findIndex = function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var 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};\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 */\ngoog.array.findRight = function(arr, f, opt_obj) {\n var i = goog.array.findIndexRight(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n};\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 */\ngoog.array.findIndexRight = function(arr, f, opt_obj) {\n var l = arr.length; // must be fixed during loop... see docs\n var arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (var 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};\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 */\ngoog.array.contains = function(arr, obj) {\n return goog.array.indexOf(arr, obj) >= 0;\n};\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 */\ngoog.array.isEmpty = function(arr) {\n return arr.length == 0;\n};\n\n\n/**\n * Clears the array.\n * @param {IArrayLike<?>} arr Array or array like object to clear.\n */\ngoog.array.clear = function(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 (var i = arr.length - 1; i >= 0; i--) {\n delete arr[i];\n }\n }\n arr.length = 0;\n};\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 */\ngoog.array.insert = function(arr, obj) {\n if (!goog.array.contains(arr, obj)) {\n arr.push(obj);\n }\n};\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 */\ngoog.array.insertAt = function(arr, obj, opt_i) {\n goog.array.splice(arr, opt_i, 0, obj);\n};\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 */\ngoog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {\n goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);\n};\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 */\ngoog.array.insertBefore = function(arr, obj, opt_obj2) {\n var i;\n if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {\n arr.push(obj);\n } else {\n goog.array.insertAt(arr, obj, i);\n }\n};\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 */\ngoog.array.remove = function(arr, obj) {\n var i = goog.array.indexOf(arr, obj);\n var rv;\n if ((rv = i >= 0)) {\n goog.array.removeAt(arr, i);\n }\n return rv;\n};\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 */\ngoog.array.removeLast = function(arr, obj) {\n var i = goog.array.lastIndexOf(arr, obj);\n if (i >= 0) {\n goog.array.removeAt(arr, i);\n return true;\n }\n return false;\n};\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 */\ngoog.array.removeAt = function(arr, i) {\n goog.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};\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 */\ngoog.array.removeIf = function(arr, f, opt_obj) {\n var i = goog.array.findIndex(arr, f, opt_obj);\n if (i >= 0) {\n goog.array.removeAt(arr, i);\n return true;\n }\n return false;\n};\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 */\ngoog.array.removeAllIf = function(arr, f, opt_obj) {\n var removedCount = 0;\n goog.array.forEachRight(arr, function(val, index) {\n if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\n if (goog.array.removeAt(arr, index)) {\n removedCount++;\n }\n }\n });\n return removedCount;\n};\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 * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\n * goog.array.concat(0, [1, 2]) -> [0, 1, 2]\n * goog.array.concat([1, 2], null) -> [1, 2, null]\n *\n * There is bug in all current versions of IE (6, 7 and 8) where arrays created\n * in an iframe become corrupted soon (not immediately) after the iframe is\n * destroyed. This is common if loading data via goog.net.IframeIo, for example.\n * This corruption only affects the concat method which will start throwing\n * Catastrophic Errors (#-2147418113).\n *\n * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.\n *\n * Internally goog.array should use this, so that all methods will continue to\n * work on these broken array objects.\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 */\ngoog.array.concat = function(var_args) {\n return Array.prototype.concat.apply([], arguments);\n};\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 */\ngoog.array.join = function(var_args) {\n return Array.prototype.concat.apply([], arguments);\n};\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 */\ngoog.array.toArray = function(object) {\n var 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 var rv = new Array(length);\n for (var i = 0; i < length; i++) {\n rv[i] = object[i];\n }\n return rv;\n }\n return [];\n};\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 */\ngoog.array.clone = goog.array.toArray;\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 * goog.array.extend(a, [0, 1]);\n * a; // [0, 1]\n * goog.array.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 */\ngoog.array.extend = function(arr1, var_args) {\n for (var i = 1; i < arguments.length; i++) {\n var arr2 = arguments[i];\n if (goog.isArrayLike(arr2)) {\n var len1 = arr1.length || 0;\n var len2 = arr2.length || 0;\n arr1.length = len1 + len2;\n for (var j = 0; j < len2; j++) {\n arr1[len1 + j] = arr2[j];\n }\n } else {\n arr1.push(arr2);\n }\n }\n};\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 */\ngoog.array.splice = function(arr, index, howMany, var_args) {\n goog.asserts.assert(arr.length != null);\n\n return Array.prototype.splice.apply(arr, goog.array.slice(arguments, 1));\n};\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 */\ngoog.array.slice = function(arr, start, opt_end) {\n goog.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};\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 */\ngoog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {\n var returnArray = opt_rv || arr;\n var 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 var hashFn = opt_hashFn || defaultHashFn;\n\n var seen = {}, cursorInsert = 0, cursorRead = 0;\n while (cursorRead < arr.length) {\n var current = arr[cursorRead++];\n var 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};\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>goog.array.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 */\ngoog.array.binarySearch = function(arr, target, opt_compareFn) {\n return goog.array.binarySearch_(\n arr, opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,\n target);\n};\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 * goog.array.map(goog.array.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 */\ngoog.array.binarySelect = function(arr, evaluator, opt_obj) {\n return goog.array.binarySearch_(\n arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\n opt_obj);\n};\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 */\ngoog.array.binarySearch_ = function(\n arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n var left = 0; // inclusive\n var right = arr.length; // exclusive\n var found;\n while (left < right) {\n var middle = left + ((right - left) >>> 1);\n var 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>goog.array.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 <code>Array.prototype.sort</code>\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 */\ngoog.array.sort = function(arr, opt_compareFn) {\n // TODO(arv): Update type annotation since null is not accepted.\n arr.sort(opt_compareFn || goog.array.defaultCompare);\n};\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>goog.array.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 <code>Array.prototype.sort</code>, 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 */\ngoog.array.stableSort = function(arr, opt_compareFn) {\n var compArr = new Array(arr.length);\n for (var i = 0; i < arr.length; i++) {\n compArr[i] = {index: i, value: arr[i]};\n }\n var valueCompareFn = opt_compareFn || goog.array.defaultCompare;\n function stableCompareFn(obj1, obj2) {\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n }\n goog.array.sort(compArr, stableCompareFn);\n for (var i = 0; i < arr.length; i++) {\n arr[i] = compArr[i].value;\n }\n};\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>goog.array.defaultCompare</code>.\n *\n * Runtime: O(S(f(n)), where S is runtime of <code>goog.array.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 */\ngoog.array.sortByKey = function(arr, keyFn, opt_compareFn) {\n var keyCompareFn = opt_compareFn || goog.array.defaultCompare;\n goog.array.sort(\n arr, function(a, b) { return keyCompareFn(keyFn(a), keyFn(b)); });\n};\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>goog.array.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 */\ngoog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {\n goog.array.sortByKey(arr, function(obj) { return obj[key]; }, opt_compareFn);\n};\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 */\ngoog.array.isSorted = function(arr, opt_compareFn, opt_strict) {\n var compare = opt_compareFn || goog.array.defaultCompare;\n for (var i = 1; i < arr.length; i++) {\n var compareResult = compare(arr[i - 1], arr[i]);\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\n return false;\n }\n }\n return true;\n};\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<?>} arr1 The first array to compare.\n * @param {IArrayLike<?>} arr2 The second array to compare.\n * @param {Function=} 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 */\ngoog.array.equals = function(arr1, arr2, opt_equalsFn) {\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\n arr1.length != arr2.length) {\n return false;\n }\n var l = arr1.length;\n var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;\n for (var i = 0; i < l; i++) {\n if (!equalsFn(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n};\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 */\ngoog.array.compare3 = function(arr1, arr2, opt_compareFn) {\n var compare = opt_compareFn || goog.array.defaultCompare;\n var l = Math.min(arr1.length, arr2.length);\n for (var i = 0; i < l; i++) {\n var result = compare(arr1[i], arr2[i]);\n if (result != 0) {\n return result;\n }\n }\n return goog.array.defaultCompare(arr1.length, arr2.length);\n};\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 */\ngoog.array.defaultCompare = function(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n};\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 */\ngoog.array.inverseDefaultCompare = function(a, b) {\n return -goog.array.defaultCompare(a, b);\n};\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 */\ngoog.array.defaultCompareEquality = function(a, b) {\n return a === b;\n};\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 */\ngoog.array.binaryInsert = function(array, value, opt_compareFn) {\n var index = goog.array.binarySearch(array, value, opt_compareFn);\n if (index < 0) {\n goog.array.insertAt(array, value, -(index + 1));\n return true;\n }\n return false;\n};\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 */\ngoog.array.binaryRemove = function(array, value, opt_compareFn) {\n var index = goog.array.binarySearch(array, value, opt_compareFn);\n return (index >= 0) ? goog.array.removeAt(array, index) : false;\n};\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 */\ngoog.array.bucket = function(array, sorter, opt_obj) {\n var buckets = {};\n\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n var 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 var bucket = buckets[key] || (buckets[key] = []);\n bucket.push(value);\n }\n }\n\n return buckets;\n};\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 */\ngoog.array.toObject = function(arr, keyFunc, opt_obj) {\n var ret = {};\n goog.array.forEach(arr, function(element, index) {\n ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\n element;\n });\n return ret;\n};\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 */\ngoog.array.range = function(startOrEnd, opt_end, opt_step) {\n var array = [];\n var start = 0;\n var end = startOrEnd;\n var 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 (var i = start; i < end; i += step) {\n array.push(i);\n }\n } else {\n for (var i = start; i > end; i += step) {\n array.push(i);\n }\n }\n return array;\n};\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 */\ngoog.array.repeat = function(value, n) {\n var array = [];\n for (var i = 0; i < n; i++) {\n array[i] = value;\n }\n return array;\n};\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 */\ngoog.array.flatten = function(var_args) {\n var CHUNK_SIZE = 8192;\n\n var result = [];\n for (var i = 0; i < arguments.length; i++) {\n var element = arguments[i];\n if (Array.isArray(element)) {\n for (var c = 0; c < element.length; c += CHUNK_SIZE) {\n var chunk = goog.array.slice(element, c, c + CHUNK_SIZE);\n var recurseResult = goog.array.flatten.apply(null, chunk);\n for (var 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};\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 */\ngoog.array.rotate = function(array, n) {\n goog.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};\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 * {@code arr.length - 1}.\n * @param {number} toIndex Target index between 0 and {@code arr.length - 1}.\n */\ngoog.array.moveItem = function(arr, fromIndex, toIndex) {\n goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);\n // Remove 1 item at fromIndex.\n var 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};\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 */\ngoog.array.zip = function(var_args) {\n if (!arguments.length) {\n return [];\n }\n var result = [];\n var minLen = arguments[0].length;\n for (var i = 1; i < arguments.length; i++) {\n if (arguments[i].length < minLen) {\n minLen = arguments[i].length;\n }\n }\n for (var i = 0; i < minLen; i++) {\n var value = [];\n for (var j = 0; j < arguments.length; j++) {\n value.push(arguments[j][i]);\n }\n result.push(value);\n }\n return result;\n};\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 */\ngoog.array.shuffle = function(arr, opt_randFn) {\n var randFn = opt_randFn || Math.random;\n\n for (var i = arr.length - 1; i > 0; i--) {\n // Choose a random array index in [0, i] (inclusive with i).\n var j = Math.floor(randFn() * (i + 1));\n\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n }\n};\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 */\ngoog.array.copyByIndex = function(arr, index_arr) {\n var result = [];\n goog.array.forEach(index_arr, function(index) { result.push(arr[index]); });\n return result;\n};\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 */\ngoog.array.concatMap = function(arr, f, opt_obj) {\n return goog.array.concat.apply([], goog.array.map(arr, f, opt_obj));\n};\n","// Copyright 2006 The Closure Library Authors. All Rights Reserved.\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 * @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.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.structs');\ngoog.require('goog.structs.Map');\ngoog.require('goog.uri.utils');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.Uri');\n\ngoog.scope(function() {\n\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 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 {!goog.structs.Map}\n */\n this.headers = new goog.structs.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 statte 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};\ngoog.inherits(goog.net.XhrIo, goog.events.EventTarget);\n\nvar 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\nvar 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\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.structs.Map=} opt_headers Map of headers to add to the\n * 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 var 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 var 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 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 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 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 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 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 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 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 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 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 return this.progressEventsEnabled_;\n};\n\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.structs.Map=} opt_headers Map of headers to add to the\n * request.\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 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 var 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 this.xhr_.onprogress =\n goog.bind(function(e) { this.onProgressHandler_(e, true); }, this);\n if (this.xhr_.upload) {\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 var content = opt_content || '';\n\n var headers = this.headers.clone();\n\n // Add headers specific to this request\n if (opt_headers) {\n goog.structs.forEach(\n opt_headers, function(value, key) { headers.set(key, value); });\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 var contentTypeKey =\n goog.array.find(headers.getKeys(), goog.net.XhrIo.isContentTypeHeader_);\n\n var 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 headers.forEach(function(value, key) {\n this.xhr_.setRequestHeader(key, value);\n }, this);\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 this.xhr_.withCredentials = this.withCredentials_;\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_, 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 return goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9) &&\n typeof xhr[goog.net.XhrIo.XHR2_TIMEOUT_] === 'number' &&\n xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_] !== undefined;\n};\n\n\n/**\n * @param {string} header An HTTP header key.\n * @return {boolean} Whether the key is a content type header (ignoring\n * case.\n * @private\n */\ngoog.net.XhrIo.isContentTypeHeader_ = function(header) {\n return goog.string.caseInsensitiveEquals(\n goog.net.XhrIo.CONTENT_TYPE_HEADER, header);\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 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 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 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 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 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 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 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 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 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 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(\n goog.net.XhrIo.buildProgressEvent_(\n e, 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 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 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 var xhr = this.xhr_;\n var clearedOnReadyStateChange =\n this.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ?\n goog.nullFunction :\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 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 return !!this.xhr_;\n};\n\n\n/**\n * @return {boolean} Whether the request has completed.\n */\ngoog.net.XhrIo.prototype.isComplete = function() {\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 var 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 var scheme = goog.uri.utils.getEffectiveScheme(String(this.lastUri_));\n return goog.net.XhrIo.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 return this.xhr_ ?\n /** @type {goog.net.XmlHttp.ReadyState} */ (this.xhr_.readyState) :\n goog.net.XmlHttp.ReadyState\n .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 /**\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 /**\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 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 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 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 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 if (!this.xhr_) {\n return undefined;\n }\n\n var 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 */\ngoog.net.XhrIo.prototype.getResponse = function() {\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_, '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 if (!this.xhr_ || !this.isComplete()) {\n return undefined;\n }\n\n var 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 when called from the context of a callback\n * and the request has completed.\n * @return {string} The value of the response headers or empty string.\n */\ngoog.net.XhrIo.prototype.getAllResponseHeaders = function() {\n // getAllResponseHeaders can return null if no response has been received,\n // ensure we always return an empty string.\n return this.xhr_ && this.isComplete() ?\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 // TODO(user): Make this function parse headers as per the spec\n // (https://tools.ietf.org/html/rfc2616#section-4.2).\n\n var headersObject = {};\n var headersArray = this.getAllResponseHeaders().split('\\r\\n');\n for (var i = 0; i < headersArray.length; i++) {\n if (goog.string.isEmptyOrWhitespace(headersArray[i])) {\n continue;\n }\n var keyValue =\n goog.string.splitLimit(headersArray[i], ':', /* maxSplitCount= */ 1);\n var key = keyValue[0];\n var 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 var values = headersObject[key] || [];\n headersObject[key] = values;\n values.push(value);\n }\n\n return goog.object.map(headersObject, function(values) {\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 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 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 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 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 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 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 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 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 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 return goog.string.internal.caseInsensitiveCompare(\n prefix, str.substr(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 return (\n goog.string.internal.caseInsensitiveCompare(\n suffix, str.substr(str.length - suffix.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 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 // 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 return str.trim();\n } : function(str) {\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 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 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 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 // 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 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 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 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 if (left < right) {\n return -1;\n } else if (left > right) {\n return 1;\n }\n return 0;\n};\n","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\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 * @fileoverview Utilities used by goog.labs.userAgent tools. These functions\n * should not be used outside of goog.labs.userAgent.*.\n *\n */\n\ngoog.provide('goog.labs.userAgent.util');\n\ngoog.require('goog.string.internal');\n\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 * @private\n */\ngoog.labs.userAgent.util.getNativeUserAgentString_ = function() {\n var navigator = goog.labs.userAgent.util.getNavigator_();\n if (navigator) {\n var userAgent = navigator.userAgent;\n if (userAgent) {\n return userAgent;\n }\n }\n return '';\n};\n\n\n/**\n * Getter for the native navigator.\n * This is a separate function so it can be stubbed out in testing.\n * @return {Navigator}\n * @private\n */\ngoog.labs.userAgent.util.getNavigator_ = function() {\n return goog.global.navigator;\n};\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 * @private {string}\n */\ngoog.labs.userAgent.util.userAgent_ =\n goog.labs.userAgent.util.getNativeUserAgentString_();\n\n\n/**\n * Applications may override browser detection on the built in\n * navigator.userAgent object by setting this string. Set to null to use the\n * browser object instead.\n * @param {?string=} opt_userAgent The User-Agent override.\n */\ngoog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {\n goog.labs.userAgent.util.userAgent_ =\n opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_();\n};\n\n\n/**\n * @return {string} The user agent string.\n */\ngoog.labs.userAgent.util.getUserAgent = function() {\n return goog.labs.userAgent.util.userAgent_;\n};\n\n\n/**\n * @param {string} str\n * @return {boolean} Whether the user agent contains the given string.\n */\ngoog.labs.userAgent.util.matchUserAgent = function(str) {\n var userAgent = goog.labs.userAgent.util.getUserAgent();\n return goog.string.internal.contains(userAgent, str);\n};\n\n\n/**\n * @param {string} str\n * @return {boolean} Whether the user agent contains the given string, ignoring\n * case.\n */\ngoog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {\n var userAgent = goog.labs.userAgent.util.getUserAgent();\n return goog.string.internal.caseInsensitiveContains(userAgent, str);\n};\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\n * of the parenthetical.\n */\ngoog.labs.userAgent.util.extractVersionTuples = function(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 var versionRegExp = new RegExp(\n // Key. Note that a key may have a space.\n // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')\n '(\\\\w[\\\\w ]+)' +\n\n '/' + // slash\n '([^\\\\s]+)' + // version (i.e. '5.0b')\n '\\\\s*' + // whitespace\n '(?:\\\\((.*?)\\\\))?', // parenthetical info. parentheses not matched.\n 'g');\n\n var data = [];\n var 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","/**\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 */\n\ngoog.provide('goog.object');\n\n\n/**\n * Whether two values are not observably distinguishable. This\n * correctly detects that 0 is not the same as -0 and two NaNs are\n * practically equivalent.\n *\n * The implementation is as suggested by harmony:egal proposal.\n *\n * @param {*} v The first value to compare.\n * @param {*} v2 The second value to compare.\n * @return {boolean} Whether two values are not observably distinguishable.\n * @see http://wiki.ecmascript.org/doku.php?id=harmony:egal\n */\ngoog.object.is = function(v, v2) {\n if (v === v2) {\n // 0 === -0, but they are not identical.\n // We need the cast because the compiler requires that v2 is a\n // number (although 1/v2 works with non-number). We cast to ? to\n // stop the compiler from type-checking this statement.\n return v !== 0 || 1 / v === 1 / /** @type {?} */ (v2);\n }\n\n // NaN is non-reflexive: NaN !== NaN, although they are identical.\n return v !== v && v2 !== v2;\n};\n\n\n/**\n * Calls a function for each element in an object/map/hash.\n *\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\n * for every element. This function takes 3 arguments (the value, the\n * key and the object) and the return value is ignored.\n * @param {T=} opt_obj This is used as the 'this' object within f.\n * @template T,K,V\n */\ngoog.object.forEach = function(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/**\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 *\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\n * for every element. This\n * function takes 3 arguments (the value, the key and the object)\n * 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\n * element is not 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 */\ngoog.object.filter = function(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/**\n * For every element in an object/map/hash calls a function and inserts the\n * result into a new object.\n *\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\n * for every element. This function\n * takes 3 arguments (the value, the key and the object)\n * and should return something. The result will be inserted\n * into a 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 */\ngoog.object.map = function(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/**\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 *\n * @param {Object<K,V>} obj The object to check.\n * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to\n * call for every element. This function\n * takes 3 arguments (the value, the key and the object) and should\n * 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 */\ngoog.object.some = function(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/**\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 *\n * @param {Object<K,V>} obj The object to check.\n * @param {?function(this:T,V,?,Object<K,V>):boolean} f The function to\n * call for every element. This function\n * takes 3 arguments (the value, the key and the object) and should\n * 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 */\ngoog.object.every = function(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/**\n * Returns the number of key-value pairs in the object map.\n *\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 */\ngoog.object.getCount = function(obj) {\n let rv = 0;\n for (const key in obj) {\n rv++;\n }\n return rv;\n};\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 *\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 */\ngoog.object.getAnyKey = function(obj) {\n for (const key in obj) {\n return key;\n }\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 *\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 */\ngoog.object.getAnyValue = function(obj) {\n for (const key in obj) {\n return obj[key];\n }\n};\n\n\n/**\n * Whether the object/hash/map contains the given object as a value.\n * An alias for goog.object.containsValue(obj, val).\n *\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 */\ngoog.object.contains = function(obj, val) {\n return goog.object.containsValue(obj, val);\n};\n\n\n/**\n * Returns the values of the object/map/hash.\n *\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 */\ngoog.object.getValues = function(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/**\n * Returns the keys of the object/map/hash.\n *\n * @param {Object} obj The object from which to get the keys.\n * @return {!Array<string>} Array of property keys.\n */\ngoog.object.getKeys = function(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/**\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 *\n * @param {!Object} obj An object to get the value from. Can be array-like.\n * @param {...(string|number|!IArrayLike<number|string>)}\n * var_args A number of keys\n * (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\n * in the current object is null or undefined, returns undefined.\n */\ngoog.object.getValueByKeys = function(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/**\n * Whether the object/map/hash contains the given key.\n *\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 */\ngoog.object.containsKey = function(obj, key) {\n return obj !== null && key in obj;\n};\n\n\n/**\n * Whether the object/map/hash contains the given value. This is O(n).\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 */\ngoog.object.containsValue = function(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/**\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\n * function to call for every element. Takes 3 arguments (the value,\n * the key and the object) and should return a boolean.\n * @param {T=} opt_this 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 */\ngoog.object.findKey = function(obj, f, opt_this) {\n for (const key in obj) {\n if (f.call(/** @type {?} */ (opt_this), obj[key], key, obj)) {\n return key;\n }\n }\n return undefined;\n};\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\n * to call for every element. Takes 3 arguments (the value, the key\n * and the object) and should return a boolean.\n * @param {T=} opt_this 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 */\ngoog.object.findValue = function(obj, f, opt_this) {\n const key = goog.object.findKey(obj, f, opt_this);\n return key && obj[key];\n};\n\n\n/**\n * Whether the object/map/hash is empty.\n *\n * @param {Object} obj The object to test.\n * @return {boolean} true if obj is empty.\n */\ngoog.object.isEmpty = function(obj) {\n for (const key in obj) {\n return false;\n }\n return true;\n};\n\n\n/**\n * Removes all key value pairs from the object/map/hash.\n *\n * @param {Object} obj The object to clear.\n */\ngoog.object.clear = function(obj) {\n for (const i in obj) {\n delete obj[i];\n }\n};\n\n\n/**\n * Removes a key-value pair based on the key.\n *\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 */\ngoog.object.remove = function(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/**\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 *\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 * @template K,V\n */\ngoog.object.add = function(obj, key, val) {\n if (obj !== null && key in obj) {\n throw new Error('The object already contains the key \"' + key + '\"');\n }\n goog.object.set(obj, key, val);\n};\n\n\n/**\n * Returns the value for the given key.\n *\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=} opt_val The value to return if no item is found for the given\n * key (default is undefined).\n * @return {V|R|undefined} The value for the given key.\n * @template K,V,R\n */\ngoog.object.get = function(obj, key, opt_val) {\n if (obj !== null && key in obj) {\n return obj[key];\n }\n return opt_val;\n};\n\n\n/**\n * Adds a key-value pair to the object/map/hash.\n *\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 */\ngoog.object.set = function(obj, key, value) {\n obj[key] = value;\n};\n\n\n/**\n * Adds a key-value pair to the object/map/hash if it doesn't exist yet.\n *\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 */\ngoog.object.setIfUndefined = function(obj, key, value) {\n return key in /** @type {!Object} */ (obj) ? obj[key] : (obj[key] = value);\n};\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 *\n * This function is particularly useful when used with an `Object` which is\n * acting as a cache.\n *\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 */\ngoog.object.setWithReturnValueIfNotSet = function(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/**\n * Compares two objects for equality using === on the values.\n *\n * @param {!Object<K,V>} a\n * @param {!Object<K,V>} b\n * @return {boolean}\n * @template K,V\n */\ngoog.object.equals = function(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/**\n * Returns a shallow clone of the object.\n *\n * @param {Object<K,V>} obj Object to clone.\n * @return {!Object<K,V>} Clone of the input object.\n * @template K,V\n */\ngoog.object.clone = function(obj) {\n // We cannot use the prototype trick because a lot of methods depend on where\n // the actual key is set.\n\n const res = {};\n for (const key in obj) {\n res[key] = obj[key];\n }\n return res;\n // We could also use goog.mixin but I wanted this to be independent from that.\n};\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.object.unsafeClone</code> does not detect reference loops. Objects\n * that refer to themselves will cause infinite recursion.\n *\n * <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and\n * copies UIDs created by <code>getUid</code> into cloned results.\n *\n * @param {T} obj The value to clone.\n * @return {T} A clone of the input value.\n * @template T\n */\ngoog.object.unsafeClone = function(obj) {\n const type = goog.typeOf(obj);\n if (type == 'object' || type == 'array') {\n if (goog.isFunction(obj.clone)) {\n return obj.clone();\n }\n const clone = type == 'array' ? [] : {};\n for (const key in obj) {\n clone[key] = goog.object.unsafeClone(obj[key]);\n }\n return clone;\n }\n\n return obj;\n};\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 *\n * @param {Object} obj The object to transpose.\n * @return {!Object} The transposed object.\n */\ngoog.object.transpose = function(obj) {\n const transposed = {};\n for (const key in obj) {\n transposed[obj[key]] = key;\n }\n return transposed;\n};\n\n\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {Array<string>}\n * @private\n */\ngoog.object.PROTOTYPE_FIELDS_ = [\n 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\n 'toLocaleString', 'toString', 'valueOf'\n];\n\n\n/**\n * Extends an object with another object.\n * This operates 'in-place'; it does not create a new Object.\n *\n * Example:\n * var o = {};\n * goog.object.extend(o, {a: 0, b: 1});\n * o; // {a: 0, b: 1}\n * goog.object.extend(o, {b: 2, c: 3});\n * o; // {a: 0, b: 2, c: 3}\n *\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\n * `var_args`.\n * @param {...(Object|null|undefined)} var_args The objects from which values\n * will be copied.\n * @deprecated Prefer Object.assign\n */\ngoog.object.extend = function(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 < goog.object.PROTOTYPE_FIELDS_.length; j++) {\n key = goog.object.PROTOTYPE_FIELDS_[j];\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\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 */\ngoog.object.create = function(var_args) {\n const argLength = arguments.length;\n if (argLength == 1 && Array.isArray(arguments[0])) {\n return goog.object.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/**\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\n * as the property names.\n * @return {!Object} The new object.\n */\ngoog.object.createSet = function(var_args) {\n const argLength = arguments.length;\n if (argLength == 1 && Array.isArray(arguments[0])) {\n return goog.object.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/**\n * Creates an immutable view of the underlying object, if the browser\n * supports immutable objects.\n *\n * In default mode, writes to this view will fail silently. In strict mode,\n * they will throw an error.\n *\n * @param {!Object<K,V>} obj An object.\n * @return {!Object<K,V>} An immutable view of that object, or the\n * original object if this browser does not support immutables.\n * @template K,V\n */\ngoog.object.createImmutableView = function(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/**\n * @param {!Object} obj An object.\n * @return {boolean} Whether this is an immutable view of the object.\n */\ngoog.object.isImmutableView = function(obj) {\n return !!Object.isFrozen && Object.isFrozen(obj);\n};\n\n\n/**\n * Get all properties names on a given Object regardless of enumerability.\n *\n * <p> If the browser does not support `Object.getOwnPropertyNames` nor\n * `Object.getPrototypeOf` then this is equivalent to using\n * `goog.object.getKeys`\n *\n * @param {?Object} obj The object to get the properties of.\n * @param {boolean=} opt_includeObjectPrototype Whether properties defined on\n * `Object.prototype` should be included in the result.\n * @param {boolean=} opt_includeFunctionPrototype Whether properties defined on\n * `Function.prototype` should be included in the result.\n * @return {!Array<string>}\n * @public\n */\ngoog.object.getAllPropertyNames = function(\n obj, opt_includeObjectPrototype, opt_includeFunctionPrototype) {\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 goog.object.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 &&\n (proto !== Object.prototype || !!opt_includeObjectPrototype) &&\n (proto !== Function.prototype || !!opt_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 goog.object.getKeys(visitedSet);\n};\n\n\n/**\n * Given a ES5 or ES6 class reference, return its super class / super\n * constructor.\n *\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 *\n * Note: To start walking up the hierarchy from an instance call this with its\n * `constructor` property; e.g. `getSuperClass(instance.constructor)`.\n *\n * @param {function(new: ?)} constructor\n * @return {?Object}\n */\ngoog.object.getSuperClass = function(constructor) {\n var proto = Object.getPrototypeOf(constructor.prototype);\n return proto && proto.constructor;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.dom.asserts');\n\ngoog.require('goog.asserts');\n\n/**\n * @fileoverview Custom assertions to ensure that an element has the appropriate\n * type.\n *\n * Using a goog.dom.safe wrapper on an object on the incorrect type (via an\n * incorrect static type cast) can result in security bugs: For instance,\n * g.d.s.setAnchorHref ensures that the URL assigned to the .href attribute\n * satisfies the SafeUrl contract, i.e., is safe to dereference as a hyperlink.\n * However, the value assigned to a HTMLLinkElement's .href property requires\n * the stronger TrustedResourceUrl contract, since it can refer to a stylesheet.\n * Thus, using g.d.s.setAnchorHref on an (incorrectly statically typed) object\n * of type HTMLLinkElement can result in a security vulnerability.\n * Assertions of the correct run-time type help prevent such incorrect use.\n *\n * In some cases, code using the DOM API is tested using mock objects (e.g., a\n * plain object such as {'href': url} instead of an actual Location object).\n * To allow such mocking, the assertions permit objects of types that are not\n * relevant DOM API objects at all (for instance, not Element or Location).\n *\n * Note that instanceof checks don't work straightforwardly in older versions of\n * IE, or across frames (see,\n * http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object,\n * http://stackoverflow.com/questions/26248599/instanceof-htmlelement-in-iframe-is-not-element-or-object).\n *\n * Hence, these assertions may pass vacuously in such scenarios. The resulting\n * risk of security bugs is limited by the following factors:\n * - A bug can only arise in scenarios involving incorrect static typing (the\n * wrapper methods are statically typed to demand objects of the appropriate,\n * precise type).\n * - Typically, code is tested and exercised in multiple browsers.\n */\n\n/**\n * Asserts that a given object is a Location.\n *\n * To permit this assertion to pass in the context of tests where DOM APIs might\n * be mocked, also accepts any other type except for subtypes of {!Element}.\n * This is to ensure that, for instance, HTMLLinkElement is not being used in\n * place of a Location, since this could result in security bugs due to stronger\n * contracts required for assignments to the href property of the latter.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!Location}\n */\ngoog.dom.asserts.assertIsLocation = function(o) {\n if (goog.asserts.ENABLE_ASSERTS) {\n var win = goog.dom.asserts.getWindow_(o);\n if (win) {\n if (!o || (!(o instanceof win.Location) && o instanceof win.Element)) {\n goog.asserts.fail(\n 'Argument is not a Location (or a non-Element mock); got: %s',\n goog.dom.asserts.debugStringForType_(o));\n }\n }\n }\n return /** @type {!Location} */ (o);\n};\n\n\n/**\n * Asserts that a given object is either the given subtype of Element\n * or a non-Element, non-Location Mock.\n *\n * To permit this assertion to pass in the context of tests where DOM\n * APIs might be mocked, also accepts any other type except for\n * subtypes of {!Element}. This is to ensure that, for instance,\n * HTMLScriptElement is not being used in place of a HTMLImageElement,\n * since this could result in security bugs due to stronger contracts\n * required for assignments to the src property of the latter.\n *\n * The DOM type is looked up in the window the object belongs to. In\n * some contexts, this might not be possible (e.g. when running tests\n * outside a browser, cross-domain lookup). In this case, the\n * assertions are skipped.\n *\n * @param {?Object} o The object whose type to assert.\n * @param {string} typename The name of the DOM type.\n * @return {!Element} The object.\n * @private\n */\n// TODO(bangert): Make an analog of goog.dom.TagName to correctly handle casts?\ngoog.dom.asserts.assertIsElementType_ = function(o, typename) {\n if (goog.asserts.ENABLE_ASSERTS) {\n var win = goog.dom.asserts.getWindow_(o);\n if (win && typeof win[typename] != 'undefined') {\n if (!o ||\n (!(o instanceof win[typename]) &&\n (o instanceof win.Location || o instanceof win.Element))) {\n goog.asserts.fail(\n 'Argument is not a %s (or a non-Element, non-Location mock); ' +\n 'got: %s',\n typename, goog.dom.asserts.debugStringForType_(o));\n }\n }\n }\n return /** @type {!Element} */ (o);\n};\n\n/**\n * Asserts that a given object is a HTMLAnchorElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not of type Location nor a subtype\n * of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLAnchorElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlAnchorElement instead.\n */\ngoog.dom.asserts.assertIsHTMLAnchorElement = function(o) {\n return /** @type {!HTMLAnchorElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLAnchorElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLButtonElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLButtonElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlButtonElement instead.\n */\ngoog.dom.asserts.assertIsHTMLButtonElement = function(o) {\n return /** @type {!HTMLButtonElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLButtonElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLLinkElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLLinkElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlLinkElement instead.\n */\ngoog.dom.asserts.assertIsHTMLLinkElement = function(o) {\n return /** @type {!HTMLLinkElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLLinkElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLImageElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLImageElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlImageElement instead.\n */\ngoog.dom.asserts.assertIsHTMLImageElement = function(o) {\n return /** @type {!HTMLImageElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLImageElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLAudioElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLAudioElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlAudioElement instead.\n */\ngoog.dom.asserts.assertIsHTMLAudioElement = function(o) {\n return /** @type {!HTMLAudioElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLAudioElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLVideoElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLVideoElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlVideoElement instead.\n */\ngoog.dom.asserts.assertIsHTMLVideoElement = function(o) {\n return /** @type {!HTMLVideoElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLVideoElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLInputElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLInputElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlInputElement instead.\n */\ngoog.dom.asserts.assertIsHTMLInputElement = function(o) {\n return /** @type {!HTMLInputElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLInputElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLTextAreaElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLTextAreaElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlTextAreaElement instead.\n */\ngoog.dom.asserts.assertIsHTMLTextAreaElement = function(o) {\n return /** @type {!HTMLTextAreaElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLTextAreaElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLCanvasElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLCanvasElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlCanvasElement instead.\n */\ngoog.dom.asserts.assertIsHTMLCanvasElement = function(o) {\n return /** @type {!HTMLCanvasElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLCanvasElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLEmbedElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLEmbedElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlEmbedElement instead.\n */\ngoog.dom.asserts.assertIsHTMLEmbedElement = function(o) {\n return /** @type {!HTMLEmbedElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLEmbedElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLFormElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLFormElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlFormElement instead.\n */\ngoog.dom.asserts.assertIsHTMLFormElement = function(o) {\n return /** @type {!HTMLFormElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLFormElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLFrameElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLFrameElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlFrameElement instead.\n */\ngoog.dom.asserts.assertIsHTMLFrameElement = function(o) {\n return /** @type {!HTMLFrameElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLFrameElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLIFrameElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLIFrameElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlIFrameElement instead.\n */\ngoog.dom.asserts.assertIsHTMLIFrameElement = function(o) {\n return /** @type {!HTMLIFrameElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLIFrameElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLObjectElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLObjectElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlObjectElement instead.\n */\ngoog.dom.asserts.assertIsHTMLObjectElement = function(o) {\n return /** @type {!HTMLObjectElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLObjectElement'));\n};\n\n/**\n * Asserts that a given object is a HTMLScriptElement.\n *\n * To permit this assertion to pass in the context of tests where elements might\n * be mocked, also accepts objects that are not a subtype of Element.\n *\n * @param {?Object} o The object whose type to assert.\n * @return {!HTMLScriptElement}\n * @deprecated Use goog.asserts.dom.assertIsHtmlScriptElement instead.\n */\ngoog.dom.asserts.assertIsHTMLScriptElement = function(o) {\n return /** @type {!HTMLScriptElement} */ (\n goog.dom.asserts.assertIsElementType_(o, 'HTMLScriptElement'));\n};\n\n/**\n * Returns a string representation of a value's type.\n *\n * @param {*} value An object, or primitive.\n * @return {string} The best display name for the value.\n * @private\n */\ngoog.dom.asserts.debugStringForType_ = function(value) {\n if (goog.isObject(value)) {\n try {\n return /** @type {string|undefined} */ (value.constructor.displayName) ||\n value.constructor.name || Object.prototype.toString.call(value);\n } catch (e) {\n return '<object could not be stringified>';\n }\n } else {\n return value === undefined ? 'undefined' :\n value === null ? 'null' : typeof value;\n }\n};\n\n/**\n * Gets window of element.\n * @param {?Object} o\n * @return {?Window}\n * @private\n * @suppress {strictMissingProperties} ownerDocument not defined on Object\n */\ngoog.dom.asserts.getWindow_ = function(o) {\n try {\n var doc = o && o.ownerDocument;\n // This can throw “Blocked a frame with origin \"chrome-extension://...\" from\n // accessing a cross-origin frame” in Chrome extension.\n var win =\n doc && /** @type {?Window} */ (doc.defaultView || doc.parentWindow);\n win = win || /** @type {!Window} */ (goog.global);\n // This can throw “Permission denied to access property \"Element\" on\n // cross-origin object”.\n if (win.Element && win.Location) {\n return win;\n }\n } catch (ex) {\n }\n return null;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.string.Const');\n\ngoog.require('goog.asserts');\ngoog.require('goog.string.TypedString');\n\n\n\n/**\n * Wrapper for compile-time-constant strings.\n *\n * Const is a wrapper for strings that can only be created from program\n * constants (i.e., string literals). This property relies on a custom Closure\n * compiler check that `goog.string.Const.from` is only invoked on\n * compile-time-constant expressions.\n *\n * Const is useful in APIs whose correct and secure use requires that certain\n * arguments are not attacker controlled: Compile-time constants are inherently\n * under the control of the application and not under control of external\n * attackers, and hence are safe to use in such contexts.\n *\n * Instances of this type must be created via its factory method\n * `goog.string.Const.from` and not by invoking its constructor. The\n * constructor intentionally takes no parameters and the type is immutable;\n * hence only a default instance corresponding to the empty string can be\n * obtained via constructor invocation. Use goog.string.Const.EMPTY\n * instead of using this constructor to get an empty Const string.\n *\n * @see goog.string.Const#from\n * @constructor\n * @final\n * @struct\n * @implements {goog.string.TypedString}\n * @param {Object=} opt_token package-internal implementation detail.\n * @param {string=} opt_content package-internal implementation detail.\n */\ngoog.string.Const = function(opt_token, opt_content) {\n /**\n * The wrapped value of this Const object. The field has a purposely ugly\n * name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @private {string}\n */\n this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ =\n ((opt_token ===\n goog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_) &&\n opt_content) ||\n '';\n\n /**\n * A type marker used to implement additional run-time type checking.\n * @see goog.string.Const#unwrap\n * @const {!Object}\n * @private\n */\n this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ =\n goog.string.Const.TYPE_MARKER_;\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.string.Const.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this Const's value a string.\n *\n * IMPORTANT: In code where it is security-relevant that an object's type is\n * indeed `goog.string.Const`, use `goog.string.Const.unwrap`\n * instead of this method.\n *\n * @see goog.string.Const#unwrap\n * @override\n */\ngoog.string.Const.prototype.getTypedStringValue = function() {\n return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_;\n};\n\n\nif (goog.DEBUG) {\n /**\n * Returns a debug-string representation of this value.\n *\n * To obtain the actual string value wrapped inside an object of this type,\n * use `goog.string.Const.unwrap`.\n *\n * @see goog.string.Const#unwrap\n * @override\n */\n goog.string.Const.prototype.toString = function() {\n return 'Const{' +\n this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ +\n '}';\n };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed an instance\n * of `goog.string.Const`, and returns its value.\n * @param {!goog.string.Const} stringConst The object to extract from.\n * @return {string} The Const object's contained string, unless the run-time\n * type check fails. In that case, `unwrap` returns an innocuous\n * string, or, if assertions are enabled, throws\n * `goog.asserts.AssertionError`.\n */\ngoog.string.Const.unwrap = function(stringConst) {\n // Perform additional run-time type-checking to ensure that stringConst is\n // indeed an instance of the expected type. This provides some additional\n // protection against security bugs due to application code that disables type\n // checks.\n if (stringConst instanceof goog.string.Const &&\n stringConst.constructor === goog.string.Const &&\n stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ ===\n goog.string.Const.TYPE_MARKER_) {\n return stringConst\n .stringConstValueWithSecurityContract__googStringSecurityPrivate_;\n } else {\n goog.asserts.fail(\n 'expected object of type Const, got \\'' + stringConst + '\\'');\n return 'type_error:Const';\n }\n};\n\n\n/**\n * Creates a Const object from a compile-time constant string.\n *\n * It is illegal to invoke this function on an expression whose\n * compile-time-constant value cannot be determined by the Closure compiler.\n *\n * Correct invocations include,\n * <pre>\n * var s = goog.string.Const.from('hello');\n * var t = goog.string.Const.from('hello' + 'world');\n * </pre>\n *\n * In contrast, the following are illegal:\n * <pre>\n * var s = goog.string.Const.from(getHello());\n * var t = goog.string.Const.from('hello' + world);\n * </pre>\n *\n * @param {string} s A constant string from which to create a Const.\n * @return {!goog.string.Const} A Const object initialized to stringConst.\n */\ngoog.string.Const.from = function(s) {\n return new goog.string.Const(\n goog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_, s);\n};\n\n/**\n * Type marker for the Const type, used to implement additional run-time\n * type checking.\n * @const {!Object}\n * @private\n */\ngoog.string.Const.TYPE_MARKER_ = {};\n\n/**\n * @type {!Object}\n * @private\n * @const\n */\ngoog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n\n/**\n * A Const instance wrapping the empty string.\n * @const {!goog.string.Const}\n */\ngoog.string.Const.EMPTY = goog.string.Const.from('');\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The TrustedResourceUrl type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.provide('goog.html.TrustedResourceUrl');\n\ngoog.require('goog.asserts');\ngoog.require('goog.fs.blob');\ngoog.require('goog.fs.url');\ngoog.require('goog.html.SafeScript');\ngoog.require('goog.html.trustedtypes');\ngoog.require('goog.i18n.bidi.Dir');\ngoog.require('goog.i18n.bidi.DirectionalString');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.TypedString');\n\n\n\n/**\n * A URL which is under application control and from which script, CSS, and\n * other resources that represent executable code, can be fetched.\n *\n * Given that the URL can only be constructed from strings under application\n * control and is used to load resources, bugs resulting in a malformed URL\n * should not have a security impact and are likely to be easily detectable\n * during testing. Given the wide number of non-RFC compliant URLs in use,\n * stricter validation could prevent some applications from being able to use\n * this type.\n *\n * Instances of this type must be created via the factory method,\n * (`fromConstant`, `fromConstants`, `format` or\n * `formatWithParams`), and not by invoking its constructor. The constructor\n * is organized in a way that only methods from that file can call it and\n * initialize with non-empty values. Anyone else calling constructor will\n * get default instance with empty value.\n *\n * @see goog.html.TrustedResourceUrl#fromConstant\n * @constructor\n * @final\n * @struct\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n * @param {!Object=} opt_token package-internal implementation detail.\n * @param {!TrustedScriptURL|string=} opt_content package-internal\n * implementation detail.\n */\ngoog.html.TrustedResourceUrl = function(opt_token, opt_content) {\n /**\n * The contained value of this TrustedResourceUrl. The field has a purposely\n * ugly name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @const\n * @private {!TrustedScriptURL|string}\n */\n this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ =\n ((opt_token ===\n goog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_) &&\n opt_content) ||\n '';\n\n /**\n * A type marker used to implement additional run-time type checking.\n * @see goog.html.TrustedResourceUrl#unwrap\n * @const {!Object}\n * @private\n */\n this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =\n goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this TrustedResourceUrl's value as a string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `TrustedResourceUrl`, use\n * `goog.html.TrustedResourceUrl.unwrap` instead of this method. If in\n * doubt, assume that it's security relevant. In particular, note that\n * goog.html functions which return a goog.html type do not guarantee that\n * the returned instance is of the right type. For example:\n *\n * <pre>\n * var fakeSafeHtml = new String('fake');\n * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;\n * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);\n * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\n * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof\n * // goog.html.SafeHtml.\n * </pre>\n *\n * @see goog.html.TrustedResourceUrl#unwrap\n * @override\n */\ngoog.html.TrustedResourceUrl.prototype.getTypedStringValue = function() {\n return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_\n .toString();\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString =\n true;\n\n\n/**\n * Returns this URLs directionality, which is always `LTR`.\n * @override\n */\ngoog.html.TrustedResourceUrl.prototype.getDirection = function() {\n return goog.i18n.bidi.Dir.LTR;\n};\n\n\n/**\n * Creates a new TrustedResourceUrl with params added to URL. Both search and\n * hash params can be specified.\n *\n * @param {string|?Object<string, *>|undefined} searchParams Search parameters\n * to add to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for\n * exact format definition.\n * @param {(string|?Object<string, *>)=} opt_hashParams Hash parameters to add\n * to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for exact\n * format definition.\n * @return {!goog.html.TrustedResourceUrl} New TrustedResourceUrl with params.\n */\ngoog.html.TrustedResourceUrl.prototype.cloneWithParams = function(\n searchParams, opt_hashParams) {\n var url = goog.html.TrustedResourceUrl.unwrap(this);\n var parts = goog.html.TrustedResourceUrl.URL_PARAM_PARSER_.exec(url);\n var urlBase = parts[1];\n var urlSearch = parts[2] || '';\n var urlHash = parts[3] || '';\n\n return goog.html.TrustedResourceUrl\n .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(\n urlBase +\n goog.html.TrustedResourceUrl.stringifyParams_(\n '?', urlSearch, searchParams) +\n goog.html.TrustedResourceUrl.stringifyParams_(\n '#', urlHash, opt_hashParams));\n};\n\n\nif (goog.DEBUG) {\n /**\n * Returns a debug string-representation of this value.\n *\n * To obtain the actual string value wrapped in a TrustedResourceUrl, use\n * `goog.html.TrustedResourceUrl.unwrap`.\n *\n * @see goog.html.TrustedResourceUrl#unwrap\n * @override\n */\n goog.html.TrustedResourceUrl.prototype.toString = function() {\n return 'TrustedResourceUrl{' +\n this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ + '}';\n };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed a\n * TrustedResourceUrl object, and returns its value.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl The object to\n * extract from.\n * @return {string} The trustedResourceUrl object's contained string, unless\n * the run-time type check fails. In that case, `unwrap` returns an\n * innocuous string, or, if assertions are enabled, throws\n * `goog.asserts.AssertionError`.\n */\ngoog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) {\n return goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(trustedResourceUrl)\n .toString();\n};\n\n\n/**\n * Unwraps value as TrustedScriptURL if supported or as a string if not.\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl\n * @return {!TrustedScriptURL|string}\n * @see goog.html.TrustedResourceUrl.unwrap\n */\ngoog.html.TrustedResourceUrl.unwrapTrustedScriptURL = function(\n trustedResourceUrl) {\n // Perform additional Run-time type-checking to ensure that\n // trustedResourceUrl is indeed an instance of the expected type. This\n // provides some additional protection against security bugs due to\n // application code that disables type checks.\n // Specifically, the following checks are performed:\n // 1. The object is an instance of the expected type.\n // 2. The object is not an instance of a subclass.\n // 3. The object carries a type marker for the expected type. \"Faking\" an\n // object requires a reference to the type marker, which has names intended\n // to stand out in code reviews.\n if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl &&\n trustedResourceUrl.constructor === goog.html.TrustedResourceUrl &&\n trustedResourceUrl\n .TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===\n goog.html.TrustedResourceUrl\n .TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n return trustedResourceUrl\n .privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;\n } else {\n goog.asserts.fail('expected object of type TrustedResourceUrl, got \\'' +\n trustedResourceUrl + '\\' of type ' + goog.typeOf(trustedResourceUrl));\n return 'type_error:TrustedResourceUrl';\n }\n};\n\n\n/**\n * Creates a TrustedResourceUrl from a format string and arguments.\n *\n * The arguments for interpolation into the format string map labels to values.\n * Values of type `goog.string.Const` are interpolated without modifcation.\n * Values of other types are cast to string and encoded with\n * encodeURIComponent.\n *\n * `%{<label>}` markers are used in the format string to indicate locations\n * to be interpolated with the valued mapped to the given label. `<label>`\n * must contain only alphanumeric and `_` characters.\n *\n * The format string must match goog.html.TrustedResourceUrl.BASE_URL_.\n *\n * Example usage:\n *\n * var url = goog.html.TrustedResourceUrl.format(goog.string.Const.from(\n * 'https://www.google.com/search?q=%{query}'), {'query': searchTerm});\n *\n * var url = goog.html.TrustedResourceUrl.format(goog.string.Const.from(\n * '//www.youtube.com/v/%{videoId}?hl=en&fs=1%{autoplay}'), {\n * 'videoId': videoId,\n * 'autoplay': opt_autoplay ?\n * goog.string.Const.from('&autoplay=1') : goog.string.Const.EMPTY\n * });\n *\n * While this function can be used to create a TrustedResourceUrl from only\n * constants, fromConstant() and fromConstants() are generally preferable for\n * that purpose.\n *\n * @param {!goog.string.Const} format The format string.\n * @param {!Object<string, (string|number|!goog.string.Const)>} args Mapping\n * of labels to values to be interpolated into the format string.\n * goog.string.Const values are interpolated without encoding.\n * @return {!goog.html.TrustedResourceUrl}\n * @throws {!Error} On an invalid format string or if a label used in the\n * the format string is not present in args.\n */\ngoog.html.TrustedResourceUrl.format = function(format, args) {\n var formatStr = goog.string.Const.unwrap(format);\n if (!goog.html.TrustedResourceUrl.BASE_URL_.test(formatStr)) {\n throw new Error('Invalid TrustedResourceUrl format: ' + formatStr);\n }\n var result = formatStr.replace(\n goog.html.TrustedResourceUrl.FORMAT_MARKER_, function(match, id) {\n if (!Object.prototype.hasOwnProperty.call(args, id)) {\n throw new Error(\n 'Found marker, \"' + id + '\", in format string, \"' + formatStr +\n '\", but no valid label mapping found ' +\n 'in args: ' + JSON.stringify(args));\n }\n var arg = args[id];\n if (arg instanceof goog.string.Const) {\n return goog.string.Const.unwrap(arg);\n } else {\n return encodeURIComponent(String(arg));\n }\n });\n return goog.html.TrustedResourceUrl\n .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(result);\n};\n\n\n/**\n * @private @const {!RegExp}\n */\ngoog.html.TrustedResourceUrl.FORMAT_MARKER_ = /%{(\\w+)}/g;\n\n\n/**\n * The URL must be absolute, scheme-relative or path-absolute. So it must\n * start with:\n * - https:// followed by allowed origin characters.\n * - // followed by allowed origin characters.\n * - Any absolute or relative path.\n *\n * Based on\n * https://url.spec.whatwg.org/commit-snapshots/56b74ce7cca8883eab62e9a12666e2fac665d03d/#url-parsing\n * an initial / which is not followed by another / or \\ will end up in the \"path\n * state\" and from there it can only go to \"fragment state\" and \"query state\".\n *\n * We don't enforce a well-formed domain name. So '.' or '1.2' are valid.\n * That's ok because the origin comes from a compile-time constant.\n *\n * A regular expression is used instead of goog.uri for several reasons:\n * - Strictness. E.g. we don't want any userinfo component and we don't\n * want '/./, nor \\' in the first path component.\n * - Small trusted base. goog.uri is generic and might need to change,\n * reasoning about all the ways it can parse a URL now and in the future\n * is error-prone.\n * - Code size. We expect many calls to .format(), many of which might\n * not be using goog.uri.\n * - Simplicity. Using goog.uri would likely not result in simpler nor shorter\n * code.\n * @private @const {!RegExp}\n */\ngoog.html.TrustedResourceUrl.BASE_URL_ = new RegExp(\n '^((https:)?//[0-9a-z.:[\\\\]-]+/' // Origin.\n + '|/[^/\\\\\\\\]' // Absolute path.\n + '|[^:/\\\\\\\\%]+/' // Relative path.\n + '|[^:/\\\\\\\\%]*[?#]' // Query string or fragment.\n + '|about:blank#' // about:blank with fragment.\n + ')',\n 'i');\n\n/**\n * RegExp for splitting a URL into the base, search field, and hash field.\n *\n * @private @const {!RegExp}\n */\ngoog.html.TrustedResourceUrl.URL_PARAM_PARSER_ =\n /^([^?#]*)(\\?[^#]*)?(#[\\s\\S]*)?/;\n\n\n/**\n * Formats the URL same as TrustedResourceUrl.format and then adds extra URL\n * parameters.\n *\n * Example usage:\n *\n * // Creates '//www.youtube.com/v/abc?autoplay=1' for videoId='abc' and\n * // opt_autoplay=1. Creates '//www.youtube.com/v/abc' for videoId='abc'\n * // and opt_autoplay=undefined.\n * var url = goog.html.TrustedResourceUrl.formatWithParams(\n * goog.string.Const.from('//www.youtube.com/v/%{videoId}'),\n * {'videoId': videoId},\n * {'autoplay': opt_autoplay});\n *\n * @param {!goog.string.Const} format The format string.\n * @param {!Object<string, (string|number|!goog.string.Const)>} args Mapping\n * of labels to values to be interpolated into the format string.\n * goog.string.Const values are interpolated without encoding.\n * @param {string|?Object<string, *>|undefined} searchParams Parameters to add\n * to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for exact\n * format definition.\n * @param {(string|?Object<string, *>)=} opt_hashParams Hash parameters to add\n * to URL. See goog.html.TrustedResourceUrl.stringifyParams_ for exact\n * format definition.\n * @return {!goog.html.TrustedResourceUrl}\n * @throws {!Error} On an invalid format string or if a label used in the\n * the format string is not present in args.\n */\ngoog.html.TrustedResourceUrl.formatWithParams = function(\n format, args, searchParams, opt_hashParams) {\n var url = goog.html.TrustedResourceUrl.format(format, args);\n return url.cloneWithParams(searchParams, opt_hashParams);\n};\n\n\n/**\n * Creates a TrustedResourceUrl object from a compile-time constant string.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!goog.string.Const} url A compile-time-constant string from which to\n * create a TrustedResourceUrl.\n * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object\n * initialized to `url`.\n */\ngoog.html.TrustedResourceUrl.fromConstant = function(url) {\n return goog.html.TrustedResourceUrl\n .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(\n goog.string.Const.unwrap(url));\n};\n\n\n/**\n * Creates a TrustedResourceUrl object from a compile-time constant strings.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!Array<!goog.string.Const>} parts Compile-time-constant strings from\n * which to create a TrustedResourceUrl.\n * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object\n * initialized to concatenation of `parts`.\n */\ngoog.html.TrustedResourceUrl.fromConstants = function(parts) {\n var unwrapped = '';\n for (var i = 0; i < parts.length; i++) {\n unwrapped += goog.string.Const.unwrap(parts[i]);\n }\n return goog.html.TrustedResourceUrl\n .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(unwrapped);\n};\n\n/**\n * Creates a TrustedResourceUrl object by generating a Blob from a SafeScript\n * object and then calling createObjectURL with that blob.\n *\n * SafeScript objects are trusted to contain executable JavaScript code.\n *\n * Caller must call goog.fs.url.revokeObjectUrl() on the unwrapped url to\n * release the underlying blob.\n *\n * Throws if browser doesn't support blob construction.\n *\n * @param {!goog.html.SafeScript} safeScript A script from which to create a\n * TrustedResourceUrl.\n * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object\n * initialized to a new blob URL.\n */\ngoog.html.TrustedResourceUrl.fromSafeScript = function(safeScript) {\n var blob = goog.fs.blob.getBlobWithProperties(\n [goog.html.SafeScript.unwrap(safeScript)], 'text/javascript');\n var url = goog.fs.url.createObjectUrl(blob);\n return goog.html.TrustedResourceUrl\n .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Type marker for the TrustedResourceUrl type, used to implement additional\n * run-time type checking.\n * @const {!Object}\n * @private\n */\ngoog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n\n\n/**\n * Package-internal utility method to create TrustedResourceUrl instances.\n *\n * @param {string} url The string to initialize the TrustedResourceUrl object\n * with.\n * @return {!goog.html.TrustedResourceUrl} The initialized TrustedResourceUrl\n * object.\n * @package\n */\ngoog.html.TrustedResourceUrl\n .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) {\n var value = goog.html.trustedtypes.PRIVATE_DO_NOT_ACCESS_OR_ELSE_POLICY ?\n goog.html.trustedtypes.PRIVATE_DO_NOT_ACCESS_OR_ELSE_POLICY\n .createScriptURL(url) :\n url;\n return new goog.html.TrustedResourceUrl(\n goog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_, value);\n};\n\n\n/**\n * Stringifies the passed params to be used as either a search or hash field of\n * a URL.\n *\n * @param {string} prefix The prefix character for the given field ('?' or '#').\n * @param {string} currentString The existing field value (including the prefix\n * character, if the field is present).\n * @param {string|?Object<string, *>|undefined} params The params to set or\n * append to the field.\n * - If `undefined` or `null`, the field remains unchanged.\n * - If a string, then the string will be escaped and the field will be\n * overwritten with that value.\n * - If an Object, that object is treated as a set of key-value pairs to be\n * appended to the current field. Note that JavaScript doesn't guarantee the\n * order of values in an object which might result in non-deterministic order\n * of the parameters. However, browsers currently preserve the order. The\n * rules for each entry:\n * - If an array, it will be processed as if each entry were an additional\n * parameter with exactly the same key, following the same logic below.\n * - If `undefined` or `null`, it will be skipped.\n * - Otherwise, it will be turned into a string, escaped, and appended.\n * @return {string}\n * @private\n */\ngoog.html.TrustedResourceUrl.stringifyParams_ = function(\n prefix, currentString, params) {\n if (params == null) {\n // Do not modify the field.\n return currentString;\n }\n if (typeof params === 'string') {\n // Set field to the passed string.\n return params ? prefix + encodeURIComponent(params) : '';\n }\n // Add on parameters to field from key-value object.\n for (var key in params) {\n var value = params[key];\n var outputValues = Array.isArray(value) ? value : [value];\n for (var i = 0; i < outputValues.length; i++) {\n var outputValue = outputValues[i];\n if (outputValue != null) {\n if (!currentString) {\n currentString = prefix;\n }\n currentString += (currentString.length > prefix.length ? '&' : '') +\n encodeURIComponent(key) + '=' +\n encodeURIComponent(String(outputValue));\n }\n }\n }\n return currentString;\n};\n\n/**\n * Token used to ensure that object is created only from this file. No code\n * outside of this file can access this token.\n * @private {!Object}\n * @const\n */\ngoog.html.TrustedResourceUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The SafeUrl type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.provide('goog.html.SafeUrl');\n\ngoog.require('goog.asserts');\ngoog.require('goog.fs.url');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.i18n.bidi.Dir');\ngoog.require('goog.i18n.bidi.DirectionalString');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.TypedString');\ngoog.require('goog.string.internal');\n\n\n\n/**\n * A string that is safe to use in URL context in DOM APIs and HTML documents.\n *\n * A SafeUrl is a string-like object that carries the security type contract\n * that its value as a string will not cause untrusted script execution\n * when evaluated as a hyperlink URL in a browser.\n *\n * Values of this type are guaranteed to be safe to use in URL/hyperlink\n * contexts, such as assignment to URL-valued DOM properties, in the sense that\n * the use will not result in a Cross-Site-Scripting vulnerability. Similarly,\n * SafeUrls can be interpolated into the URL context of an HTML template (e.g.,\n * inside a href attribute). However, appropriate HTML-escaping must still be\n * applied.\n *\n * Note that, as documented in `goog.html.SafeUrl.unwrap`, this type's\n * contract does not guarantee that instances are safe to interpolate into HTML\n * without appropriate escaping.\n *\n * Note also that this type's contract does not imply any guarantees regarding\n * the resource the URL refers to. In particular, SafeUrls are <b>not</b>\n * safe to use in a context where the referred-to resource is interpreted as\n * trusted code, e.g., as the src of a script tag.\n *\n * Instances of this type must be created via the factory methods\n * (`goog.html.SafeUrl.fromConstant`, `goog.html.SafeUrl.sanitize`),\n * etc and not by invoking its constructor. The constructor is organized in a\n * way that only methods from that file can call it and initialize with\n * non-empty values. Anyone else calling constructor will get default instance\n * with empty value.\n *\n * @see goog.html.SafeUrl#fromConstant\n * @see goog.html.SafeUrl#from\n * @see goog.html.SafeUrl#sanitize\n * @constructor\n * @final\n * @struct\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n * @param {!Object=} opt_token package-internal implementation detail.\n * @param {string=} opt_content package-internal implementation detail.\n */\ngoog.html.SafeUrl = function(opt_token, opt_content) {\n /**\n * The contained value of this SafeUrl. The field has a purposely ugly\n * name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @private {string}\n */\n this.privateDoNotAccessOrElseSafeUrlWrappedValue_ =\n ((opt_token === goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_) &&\n opt_content) ||\n '';\n\n /**\n * A type marker used to implement additional run-time type checking.\n * @see goog.html.SafeUrl#unwrap\n * @const {!Object}\n * @private\n */\n this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =\n goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n};\n\n\n/**\n * The innocuous string generated by goog.html.SafeUrl.sanitize when passed\n * an unsafe URL.\n *\n * about:invalid is registered in\n * http://www.w3.org/TR/css3-values/#about-invalid.\n * http://tools.ietf.org/html/rfc6694#section-2.2.1 permits about URLs to\n * contain a fragment, which is not to be considered when determining if an\n * about URL is well-known.\n *\n * Using about:invalid seems preferable to using a fixed data URL, since\n * browsers might choose to not report CSP violations on it, as legitimate\n * CSS function calls to attr() can result in this URL being produced. It is\n * also a standard URL which matches exactly the semantics we need:\n * \"The about:invalid URI references a non-existent document with a generic\n * error condition. It can be used when a URI is necessary, but the default\n * value shouldn't be resolveable as any type of document\".\n *\n * @const {string}\n */\ngoog.html.SafeUrl.INNOCUOUS_STRING = 'about:invalid#zClosurez';\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this SafeUrl's value a string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `SafeUrl`, use `goog.html.SafeUrl.unwrap` instead of this\n * method. If in doubt, assume that it's security relevant. In particular, note\n * that goog.html functions which return a goog.html type do not guarantee that\n * the returned instance is of the right type.\n *\n * IMPORTANT: The guarantees of the SafeUrl type contract only extend to the\n * behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST\n * be appropriately escaped before embedding in a HTML document. Note that the\n * required escaping is context-sensitive (e.g. a different escaping is\n * required for embedding a URL in a style property within a style\n * attribute, as opposed to embedding in a href attribute).\n *\n * @see goog.html.SafeUrl#unwrap\n * @override\n */\ngoog.html.SafeUrl.prototype.getTypedStringValue = function() {\n return this.privateDoNotAccessOrElseSafeUrlWrappedValue_.toString();\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;\n\n\n/**\n * Returns this URLs directionality, which is always `LTR`.\n * @override\n */\ngoog.html.SafeUrl.prototype.getDirection = function() {\n return goog.i18n.bidi.Dir.LTR;\n};\n\n\nif (goog.DEBUG) {\n /**\n * Returns a debug string-representation of this value.\n *\n * To obtain the actual string value wrapped in a SafeUrl, use\n * `goog.html.SafeUrl.unwrap`.\n *\n * @see goog.html.SafeUrl#unwrap\n * @override\n */\n goog.html.SafeUrl.prototype.toString = function() {\n return 'SafeUrl{' + this.privateDoNotAccessOrElseSafeUrlWrappedValue_ + '}';\n };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed a SafeUrl\n * object, and returns its value.\n *\n * IMPORTANT: The guarantees of the SafeUrl type contract only extend to the\n * behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST\n * be appropriately escaped before embedding in a HTML document. Note that the\n * required escaping is context-sensitive (e.g. a different escaping is\n * required for embedding a URL in a style property within a style\n * attribute, as opposed to embedding in a href attribute).\n *\n * @param {!goog.html.SafeUrl} safeUrl The object to extract from.\n * @return {string} The SafeUrl object's contained string, unless the run-time\n * type check fails. In that case, `unwrap` returns an innocuous\n * string, or, if assertions are enabled, throws\n * `goog.asserts.AssertionError`.\n */\ngoog.html.SafeUrl.unwrap = function(safeUrl) {\n // Perform additional Run-time type-checking to ensure that safeUrl is indeed\n // an instance of the expected type. This provides some additional protection\n // against security bugs due to application code that disables type checks.\n // Specifically, the following checks are performed:\n // 1. The object is an instance of the expected type.\n // 2. The object is not an instance of a subclass.\n // 3. The object carries a type marker for the expected type. \"Faking\" an\n // object requires a reference to the type marker, which has names intended\n // to stand out in code reviews.\n if (safeUrl instanceof goog.html.SafeUrl &&\n safeUrl.constructor === goog.html.SafeUrl &&\n safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===\n goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n return safeUrl.privateDoNotAccessOrElseSafeUrlWrappedValue_;\n } else {\n goog.asserts.fail('expected object of type SafeUrl, got \\'' +\n safeUrl + '\\' of type ' + goog.typeOf(safeUrl));\n return 'type_error:SafeUrl';\n }\n};\n\n\n/**\n * Creates a SafeUrl object from a compile-time constant string.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!goog.string.Const} url A compile-time-constant string from which to\n * create a SafeUrl.\n * @return {!goog.html.SafeUrl} A SafeUrl object initialized to `url`.\n */\ngoog.html.SafeUrl.fromConstant = function(url) {\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n goog.string.Const.unwrap(url));\n};\n\n\n/**\n * A pattern that matches Blob or data types that can have SafeUrls created\n * from URL.createObjectURL(blob) or via a data: URI.\n *\n * This has some parameter support (most notably, we haven't implemented the\n * more complex parts like %-encoded characters or non-alphanumerical ones for\n * simplicity's sake). The specs are fairly complex, and they don't\n * always match Chrome's behavior: we settled on a subset where we're confident\n * all parties involved agree.\n *\n * The spec is available at https://mimesniff.spec.whatwg.org/ (and see\n * https://tools.ietf.org/html/rfc2397 for data: urls, which override some of\n * it).\n * @const\n * @private\n */\ngoog.html.SAFE_MIME_TYPE_PATTERN_ = new RegExp(\n // Note: Due to content-sniffing concerns, only add MIME types for\n // media formats.\n '^(?:audio/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-wav|wav|webm)|' +\n 'image/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|' +\n // TODO(user): Due to content-sniffing concerns, text/csv should\n // be removed from the whitelist.\n 'text/csv|' +\n 'video/(?:mpeg|mp4|ogg|webm|quicktime))' +\n '(?:;\\\\w+=(?:\\\\w+|\"[\\\\w;=]+\"))*$', // MIME type parameters\n 'i');\n\n\n/**\n * @param {string} mimeType The MIME type to check if safe.\n * @return {boolean} True if the MIME type is safe and creating a Blob via\n * `SafeUrl.fromBlob()` with that type will not fail due to the type. False\n * otherwise.\n */\ngoog.html.SafeUrl.isSafeMimeType = function(mimeType) {\n return goog.html.SAFE_MIME_TYPE_PATTERN_.test(mimeType);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a blob URL for the given `blob`.\n *\n * The blob URL is created with `URL.createObjectURL`. If the MIME type\n * for `blob` is not of a known safe audio, image or video MIME type,\n * then the SafeUrl will wrap {@link #INNOCUOUS_STRING}.\n *\n * @see http://www.w3.org/TR/FileAPI/#url\n * @param {!Blob} blob\n * @return {!goog.html.SafeUrl} The blob URL, or an innocuous string wrapped\n * as a SafeUrl.\n */\ngoog.html.SafeUrl.fromBlob = function(blob) {\n var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ?\n goog.fs.url.createObjectUrl(blob) :\n goog.html.SafeUrl.INNOCUOUS_STRING;\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Matches a base-64 data URL, with the first match group being the MIME type.\n * @const\n * @private\n */\ngoog.html.DATA_URL_PATTERN_ = /^data:([^,]*);base64,[a-z0-9+\\/]+=*$/i;\n\n\n/**\n * Creates a SafeUrl wrapping a data: URL, after validating it matches a\n * known-safe audio, image or video MIME type.\n *\n * @param {string} dataUrl A valid base64 data URL with one of the whitelisted\n * audio, image or video MIME types.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromDataUrl = function(dataUrl) {\n // RFC4648 suggest to ignore CRLF in base64 encoding.\n // See https://tools.ietf.org/html/rfc4648.\n // Remove the CR (%0D) and LF (%0A) from the dataUrl.\n var filteredDataUrl = dataUrl.replace(/(%0A|%0D)/g, '');\n // There's a slight risk here that a browser sniffs the content type if it\n // doesn't know the MIME type and executes HTML within the data: URL. For this\n // to cause XSS it would also have to execute the HTML in the same origin\n // of the page with the link. It seems unlikely that both of these will\n // happen, particularly in not really old IEs.\n var match = filteredDataUrl.match(goog.html.DATA_URL_PATTERN_);\n var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n valid ? filteredDataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a tel: URL.\n *\n * @param {string} telUrl A tel URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromTelUrl = function(telUrl) {\n // There's a risk that a tel: URL could immediately place a call once\n // clicked, without requiring user confirmation. For that reason it is\n // handled in this separate function.\n if (!goog.string.internal.caseInsensitiveStartsWith(telUrl, 'tel:')) {\n telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n telUrl);\n};\n\n\n/**\n * Matches a sip/sips URL. We only allow urls that consist of an email address.\n * The characters '?' and '#' are not allowed in the local part of the email\n * address.\n * @const\n * @private\n */\ngoog.html.SIP_URL_PATTERN_ = new RegExp(\n '^sip[s]?:[+a-z0-9_.!$%&\\'*\\\\/=^`{|}~-]+@([a-z0-9-]+\\\\.)+[a-z0-9]{2,63}$',\n 'i');\n\n\n/**\n * Creates a SafeUrl wrapping a sip: URL. We only allow urls that consist of an\n * email address. The characters '?' and '#' are not allowed in the local part\n * of the email address.\n *\n * @param {string} sipUrl A sip URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSipUrl = function(sipUrl) {\n if (!goog.html.SIP_URL_PATTERN_.test(decodeURIComponent(sipUrl))) {\n sipUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n sipUrl);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a fb-messenger://share URL.\n *\n * @param {string} facebookMessengerUrl A facebook messenger URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromFacebookMessengerUrl = function(facebookMessengerUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(\n facebookMessengerUrl, 'fb-messenger://share')) {\n facebookMessengerUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n facebookMessengerUrl);\n};\n\n/**\n * Creates a SafeUrl wrapping a whatsapp://send URL.\n *\n * @param {string} whatsAppUrl A WhatsApp URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromWhatsAppUrl = function(whatsAppUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(\n whatsAppUrl, 'whatsapp://send')) {\n whatsAppUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n whatsAppUrl);\n};\n\n/**\n * Creates a SafeUrl wrapping a sms: URL.\n *\n * @param {string} smsUrl A sms URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSmsUrl = function(smsUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(smsUrl, 'sms:') ||\n !goog.html.SafeUrl.isSmsUrlBodyValid_(smsUrl)) {\n smsUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n smsUrl);\n};\n\n\n/**\n * Validates SMS URL `body` parameter, which is optional and should appear at\n * most once and should be percent-encoded if present. Rejects many malformed\n * bodies, but may spuriously reject some URLs and does not reject all malformed\n * sms: URLs.\n *\n * @param {string} smsUrl A sms URL.\n * @return {boolean} Whether SMS URL has a valid `body` parameter if it exists.\n * @private\n */\ngoog.html.SafeUrl.isSmsUrlBodyValid_ = function(smsUrl) {\n var hash = smsUrl.indexOf('#');\n if (hash > 0) {\n smsUrl = smsUrl.substring(0, hash);\n }\n var bodyParams = smsUrl.match(/[?&]body=/gi);\n // \"body\" param is optional\n if (!bodyParams) {\n return true;\n }\n // \"body\" MUST only appear once\n if (bodyParams.length > 1) {\n return false;\n }\n // Get the encoded `body` parameter value.\n var bodyValue = smsUrl.match(/[?&]body=([^&]*)/)[1];\n if (!bodyValue) {\n return true;\n }\n try {\n decodeURIComponent(bodyValue);\n } catch (error) {\n return false;\n }\n return /^(?:[a-z0-9\\-_.~]|%[0-9a-f]{2})+$/i.test(bodyValue);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a ssh: URL.\n *\n * @param {string} sshUrl A ssh URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSshUrl = function(sshUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(sshUrl, 'ssh://')) {\n sshUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n sshUrl);\n};\n\n/**\n * Sanitizes a Chrome extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeChromeExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(\n /^chrome-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Sanitizes a Firefox extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeFirefoxExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(\n /^moz-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Sanitizes a Edge extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeEdgeExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(\n /^ms-browser-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Private helper for converting extension URLs to SafeUrl, given the scheme for\n * that particular extension type. Use the sanitizeFirefoxExtensionUrl,\n * sanitizeChromeExtensionUrl or sanitizeEdgeExtensionUrl unless you're building\n * new helpers.\n *\n * @private\n * @param {!RegExp} scheme The scheme to accept as a RegExp extracting the\n * extension identifier.\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeExtensionUrl_ = function(scheme, url, extensionId) {\n var matches = scheme.exec(url);\n if (!matches) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n } else {\n var extractedExtensionId = matches[1];\n var acceptedExtensionIds;\n if (extensionId instanceof goog.string.Const) {\n acceptedExtensionIds = [goog.string.Const.unwrap(extensionId)];\n } else {\n acceptedExtensionIds = extensionId.map(function unwrap(x) {\n return goog.string.Const.unwrap(x);\n });\n }\n if (acceptedExtensionIds.indexOf(extractedExtensionId) == -1) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Creates a SafeUrl from TrustedResourceUrl. This is safe because\n * TrustedResourceUrl is more tightly restricted than SafeUrl.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromTrustedResourceUrl = function(trustedResourceUrl) {\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n goog.html.TrustedResourceUrl.unwrap(trustedResourceUrl));\n};\n\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that satisfy\n * the SafeUrl contract.\n *\n * This regular expression matches a subset of URLs that will not cause script\n * execution if used in URL context within a HTML document. Specifically, this\n * regular expression matches if (comment from here on and regex copied from\n * Soy's EscapingConventions):\n * (1) Either a protocol in a whitelist (http, https, mailto or ftp).\n * (2) or no protocol. A protocol must be followed by a colon. The below\n * allows that by allowing colons only after one of the characters [/?#].\n * A colon after a hash (#) must be in the fragment.\n * Otherwise, a colon after a (?) must be in a query.\n * Otherwise, a colon after a single solidus (/) must be in a path.\n * Otherwise, a colon after a double solidus (//) must be in the authority\n * (before port).\n *\n * @private\n * @const {!RegExp}\n */\ngoog.html.SAFE_URL_PATTERN_ =\n /^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;\n\n/**\n * Public version of goog.html.SAFE_URL_PATTERN_. Updating\n * goog.html.SAFE_URL_PATTERN_ doesn't seem to be backward compatible.\n * Namespace is also changed to goog.html.SafeUrl so it can be imported using\n * goog.require('goog.dom.SafeUrl').\n *\n * TODO(bangert): Remove SAFE_URL_PATTERN_\n * @const {!RegExp}\n */\ngoog.html.SafeUrl.SAFE_URL_PATTERN = goog.html.SAFE_URL_PATTERN_;\n\n\n/**\n * Creates a SafeUrl object from `url`. If `url` is a\n * goog.html.SafeUrl then it is simply returned. Otherwise the input string is\n * validated to match a pattern of commonly used safe URLs.\n *\n * `url` may be a URL with the http, https, mailto or ftp scheme,\n * or a relative URL (i.e., a URL without a scheme; specifically, a\n * scheme-relative, absolute-path-relative, or path-relative URL).\n *\n * @see http://url.spec.whatwg.org/#concept-relative-url\n * @param {string|!goog.string.TypedString} url The URL to validate.\n * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.\n */\ngoog.html.SafeUrl.sanitize = function(url) {\n if (url instanceof goog.html.SafeUrl) {\n return url;\n } else if (typeof url == 'object' && url.implementsGoogStringTypedString) {\n url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n } else {\n url = String(url);\n }\n if (!goog.html.SAFE_URL_PATTERN_.test(url)) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n/**\n * Creates a SafeUrl object from `url`. If `url` is a\n * goog.html.SafeUrl then it is simply returned. Otherwise the input string is\n * validated to match a pattern of commonly used safe URLs.\n *\n * `url` may be a URL with the http, https, mailto or ftp scheme,\n * or a relative URL (i.e., a URL without a scheme; specifically, a\n * scheme-relative, absolute-path-relative, or path-relative URL).\n *\n * This function asserts (using goog.asserts) that the URL matches this pattern.\n * If it does not, in addition to failing the assert, an innocous URL will be\n * returned.\n *\n * @see http://url.spec.whatwg.org/#concept-relative-url\n * @param {string|!goog.string.TypedString} url The URL to validate.\n * @param {boolean=} opt_allowDataUrl Whether to allow valid data: URLs.\n * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.\n */\ngoog.html.SafeUrl.sanitizeAssertUnchanged = function(url, opt_allowDataUrl) {\n if (url instanceof goog.html.SafeUrl) {\n return url;\n } else if (typeof url == 'object' && url.implementsGoogStringTypedString) {\n url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n } else {\n url = String(url);\n }\n if (opt_allowDataUrl && /^data:/i.test(url)) {\n var safeUrl = goog.html.SafeUrl.fromDataUrl(url);\n if (safeUrl.getTypedStringValue() == url) {\n return safeUrl;\n }\n }\n if (!goog.asserts.assert(\n goog.html.SAFE_URL_PATTERN_.test(url),\n '%s does not match the safe URL pattern', url)) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n\n/**\n * Type marker for the SafeUrl type, used to implement additional run-time\n * type checking.\n * @const {!Object}\n * @private\n */\ngoog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n\n\n/**\n * Package-internal utility method to create SafeUrl instances.\n *\n * @param {string} url The string to initialize the SafeUrl object with.\n * @return {!goog.html.SafeUrl} The initialized SafeUrl object.\n * @package\n */\ngoog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(\n url) {\n return new goog.html.SafeUrl(\n goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_, url);\n};\n\n\n/**\n * A SafeUrl corresponding to the special about:blank url.\n * @const {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.ABOUT_BLANK =\n goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n 'about:blank');\n\n/**\n * Token used to ensure that object is created only from this file. No code\n * outside of this file can access this token.\n * @private {!Object}\n * @const\n */\ngoog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview The SafeHtml type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.provide('goog.html.SafeHtml');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.tags');\ngoog.require('goog.html.SafeScript');\ngoog.require('goog.html.SafeStyle');\ngoog.require('goog.html.SafeStyleSheet');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.html.trustedtypes');\ngoog.require('goog.i18n.bidi.Dir');\ngoog.require('goog.i18n.bidi.DirectionalString');\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.object');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.TypedString');\ngoog.require('goog.string.internal');\n\n\n\n/**\n * A string that is safe to use in HTML context in DOM APIs and HTML documents.\n *\n * A SafeHtml is a string-like object that carries the security type contract\n * that its value as a string will not cause untrusted script execution when\n * evaluated as HTML in a browser.\n *\n * Values of this type are guaranteed to be safe to use in HTML contexts,\n * such as, assignment to the innerHTML DOM property, or interpolation into\n * a HTML template in HTML PC_DATA context, in the sense that the use will not\n * result in a Cross-Site-Scripting vulnerability.\n *\n * Instances of this type must be created via the factory methods\n * (`goog.html.SafeHtml.create`, `goog.html.SafeHtml.htmlEscape`),\n * etc and not by invoking its constructor. The constructor intentionally\n * takes no parameters and the type is immutable; hence only a default instance\n * corresponding to the empty string can be obtained via constructor invocation.\n *\n * Note that there is no `goog.html.SafeHtml.fromConstant`. The reason is that\n * the following code would create an unsafe HTML:\n *\n * ```\n * goog.html.SafeHtml.concat(\n * goog.html.SafeHtml.fromConstant(goog.string.Const.from('<script>')),\n * goog.html.SafeHtml.htmlEscape(userInput),\n * goog.html.SafeHtml.fromConstant(goog.string.Const.from('<\\/script>')));\n * ```\n *\n * There's `goog.dom.constHtmlToNode` to create a node from constant strings\n * only.\n *\n * @see goog.html.SafeHtml.create\n * @see goog.html.SafeHtml.htmlEscape\n * @constructor\n * @final\n * @struct\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n */\ngoog.html.SafeHtml = function() {\n /**\n * The contained value of this SafeHtml. The field has a purposely ugly\n * name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @private {!TrustedHTML|string}\n */\n this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = '';\n\n /**\n * A type marker used to implement additional run-time type checking.\n * @see goog.html.SafeHtml.unwrap\n * @const {!Object}\n * @private\n */\n this.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =\n goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n\n /**\n * This SafeHtml's directionality, or null if unknown.\n * @private {?goog.i18n.bidi.Dir}\n */\n this.dir_ = null;\n};\n\n\n/**\n * @define {boolean} Whether to strip out error messages or to leave them in.\n */\ngoog.html.SafeHtml.ENABLE_ERROR_MESSAGES =\n goog.define('goog.html.SafeHtml.ENABLE_ERROR_MESSAGES', goog.DEBUG);\n\n\n/**\n * Whether the `style` attribute is supported. Set to false to avoid the byte\n * weight of `goog.html.SafeStyle` where unneeded. An error will be thrown if\n * the `style` attribute is used.\n * @define {boolean}\n */\ngoog.html.SafeHtml.SUPPORT_STYLE_ATTRIBUTE =\n goog.define('goog.html.SafeHtml.SUPPORT_STYLE_ATTRIBUTE', true);\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeHtml.prototype.implementsGoogI18nBidiDirectionalString = true;\n\n\n/** @override */\ngoog.html.SafeHtml.prototype.getDirection = function() {\n return this.dir_;\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeHtml.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this SafeHtml's value as string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `SafeHtml`, use `goog.html.SafeHtml.unwrap` instead of\n * this method. If in doubt, assume that it's security relevant. In particular,\n * note that goog.html functions which return a goog.html type do not guarantee\n * that the returned instance is of the right type. For example:\n *\n * <pre>\n * var fakeSafeHtml = new String('fake');\n * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;\n * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);\n * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by\n * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml\n * // instanceof goog.html.SafeHtml.\n * </pre>\n *\n * @see goog.html.SafeHtml.unwrap\n * @override\n */\ngoog.html.SafeHtml.prototype.getTypedStringValue = function() {\n return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_.toString();\n};\n\n\nif (goog.DEBUG) {\n /**\n * Returns a debug string-representation of this value.\n *\n * To obtain the actual string value wrapped in a SafeHtml, use\n * `goog.html.SafeHtml.unwrap`.\n *\n * @see goog.html.SafeHtml.unwrap\n * @override\n */\n goog.html.SafeHtml.prototype.toString = function() {\n return 'SafeHtml{' + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ +\n '}';\n };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed a SafeHtml\n * object, and returns its value.\n * @param {!goog.html.SafeHtml} safeHtml The object to extract from.\n * @return {string} The SafeHtml object's contained string, unless the run-time\n * type check fails. In that case, `unwrap` returns an innocuous\n * string, or, if assertions are enabled, throws\n * `goog.asserts.AssertionError`.\n */\ngoog.html.SafeHtml.unwrap = function(safeHtml) {\n return goog.html.SafeHtml.unwrapTrustedHTML(safeHtml).toString();\n};\n\n\n/**\n * Unwraps value as TrustedHTML if supported or as a string if not.\n * @param {!goog.html.SafeHtml} safeHtml\n * @return {!TrustedHTML|string}\n * @see goog.html.SafeHtml.unwrap\n */\ngoog.html.SafeHtml.unwrapTrustedHTML = function(safeHtml) {\n // Perform additional run-time type-checking to ensure that safeHtml is indeed\n // an instance of the expected type. This provides some additional protection\n // against security bugs due to application code that disables type checks.\n // Specifically, the following checks are performed:\n // 1. The object is an instance of the expected type.\n // 2. The object is not an instance of a subclass.\n // 3. The object carries a type marker for the expected type. \"Faking\" an\n // object requires a reference to the type marker, which has names intended\n // to stand out in code reviews.\n if (safeHtml instanceof goog.html.SafeHtml &&\n safeHtml.constructor === goog.html.SafeHtml &&\n safeHtml.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===\n goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;\n } else {\n goog.asserts.fail('expected object of type SafeHtml, got \\'' +\n safeHtml + '\\' of type ' + goog.typeOf(safeHtml));\n return 'type_error:SafeHtml';\n }\n};\n\n\n/**\n * Shorthand for union of types that can sensibly be converted to strings\n * or might already be SafeHtml (as SafeHtml is a goog.string.TypedString).\n * @private\n * @typedef {string|number|boolean|!goog.string.TypedString|\n * !goog.i18n.bidi.DirectionalString}\n */\ngoog.html.SafeHtml.TextOrHtml_;\n\n\n/**\n * Returns HTML-escaped text as a SafeHtml object.\n *\n * If text is of a type that implements\n * `goog.i18n.bidi.DirectionalString`, the directionality of the new\n * `SafeHtml` object is set to `text`'s directionality, if known.\n * Otherwise, the directionality of the resulting SafeHtml is unknown (i.e.,\n * `null`).\n *\n * @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\n * the parameter is of type SafeHtml it is returned directly (no escaping\n * is done).\n * @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.\n */\ngoog.html.SafeHtml.htmlEscape = function(textOrHtml) {\n if (textOrHtml instanceof goog.html.SafeHtml) {\n return textOrHtml;\n }\n var textIsObject = typeof textOrHtml == 'object';\n var dir = null;\n if (textIsObject && textOrHtml.implementsGoogI18nBidiDirectionalString) {\n dir = /** @type {!goog.i18n.bidi.DirectionalString} */ (textOrHtml)\n .getDirection();\n }\n var textAsString;\n if (textIsObject && textOrHtml.implementsGoogStringTypedString) {\n textAsString = /** @type {!goog.string.TypedString} */ (textOrHtml)\n .getTypedStringValue();\n } else {\n textAsString = String(textOrHtml);\n }\n return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n goog.string.internal.htmlEscape(textAsString), dir);\n};\n\n\n/**\n * Returns HTML-escaped text as a SafeHtml object, with newlines changed to\n * <br>.\n * @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\n * the parameter is of type SafeHtml it is returned directly (no escaping\n * is done).\n * @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.\n */\ngoog.html.SafeHtml.htmlEscapePreservingNewlines = function(textOrHtml) {\n if (textOrHtml instanceof goog.html.SafeHtml) {\n return textOrHtml;\n }\n var html = goog.html.SafeHtml.htmlEscape(textOrHtml);\n return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n goog.string.internal.newLineToBr(goog.html.SafeHtml.unwrap(html)),\n html.getDirection());\n};\n\n\n/**\n * Returns HTML-escaped text as a SafeHtml object, with newlines changed to\n * <br> and escaping whitespace to preserve spatial formatting. Character\n * entity #160 is used to make it safer for XML.\n * @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If\n * the parameter is of type SafeHtml it is returned directly (no escaping\n * is done).\n * @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.\n */\ngoog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces = function(\n textOrHtml) {\n if (textOrHtml instanceof goog.html.SafeHtml) {\n return textOrHtml;\n }\n var html = goog.html.SafeHtml.htmlEscape(textOrHtml);\n return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n goog.string.internal.whitespaceEscape(goog.html.SafeHtml.unwrap(html)),\n html.getDirection());\n};\n\n\n/**\n * Coerces an arbitrary object into a SafeHtml object.\n *\n * If `textOrHtml` is already of type `goog.html.SafeHtml`, the same\n * object is returned. Otherwise, `textOrHtml` is coerced to string, and\n * HTML-escaped. If `textOrHtml` is of a type that implements\n * `goog.i18n.bidi.DirectionalString`, its directionality, if known, is\n * preserved.\n *\n * @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text or SafeHtml to\n * coerce.\n * @return {!goog.html.SafeHtml} The resulting SafeHtml object.\n * @deprecated Use goog.html.SafeHtml.htmlEscape.\n */\ngoog.html.SafeHtml.from = goog.html.SafeHtml.htmlEscape;\n\n\n/**\n * @const\n * @private\n */\ngoog.html.SafeHtml.VALID_NAMES_IN_TAG_ = /^[a-zA-Z0-9-]+$/;\n\n\n/**\n * Set of attributes containing URL as defined at\n * http://www.w3.org/TR/html5/index.html#attributes-1.\n * @private @const {!Object<string,boolean>}\n */\ngoog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet(\n 'action', 'cite', 'data', 'formaction', 'href', 'manifest', 'poster',\n 'src');\n\n\n/**\n * Tags which are unsupported via create(). They might be supported via a\n * tag-specific create method. These are tags which might require a\n * TrustedResourceUrl in one of their attributes or a restricted type for\n * their content.\n * @private @const {!Object<string,boolean>}\n */\ngoog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_ = goog.object.createSet(\n goog.dom.TagName.APPLET, goog.dom.TagName.BASE, goog.dom.TagName.EMBED,\n goog.dom.TagName.IFRAME, goog.dom.TagName.LINK, goog.dom.TagName.MATH,\n goog.dom.TagName.META, goog.dom.TagName.OBJECT, goog.dom.TagName.SCRIPT,\n goog.dom.TagName.STYLE, goog.dom.TagName.SVG, goog.dom.TagName.TEMPLATE);\n\n\n/**\n * @typedef {string|number|goog.string.TypedString|\n * goog.html.SafeStyle.PropertyMap|undefined}\n */\ngoog.html.SafeHtml.AttributeValue;\n\n\n/**\n * Creates a SafeHtml content consisting of a tag with optional attributes and\n * optional content.\n *\n * For convenience tag names and attribute names are accepted as regular\n * strings, instead of goog.string.Const. Nevertheless, you should not pass\n * user-controlled values to these parameters. Note that these parameters are\n * syntactically validated at runtime, and invalid values will result in\n * an exception.\n *\n * Example usage:\n *\n * goog.html.SafeHtml.create('br');\n * goog.html.SafeHtml.create('div', {'class': 'a'});\n * goog.html.SafeHtml.create('p', {}, 'a');\n * goog.html.SafeHtml.create('p', {}, goog.html.SafeHtml.create('br'));\n *\n * goog.html.SafeHtml.create('span', {\n * 'style': {'margin': '0'}\n * });\n *\n * To guarantee SafeHtml's type contract is upheld there are restrictions on\n * attribute values and tag names.\n *\n * - For attributes which contain script code (on*), a goog.string.Const is\n * required.\n * - For attributes which contain style (style), a goog.html.SafeStyle or a\n * goog.html.SafeStyle.PropertyMap is required.\n * - For attributes which are interpreted as URLs (e.g. src, href) a\n * goog.html.SafeUrl, goog.string.Const or string is required. If a string\n * is passed, it will be sanitized with SafeUrl.sanitize().\n * - For tags which can load code or set security relevant page metadata,\n * more specific goog.html.SafeHtml.create*() functions must be used. Tags\n * which are not supported by this function are applet, base, embed, iframe,\n * link, math, object, script, style, svg, and template.\n *\n * @param {!goog.dom.TagName|string} tagName The name of the tag. Only tag names\n * consisting of [a-zA-Z0-9-] are allowed. Tag names documented above are\n * disallowed.\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes\n * the attribute to be omitted.\n * @param {!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to\n * HTML-escape and put inside the tag. This must be empty for void tags\n * like <br>. Array elements are concatenated.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n * @throws {Error} If invalid tag name, attribute name, or attribute value is\n * provided.\n * @throws {goog.asserts.AssertionError} If content for void tag is provided.\n */\ngoog.html.SafeHtml.create = function(tagName, opt_attributes, opt_content) {\n goog.html.SafeHtml.verifyTagName(String(tagName));\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n String(tagName), opt_attributes, opt_content);\n};\n\n\n/**\n * Verifies if the tag name is valid and if it doesn't change the context.\n * E.g. STRONG is fine but SCRIPT throws because it changes context. See\n * goog.html.SafeHtml.create for an explanation of allowed tags.\n * @param {string} tagName\n * @throws {Error} If invalid tag name is provided.\n * @package\n */\ngoog.html.SafeHtml.verifyTagName = function(tagName) {\n if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(tagName)) {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'Invalid tag name <' + tagName + '>.' :\n '');\n }\n if (tagName.toUpperCase() in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_) {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n\n 'Tag name <' + tagName + '> is not allowed for SafeHtml.' :\n '');\n }\n};\n\n\n/**\n * Creates a SafeHtml representing an iframe tag.\n *\n * This by default restricts the iframe as much as possible by setting the\n * sandbox attribute to the empty string. If the iframe requires less\n * restrictions, set the sandbox attribute as tight as possible, but do not rely\n * on the sandbox as a security feature because it is not supported by older\n * browsers. If a sandbox is essential to security (e.g. for third-party\n * frames), use createSandboxIframe which checks for browser support.\n *\n * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox\n *\n * @param {?goog.html.TrustedResourceUrl=} opt_src The value of the src\n * attribute. If null or undefined src will not be set.\n * @param {?goog.html.SafeHtml=} opt_srcdoc The value of the srcdoc attribute.\n * If null or undefined srcdoc will not be set.\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes\n * the attribute to be omitted.\n * @param {!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to\n * HTML-escape and put inside the tag. Array elements are concatenated.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n * @throws {Error} If invalid tag name, attribute name, or attribute value is\n * provided. If opt_attributes contains the src or srcdoc attributes.\n */\ngoog.html.SafeHtml.createIframe = function(\n opt_src, opt_srcdoc, opt_attributes, opt_content) {\n if (opt_src) {\n // Check whether this is really TrustedResourceUrl.\n goog.html.TrustedResourceUrl.unwrap(opt_src);\n }\n\n var fixedAttributes = {};\n fixedAttributes['src'] = opt_src || null;\n fixedAttributes['srcdoc'] =\n opt_srcdoc && goog.html.SafeHtml.unwrap(opt_srcdoc);\n var defaultAttributes = {'sandbox': ''};\n var attributes = goog.html.SafeHtml.combineAttributes(\n fixedAttributes, defaultAttributes, opt_attributes);\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'iframe', attributes, opt_content);\n};\n\n\n/**\n * Creates a SafeHtml representing a sandboxed iframe tag.\n *\n * The sandbox attribute is enforced in its most restrictive mode, an empty\n * string. Consequently, the security requirements for the src and srcdoc\n * attributes are relaxed compared to SafeHtml.createIframe. This function\n * will throw on browsers that do not support the sandbox attribute, as\n * determined by SafeHtml.canUseSandboxIframe.\n *\n * The SafeHtml returned by this function can trigger downloads with no\n * user interaction on Chrome (though only a few, further attempts are blocked).\n * Firefox and IE will block all downloads from the sandbox.\n *\n * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox\n * @see https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Feb/0112.html\n *\n * @param {string|!goog.html.SafeUrl=} opt_src The value of the src\n * attribute. If null or undefined src will not be set.\n * @param {string=} opt_srcdoc The value of the srcdoc attribute.\n * If null or undefined srcdoc will not be set. Will not be sanitized.\n * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes\n * the attribute to be omitted.\n * @param {!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to\n * HTML-escape and put inside the tag. Array elements are concatenated.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n * @throws {Error} If invalid tag name, attribute name, or attribute value is\n * provided. If opt_attributes contains the src, srcdoc or sandbox\n * attributes. If browser does not support the sandbox attribute on iframe.\n */\ngoog.html.SafeHtml.createSandboxIframe = function(\n opt_src, opt_srcdoc, opt_attributes, opt_content) {\n if (!goog.html.SafeHtml.canUseSandboxIframe()) {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'The browser does not support sandboxed iframes.' :\n '');\n }\n\n var fixedAttributes = {};\n if (opt_src) {\n // Note that sanitize is a no-op on SafeUrl.\n fixedAttributes['src'] =\n goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(opt_src));\n } else {\n fixedAttributes['src'] = null;\n }\n fixedAttributes['srcdoc'] = opt_srcdoc || null;\n fixedAttributes['sandbox'] = '';\n var attributes =\n goog.html.SafeHtml.combineAttributes(fixedAttributes, {}, opt_attributes);\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'iframe', attributes, opt_content);\n};\n\n\n/**\n * Checks if the user agent supports sandboxed iframes.\n * @return {boolean}\n */\ngoog.html.SafeHtml.canUseSandboxIframe = function() {\n return goog.global['HTMLIFrameElement'] &&\n ('sandbox' in goog.global['HTMLIFrameElement'].prototype);\n};\n\n\n/**\n * Creates a SafeHtml representing a script tag with the src attribute.\n * @param {!goog.html.TrustedResourceUrl} src The value of the src\n * attribute.\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=}\n * opt_attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined\n * causes the attribute to be omitted.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n * @throws {Error} If invalid attribute name or value is provided. If\n * opt_attributes contains the src attribute.\n */\ngoog.html.SafeHtml.createScriptSrc = function(src, opt_attributes) {\n // TODO(mlourenco): The charset attribute should probably be blocked. If\n // its value is attacker controlled, the script contains attacker controlled\n // sub-strings (even if properly escaped) and the server does not set charset\n // then XSS is likely possible.\n // https://html.spec.whatwg.org/multipage/scripting.html#dom-script-charset\n\n // Check whether this is really TrustedResourceUrl.\n goog.html.TrustedResourceUrl.unwrap(src);\n\n var fixedAttributes = {'src': src};\n var defaultAttributes = {};\n var attributes = goog.html.SafeHtml.combineAttributes(\n fixedAttributes, defaultAttributes, opt_attributes);\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'script', attributes);\n};\n\n\n/**\n * Creates a SafeHtml representing a script tag. Does not allow the language,\n * src, text or type attributes to be set.\n * @param {!goog.html.SafeScript|!Array<!goog.html.SafeScript>}\n * script Content to put inside the tag. Array elements are\n * concatenated.\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes\n * the attribute to be omitted.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n * @throws {Error} If invalid attribute name or attribute value is provided. If\n * opt_attributes contains the language, src, text or type attribute.\n */\ngoog.html.SafeHtml.createScript = function(script, opt_attributes) {\n for (var attr in opt_attributes) {\n var attrLower = attr.toLowerCase();\n if (attrLower == 'language' || attrLower == 'src' || attrLower == 'text' ||\n attrLower == 'type') {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'Cannot set \"' + attrLower + '\" attribute' :\n '');\n }\n }\n\n var content = '';\n script = goog.array.concat(script);\n for (var i = 0; i < script.length; i++) {\n content += goog.html.SafeScript.unwrap(script[i]);\n }\n // Convert to SafeHtml so that it's not HTML-escaped. This is safe because\n // as part of its contract, SafeScript should have no dangerous '<'.\n var htmlContent =\n goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n content, goog.i18n.bidi.Dir.NEUTRAL);\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'script', opt_attributes, htmlContent);\n};\n\n\n/**\n * Creates a SafeHtml representing a style tag. The type attribute is set\n * to \"text/css\".\n * @param {!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>}\n * styleSheet Content to put inside the tag. Array elements are\n * concatenated.\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * Mapping from attribute names to their values. Only attribute names\n * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes\n * the attribute to be omitted.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n * @throws {Error} If invalid attribute name or attribute value is provided. If\n * opt_attributes contains the type attribute.\n */\ngoog.html.SafeHtml.createStyle = function(styleSheet, opt_attributes) {\n var fixedAttributes = {'type': 'text/css'};\n var defaultAttributes = {};\n var attributes = goog.html.SafeHtml.combineAttributes(\n fixedAttributes, defaultAttributes, opt_attributes);\n\n var content = '';\n styleSheet = goog.array.concat(styleSheet);\n for (var i = 0; i < styleSheet.length; i++) {\n content += goog.html.SafeStyleSheet.unwrap(styleSheet[i]);\n }\n // Convert to SafeHtml so that it's not HTML-escaped. This is safe because\n // as part of its contract, SafeStyleSheet should have no dangerous '<'.\n var htmlContent =\n goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n content, goog.i18n.bidi.Dir.NEUTRAL);\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'style', attributes, htmlContent);\n};\n\n\n/**\n * Creates a SafeHtml representing a meta refresh tag.\n * @param {!goog.html.SafeUrl|string} url Where to redirect. If a string is\n * passed, it will be sanitized with SafeUrl.sanitize().\n * @param {number=} opt_secs Number of seconds until the page should be\n * reloaded. Will be set to 0 if unspecified.\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n */\ngoog.html.SafeHtml.createMetaRefresh = function(url, opt_secs) {\n\n // Note that sanitize is a no-op on SafeUrl.\n var unwrappedUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url));\n\n if (goog.labs.userAgent.browser.isIE() ||\n goog.labs.userAgent.browser.isEdge()) {\n // IE/EDGE can't parse the content attribute if the url contains a\n // semicolon. We can fix this by adding quotes around the url, but then we\n // can't parse quotes in the URL correctly. Also, it seems that IE/EDGE\n // did not unescape semicolons in these URLs at some point in the past. We\n // take a best-effort approach.\n //\n // If the URL has semicolons (which may happen in some cases, see\n // http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2\n // for instance), wrap it in single quotes to protect the semicolons.\n // If the URL has semicolons and single quotes, url-encode the single quotes\n // as well.\n //\n // This is imperfect. Notice that both ' and ; are reserved characters in\n // URIs, so this could do the wrong thing, but at least it will do the wrong\n // thing in only rare cases.\n if (goog.string.internal.contains(unwrappedUrl, ';')) {\n unwrappedUrl = \"'\" + unwrappedUrl.replace(/'/g, '%27') + \"'\";\n }\n }\n var attributes = {\n 'http-equiv': 'refresh',\n 'content': (opt_secs || 0) + '; url=' + unwrappedUrl\n };\n\n // This function will handle the HTML escaping for attributes.\n return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(\n 'meta', attributes);\n};\n\n\n/**\n * @param {string} tagName The tag name.\n * @param {string} name The attribute name.\n * @param {!goog.html.SafeHtml.AttributeValue} value The attribute value.\n * @return {string} A \"name=value\" string.\n * @throws {Error} If attribute value is unsafe for the given tag and attribute.\n * @private\n */\ngoog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) {\n // If it's goog.string.Const, allow any valid attribute name.\n if (value instanceof goog.string.Const) {\n value = goog.string.Const.unwrap(value);\n } else if (name.toLowerCase() == 'style') {\n if (goog.html.SafeHtml.SUPPORT_STYLE_ATTRIBUTE) {\n value = goog.html.SafeHtml.getStyleValue_(value);\n } else {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'Attribute \"style\" not supported.' :\n '');\n }\n } else if (/^on/i.test(name)) {\n // TODO(jakubvrana): Disallow more attributes with a special meaning.\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ? 'Attribute \"' + name +\n '\" requires goog.string.Const value, \"' + value + '\" given.' :\n '');\n // URL attributes handled differently according to tag.\n } else if (name.toLowerCase() in goog.html.SafeHtml.URL_ATTRIBUTES_) {\n if (value instanceof goog.html.TrustedResourceUrl) {\n value = goog.html.TrustedResourceUrl.unwrap(value);\n } else if (value instanceof goog.html.SafeUrl) {\n value = goog.html.SafeUrl.unwrap(value);\n } else if (typeof value === 'string') {\n value = goog.html.SafeUrl.sanitize(value).getTypedStringValue();\n } else {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'Attribute \"' + name + '\" on tag \"' + tagName +\n '\" requires goog.html.SafeUrl, goog.string.Const, or' +\n ' string, value \"' + value + '\" given.' :\n '');\n }\n }\n\n // Accept SafeUrl, TrustedResourceUrl, etc. for attributes which only require\n // HTML-escaping.\n if (value.implementsGoogStringTypedString) {\n // Ok to call getTypedStringValue() since there's no reliance on the type\n // contract for security here.\n value =\n /** @type {!goog.string.TypedString} */ (value).getTypedStringValue();\n }\n\n goog.asserts.assert(\n typeof value === 'string' || typeof value === 'number',\n 'String or number value expected, got ' + (typeof value) +\n ' with value: ' + value);\n return name + '=\"' + goog.string.internal.htmlEscape(String(value)) + '\"';\n};\n\n\n/**\n * Gets value allowed in \"style\" attribute.\n * @param {!goog.html.SafeHtml.AttributeValue} value It could be SafeStyle or a\n * map which will be passed to goog.html.SafeStyle.create.\n * @return {string} Unwrapped value.\n * @throws {Error} If string value is given.\n * @private\n */\ngoog.html.SafeHtml.getStyleValue_ = function(value) {\n if (!goog.isObject(value)) {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'The \"style\" attribute requires goog.html.SafeStyle or map ' +\n 'of style properties, ' + (typeof value) + ' given: ' + value :\n '');\n }\n if (!(value instanceof goog.html.SafeStyle)) {\n // Process the property bag into a style object.\n value = goog.html.SafeStyle.create(value);\n }\n return goog.html.SafeStyle.unwrap(value);\n};\n\n\n/**\n * Creates a SafeHtml content with known directionality consisting of a tag with\n * optional attributes and optional content.\n * @param {!goog.i18n.bidi.Dir} dir Directionality.\n * @param {string} tagName\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * @param {!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content\n * @return {!goog.html.SafeHtml} The SafeHtml content with the tag.\n */\ngoog.html.SafeHtml.createWithDir = function(\n dir, tagName, opt_attributes, opt_content) {\n var html = goog.html.SafeHtml.create(tagName, opt_attributes, opt_content);\n html.dir_ = dir;\n return html;\n};\n\n\n/**\n * Creates a new SafeHtml object by joining the parts with separator.\n * @param {!goog.html.SafeHtml.TextOrHtml_} separator\n * @param {!Array<!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>>} parts Parts to join. If a part\n * contains an array then each member of this array is also joined with the\n * separator.\n * @return {!goog.html.SafeHtml}\n */\ngoog.html.SafeHtml.join = function(separator, parts) {\n var separatorHtml = goog.html.SafeHtml.htmlEscape(separator);\n var dir = separatorHtml.getDirection();\n var content = [];\n\n /**\n * @param {!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>} argument\n */\n var addArgument = function(argument) {\n if (Array.isArray(argument)) {\n goog.array.forEach(argument, addArgument);\n } else {\n var html = goog.html.SafeHtml.htmlEscape(argument);\n content.push(goog.html.SafeHtml.unwrap(html));\n var htmlDir = html.getDirection();\n if (dir == goog.i18n.bidi.Dir.NEUTRAL) {\n dir = htmlDir;\n } else if (htmlDir != goog.i18n.bidi.Dir.NEUTRAL && dir != htmlDir) {\n dir = null;\n }\n }\n };\n\n goog.array.forEach(parts, addArgument);\n return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n content.join(goog.html.SafeHtml.unwrap(separatorHtml)), dir);\n};\n\n\n/**\n * Creates a new SafeHtml object by concatenating values.\n * @param {...(!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>)} var_args Values to concatenate.\n * @return {!goog.html.SafeHtml}\n */\ngoog.html.SafeHtml.concat = function(var_args) {\n return goog.html.SafeHtml.join(\n goog.html.SafeHtml.EMPTY, Array.prototype.slice.call(arguments));\n};\n\n\n/**\n * Creates a new SafeHtml object with known directionality by concatenating the\n * values.\n * @param {!goog.i18n.bidi.Dir} dir Directionality.\n * @param {...(!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>)} var_args Elements of array\n * arguments would be processed recursively.\n * @return {!goog.html.SafeHtml}\n */\ngoog.html.SafeHtml.concatWithDir = function(dir, var_args) {\n var html = goog.html.SafeHtml.concat(goog.array.slice(arguments, 1));\n html.dir_ = dir;\n return html;\n};\n\n\n/**\n * Type marker for the SafeHtml type, used to implement additional run-time\n * type checking.\n * @const {!Object}\n * @private\n */\ngoog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n\n\n/**\n * Package-internal utility method to create SafeHtml instances.\n *\n * @param {string} html The string to initialize the SafeHtml object with.\n * @param {?goog.i18n.bidi.Dir} dir The directionality of the SafeHtml to be\n * constructed, or null if unknown.\n * @return {!goog.html.SafeHtml} The initialized SafeHtml object.\n * @package\n */\ngoog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse = function(\n html, dir) {\n return new goog.html.SafeHtml().initSecurityPrivateDoNotAccessOrElse_(\n html, dir);\n};\n\n\n/**\n * Called from createSafeHtmlSecurityPrivateDoNotAccessOrElse(). This\n * method exists only so that the compiler can dead code eliminate static\n * fields (like EMPTY) when they're not accessed.\n * @param {string} html\n * @param {?goog.i18n.bidi.Dir} dir\n * @return {!goog.html.SafeHtml}\n * @private\n */\ngoog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(\n html, dir) {\n this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ =\n goog.html.trustedtypes.PRIVATE_DO_NOT_ACCESS_OR_ELSE_POLICY ?\n goog.html.trustedtypes.PRIVATE_DO_NOT_ACCESS_OR_ELSE_POLICY.createHTML(\n html) :\n html;\n this.dir_ = dir;\n return this;\n};\n\n\n/**\n * Like create() but does not restrict which tags can be constructed.\n *\n * @param {string} tagName Tag name. Set or validated by caller.\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * @param {(!goog.html.SafeHtml.TextOrHtml_|\n * !Array<!goog.html.SafeHtml.TextOrHtml_>)=} opt_content\n * @return {!goog.html.SafeHtml}\n * @throws {Error} If invalid or unsafe attribute name or value is provided.\n * @throws {goog.asserts.AssertionError} If content for void tag is provided.\n * @package\n */\ngoog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = function(\n tagName, opt_attributes, opt_content) {\n var dir = null;\n var result = '<' + tagName;\n result += goog.html.SafeHtml.stringifyAttributes(tagName, opt_attributes);\n\n var content = opt_content;\n if (content == null) {\n content = [];\n } else if (!Array.isArray(content)) {\n content = [content];\n }\n\n if (goog.dom.tags.isVoidTag(tagName.toLowerCase())) {\n goog.asserts.assert(\n !content.length, 'Void tag <' + tagName + '> does not allow content.');\n result += '>';\n } else {\n var html = goog.html.SafeHtml.concat(content);\n result += '>' + goog.html.SafeHtml.unwrap(html) + '</' + tagName + '>';\n dir = html.getDirection();\n }\n\n var dirAttribute = opt_attributes && opt_attributes['dir'];\n if (dirAttribute) {\n if (/^(ltr|rtl|auto)$/i.test(dirAttribute)) {\n // If the tag has the \"dir\" attribute specified then its direction is\n // neutral because it can be safely used in any context.\n dir = goog.i18n.bidi.Dir.NEUTRAL;\n } else {\n dir = null;\n }\n }\n\n return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n result, dir);\n};\n\n\n/**\n * Creates a string with attributes to insert after tagName.\n * @param {string} tagName\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * @return {string} Returns an empty string if there are no attributes, returns\n * a string starting with a space otherwise.\n * @throws {Error} If attribute value is unsafe for the given tag and attribute.\n * @package\n */\ngoog.html.SafeHtml.stringifyAttributes = function(tagName, opt_attributes) {\n var result = '';\n if (opt_attributes) {\n for (var name in opt_attributes) {\n if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(name)) {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'Invalid attribute name \"' + name + '\".' :\n '');\n }\n var value = opt_attributes[name];\n if (value == null) {\n continue;\n }\n result +=\n ' ' + goog.html.SafeHtml.getAttrNameAndValue_(tagName, name, value);\n }\n }\n return result;\n};\n\n\n/**\n * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>} fixedAttributes\n * @param {!Object<string, string>} defaultAttributes\n * @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes\n * Optional attributes passed to create*().\n * @return {!Object<string, ?goog.html.SafeHtml.AttributeValue>}\n * @throws {Error} If opt_attributes contains an attribute with the same name\n * as an attribute in fixedAttributes.\n * @package\n */\ngoog.html.SafeHtml.combineAttributes = function(\n fixedAttributes, defaultAttributes, opt_attributes) {\n var combinedAttributes = {};\n var name;\n\n for (name in fixedAttributes) {\n goog.asserts.assert(name.toLowerCase() == name, 'Must be lower case');\n combinedAttributes[name] = fixedAttributes[name];\n }\n for (name in defaultAttributes) {\n goog.asserts.assert(name.toLowerCase() == name, 'Must be lower case');\n combinedAttributes[name] = defaultAttributes[name];\n }\n\n if (opt_attributes) {\n for (name in opt_attributes) {\n var nameLower = name.toLowerCase();\n if (nameLower in fixedAttributes) {\n throw new Error(\n goog.html.SafeHtml.ENABLE_ERROR_MESSAGES ?\n 'Cannot override \"' + nameLower + '\" attribute, got \"' + name +\n '\" with value \"' + opt_attributes[name] + '\"' :\n '');\n }\n if (nameLower in defaultAttributes) {\n delete combinedAttributes[nameLower];\n }\n combinedAttributes[name] = opt_attributes[name];\n }\n }\n\n return combinedAttributes;\n};\n\n\n/**\n * A SafeHtml instance corresponding to the HTML doctype: \"<!DOCTYPE html>\".\n * @const {!goog.html.SafeHtml}\n */\ngoog.html.SafeHtml.DOCTYPE_HTML =\n goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n '<!DOCTYPE html>', goog.i18n.bidi.Dir.NEUTRAL);\n\n\n/**\n * A SafeHtml instance corresponding to the empty string.\n * @const {!goog.html.SafeHtml}\n */\ngoog.html.SafeHtml.EMPTY =\n goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n '', goog.i18n.bidi.Dir.NEUTRAL);\n\n\n/**\n * A SafeHtml instance corresponding to the <br> tag.\n * @const {!goog.html.SafeHtml}\n */\ngoog.html.SafeHtml.BR =\n goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(\n '<br>', goog.i18n.bidi.Dir.NEUTRAL);\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Type-safe wrappers for unsafe DOM APIs.\n *\n * This file provides type-safe wrappers for DOM APIs that can result in\n * cross-site scripting (XSS) vulnerabilities, if the API is supplied with\n * untrusted (attacker-controlled) input. Instead of plain strings, the type\n * safe wrappers consume values of types from the goog.html package whose\n * contract promises that values are safe to use in the corresponding context.\n *\n * Hence, a program that exclusively uses the wrappers in this file (i.e., whose\n * only reference to security-sensitive raw DOM APIs are in this file) is\n * guaranteed to be free of XSS due to incorrect use of such DOM APIs (modulo\n * correctness of code that produces values of the respective goog.html types,\n * and absent code that violates type safety).\n *\n * For example, assigning to an element's .innerHTML property a string that is\n * derived (even partially) from untrusted input typically results in an XSS\n * vulnerability. The type-safe wrapper goog.dom.safe.setInnerHtml consumes a\n * value of type goog.html.SafeHtml, whose contract states that using its values\n * in a HTML context will not result in XSS. Hence a program that is free of\n * direct assignments to any element's innerHTML property (with the exception of\n * the assignment to .innerHTML in this file) is guaranteed to be free of XSS\n * due to assignment of untrusted strings to the innerHTML property.\n */\n\ngoog.provide('goog.dom.safe');\ngoog.provide('goog.dom.safe.InsertAdjacentHtmlPosition');\n\ngoog.require('goog.asserts');\ngoog.require('goog.dom.asserts');\ngoog.require('goog.functions');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.SafeScript');\ngoog.require('goog.html.SafeStyle');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.internal');\n\n\n/** @enum {string} */\ngoog.dom.safe.InsertAdjacentHtmlPosition = {\n AFTERBEGIN: 'afterbegin',\n AFTEREND: 'afterend',\n BEFOREBEGIN: 'beforebegin',\n BEFOREEND: 'beforeend'\n};\n\n\n/**\n * Inserts known-safe HTML into a Node, at the specified position.\n * @param {!Node} node The node on which to call insertAdjacentHTML.\n * @param {!goog.dom.safe.InsertAdjacentHtmlPosition} position Position where\n * to insert the HTML.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to insert.\n */\ngoog.dom.safe.insertAdjacentHtml = function(node, position, html) {\n node.insertAdjacentHTML(position, goog.html.SafeHtml.unwrapTrustedHTML(html));\n};\n\n\n/**\n * Tags not allowed in goog.dom.safe.setInnerHtml.\n * @private @const {!Object<string, boolean>}\n */\ngoog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_ = {\n 'MATH': true,\n 'SCRIPT': true,\n 'STYLE': true,\n 'SVG': true,\n 'TEMPLATE': true\n};\n\n\n/**\n * Whether assigning to innerHTML results in a non-spec-compliant clean-up. Used\n * to define goog.dom.safe.unsafeSetInnerHtmlDoNotUseOrElse.\n *\n * <p>As mentioned in https://stackoverflow.com/questions/28741528, re-rendering\n * an element in IE by setting innerHTML causes IE to recursively disconnect all\n * parent/children connections that were in the previous contents of the\n * element. Unfortunately, this can unexpectedly result in confusing cases where\n * a function is run (typically asynchronously) on element that has since\n * disconnected from the DOM but assumes the presence of its children. A simple\n * workaround is to remove all children first. Testing on IE11 via\n * https://jsperf.com/innerhtml-vs-removechild/239, removeChild seems to be\n * ~10x faster than innerHTML='' for a large number of children (perhaps due\n * to the latter's recursive behavior), implying that this workaround would\n * not hurt performance and might actually improve it.\n * @return {boolean}\n * @private\n */\ngoog.dom.safe.isInnerHtmlCleanupRecursive_ =\n goog.functions.cacheReturnValue(function() {\n // `document` missing in some test frameworks.\n if (goog.DEBUG && typeof document === 'undefined') {\n return false;\n }\n // Create 3 nested <div>s without using innerHTML.\n // We're not chaining the appendChilds in one call, as this breaks\n // in a DocumentFragment.\n var div = document.createElement('div');\n var childDiv = document.createElement('div');\n childDiv.appendChild(document.createElement('div'));\n div.appendChild(childDiv);\n // `firstChild` is null in Google Js Test.\n if (goog.DEBUG && !div.firstChild) {\n return false;\n }\n var innerChild = div.firstChild.firstChild;\n div.innerHTML =\n goog.html.SafeHtml.unwrapTrustedHTML(goog.html.SafeHtml.EMPTY);\n return !innerChild.parentElement;\n });\n\n\n/**\n * Assigns HTML to an element's innerHTML property. Helper to use only here and\n * in soy.js.\n * @param {?Element} elem The element whose innerHTML is to be assigned to.\n * @param {!goog.html.SafeHtml} html\n */\ngoog.dom.safe.unsafeSetInnerHtmlDoNotUseOrElse = function(elem, html) {\n // See comment above goog.dom.safe.isInnerHtmlCleanupRecursive_.\n if (goog.dom.safe.isInnerHtmlCleanupRecursive_()) {\n while (elem.lastChild) {\n elem.removeChild(elem.lastChild);\n }\n }\n elem.innerHTML = goog.html.SafeHtml.unwrapTrustedHTML(html);\n};\n\n\n/**\n * Assigns known-safe HTML to an element's innerHTML property.\n * @param {!Element} elem The element whose innerHTML is to be assigned to.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.\n * @throws {Error} If called with one of these tags: math, script, style, svg,\n * template.\n */\ngoog.dom.safe.setInnerHtml = function(elem, html) {\n if (goog.asserts.ENABLE_ASSERTS) {\n var tagName = elem.tagName.toUpperCase();\n if (goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_[tagName]) {\n throw new Error(\n 'goog.dom.safe.setInnerHtml cannot be used to set content of ' +\n elem.tagName + '.');\n }\n }\n\n goog.dom.safe.unsafeSetInnerHtmlDoNotUseOrElse(elem, html);\n};\n\n\n/**\n * Assigns known-safe HTML to an element's outerHTML property.\n * @param {!Element} elem The element whose outerHTML is to be assigned to.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.\n */\ngoog.dom.safe.setOuterHtml = function(elem, html) {\n elem.outerHTML = goog.html.SafeHtml.unwrapTrustedHTML(html);\n};\n\n\n/**\n * Safely assigns a URL a form element's action property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * form's action property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.setFormElementAction(formEl, url);\n * which is a safe alternative to\n * formEl.action = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!Element} form The form element whose action property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setFormElementAction = function(form, url) {\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n goog.dom.asserts.assertIsHTMLFormElement(form).action =\n goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to a button element's formaction property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * button's formaction property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.setButtonFormAction(buttonEl, url);\n * which is a safe alternative to\n * buttonEl.action = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!Element} button The button element whose action property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setButtonFormAction = function(button, url) {\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n goog.dom.asserts.assertIsHTMLButtonElement(button).formAction =\n goog.html.SafeUrl.unwrap(safeUrl);\n};\n/**\n * Safely assigns a URL to an input element's formaction property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * input's formaction property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.setInputFormAction(inputEl, url);\n * which is a safe alternative to\n * inputEl.action = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!Element} input The input element whose action property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setInputFormAction = function(input, url) {\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n goog.dom.asserts.assertIsHTMLInputElement(input).formAction =\n goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Sets the given element's style property to the contents of the provided\n * SafeStyle object.\n * @param {!Element} elem\n * @param {!goog.html.SafeStyle} style\n */\ngoog.dom.safe.setStyle = function(elem, style) {\n elem.style.cssText = goog.html.SafeStyle.unwrap(style);\n};\n\n\n/**\n * Writes known-safe HTML to a document.\n * @param {!Document} doc The document to be written to.\n * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.\n */\ngoog.dom.safe.documentWrite = function(doc, html) {\n doc.write(goog.html.SafeHtml.unwrapTrustedHTML(html));\n};\n\n\n/**\n * Safely assigns a URL to an anchor element's href property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * anchor's href property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.setAnchorHref(anchorEl, url);\n * which is a safe alternative to\n * anchorEl.href = url;\n * The latter can result in XSS vulnerabilities if url is a\n * user-/attacker-controlled value.\n *\n * @param {!HTMLAnchorElement} anchor The anchor element whose href property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setAnchorHref = function(anchor, url) {\n goog.dom.asserts.assertIsHTMLAnchorElement(anchor);\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n anchor.href = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n\n/**\n * Safely assigns a URL to an image element's src property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * image's src property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * @param {!HTMLImageElement} imageElement The image element whose src property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setImageSrc = function(imageElement, url) {\n goog.dom.asserts.assertIsHTMLImageElement(imageElement);\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n var allowDataUrl = /^data:image\\//i.test(url);\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url, allowDataUrl);\n }\n imageElement.src = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to a audio element's src property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * audio's src property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * @param {!HTMLAudioElement} audioElement The audio element whose src property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setAudioSrc = function(audioElement, url) {\n goog.dom.asserts.assertIsHTMLAudioElement(audioElement);\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n var allowDataUrl = /^data:audio\\//i.test(url);\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url, allowDataUrl);\n }\n audioElement.src = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to a video element's src property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * video's src property. If url is of type string however, it is first\n * sanitized using goog.html.SafeUrl.sanitize.\n *\n * @param {!HTMLVideoElement} videoElement The video element whose src property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setVideoSrc = function(videoElement, url) {\n goog.dom.asserts.assertIsHTMLVideoElement(videoElement);\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n var allowDataUrl = /^data:video\\//i.test(url);\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url, allowDataUrl);\n }\n videoElement.src = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns a URL to an embed element's src property.\n *\n * Example usage:\n * goog.dom.safe.setEmbedSrc(embedEl, url);\n * which is a safe alternative to\n * embedEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLEmbedElement} embed The embed element whose src property\n * is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setEmbedSrc = function(embed, url) {\n goog.dom.asserts.assertIsHTMLEmbedElement(embed);\n embed.src = goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(url);\n};\n\n\n/**\n * Safely assigns a URL to a frame element's src property.\n *\n * Example usage:\n * goog.dom.safe.setFrameSrc(frameEl, url);\n * which is a safe alternative to\n * frameEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLFrameElement} frame The frame element whose src property\n * is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setFrameSrc = function(frame, url) {\n goog.dom.asserts.assertIsHTMLFrameElement(frame);\n frame.src = goog.html.TrustedResourceUrl.unwrap(url);\n};\n\n\n/**\n * Safely assigns a URL to an iframe element's src property.\n *\n * Example usage:\n * goog.dom.safe.setIframeSrc(iframeEl, url);\n * which is a safe alternative to\n * iframeEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLIFrameElement} iframe The iframe element whose src property\n * is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setIframeSrc = function(iframe, url) {\n goog.dom.asserts.assertIsHTMLIFrameElement(iframe);\n iframe.src = goog.html.TrustedResourceUrl.unwrap(url);\n};\n\n\n/**\n * Safely assigns HTML to an iframe element's srcdoc property.\n *\n * Example usage:\n * goog.dom.safe.setIframeSrcdoc(iframeEl, safeHtml);\n * which is a safe alternative to\n * iframeEl.srcdoc = html;\n * The latter can result in loading untrusted code.\n *\n * @param {!HTMLIFrameElement} iframe The iframe element whose srcdoc property\n * is to be assigned to.\n * @param {!goog.html.SafeHtml} html The HTML to assign.\n */\ngoog.dom.safe.setIframeSrcdoc = function(iframe, html) {\n goog.dom.asserts.assertIsHTMLIFrameElement(iframe);\n iframe.srcdoc = goog.html.SafeHtml.unwrapTrustedHTML(html);\n};\n\n\n/**\n * Safely sets a link element's href and rel properties. Whether or not\n * the URL assigned to href has to be a goog.html.TrustedResourceUrl\n * depends on the value of the rel property. If rel contains \"stylesheet\"\n * then a TrustedResourceUrl is required.\n *\n * Example usage:\n * goog.dom.safe.setLinkHrefAndRel(linkEl, url, 'stylesheet');\n * which is a safe alternative to\n * linkEl.rel = 'stylesheet';\n * linkEl.href = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLLinkElement} link The link element whose href property\n * is to be assigned to.\n * @param {string|!goog.html.SafeUrl|!goog.html.TrustedResourceUrl} url The URL\n * to assign to the href property. Must be a TrustedResourceUrl if the\n * value assigned to rel contains \"stylesheet\". A string value is\n * sanitized with goog.html.SafeUrl.sanitize.\n * @param {string} rel The value to assign to the rel property.\n * @throws {Error} if rel contains \"stylesheet\" and url is not a\n * TrustedResourceUrl\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {\n goog.dom.asserts.assertIsHTMLLinkElement(link);\n link.rel = rel;\n if (goog.string.internal.caseInsensitiveContains(rel, 'stylesheet')) {\n goog.asserts.assert(\n url instanceof goog.html.TrustedResourceUrl,\n 'URL must be TrustedResourceUrl because \"rel\" contains \"stylesheet\"');\n link.href = goog.html.TrustedResourceUrl.unwrap(url);\n } else if (url instanceof goog.html.TrustedResourceUrl) {\n link.href = goog.html.TrustedResourceUrl.unwrap(url);\n } else if (url instanceof goog.html.SafeUrl) {\n link.href = goog.html.SafeUrl.unwrap(url);\n } else { // string\n // SafeUrl.sanitize must return legitimate SafeUrl when passed a string.\n link.href = goog.html.SafeUrl.unwrap(\n goog.html.SafeUrl.sanitizeAssertUnchanged(url));\n }\n};\n\n\n/**\n * Safely assigns a URL to an object element's data property.\n *\n * Example usage:\n * goog.dom.safe.setObjectData(objectEl, url);\n * which is a safe alternative to\n * objectEl.data = url;\n * The latter can result in loading untrusted code unless setit is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLObjectElement} object The object element whose data property\n * is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setObjectData = function(object, url) {\n goog.dom.asserts.assertIsHTMLObjectElement(object);\n object.data = goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(url);\n};\n\n\n/**\n * Safely assigns a URL to a script element's src property.\n *\n * Example usage:\n * goog.dom.safe.setScriptSrc(scriptEl, url);\n * which is a safe alternative to\n * scriptEl.src = url;\n * The latter can result in loading untrusted code unless it is ensured that\n * the URL refers to a trustworthy resource.\n *\n * @param {!HTMLScriptElement} script The script element whose src property\n * is to be assigned to.\n * @param {!goog.html.TrustedResourceUrl} url The URL to assign.\n */\ngoog.dom.safe.setScriptSrc = function(script, url) {\n goog.dom.asserts.assertIsHTMLScriptElement(script);\n script.src = goog.html.TrustedResourceUrl.unwrapTrustedScriptURL(url);\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 script.setAttribute('nonce', nonce);\n }\n};\n\n\n/**\n * Safely assigns a value to a script element's content.\n *\n * Example usage:\n * goog.dom.safe.setScriptContent(scriptEl, content);\n * which is a safe alternative to\n * scriptEl.text = content;\n * The latter can result in executing untrusted code unless it is ensured that\n * the code is loaded from a trustworthy resource.\n *\n * @param {!HTMLScriptElement} script The script element whose content is being\n * set.\n * @param {!goog.html.SafeScript} content The content to assign.\n */\ngoog.dom.safe.setScriptContent = function(script, content) {\n goog.dom.asserts.assertIsHTMLScriptElement(script);\n script.text = goog.html.SafeScript.unwrapTrustedScript(content);\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 script.setAttribute('nonce', nonce);\n }\n};\n\n\n/**\n * Safely assigns a URL to a Location object's href property.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to\n * loc's href property. If url is of type string however, it is first sanitized\n * using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.setLocationHref(document.location, redirectUrl);\n * which is a safe alternative to\n * document.location.href = redirectUrl;\n * The latter can result in XSS vulnerabilities if redirectUrl is a\n * user-/attacker-controlled value.\n *\n * @param {!Location} loc The Location object whose href property is to be\n * assigned to.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.setLocationHref = function(loc, url) {\n goog.dom.asserts.assertIsLocation(loc);\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n loc.href = goog.html.SafeUrl.unwrap(safeUrl);\n};\n\n/**\n * Safely assigns the URL of a Location object.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and\n * passed to Location#assign. If url is of type string however, it is\n * first sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.assignLocation(document.location, newUrl);\n * which is a safe alternative to\n * document.location.assign(newUrl);\n * The latter can result in XSS vulnerabilities if newUrl is a\n * user-/attacker-controlled value.\n *\n * This has the same behaviour as setLocationHref, however some test\n * mock Location.assign instead of a property assignment.\n *\n * @param {!Location} loc The Location object which is to be assigned.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.assignLocation = function(loc, url) {\n goog.dom.asserts.assertIsLocation(loc);\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n loc.assign(goog.html.SafeUrl.unwrap(safeUrl));\n};\n\n\n/**\n * Safely replaces the URL of a Location object.\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and\n * passed to Location#replace. If url is of type string however, it is\n * first sanitized using goog.html.SafeUrl.sanitize.\n *\n * Example usage:\n * goog.dom.safe.replaceLocation(document.location, newUrl);\n * which is a safe alternative to\n * document.location.replace(newUrl);\n * The latter can result in XSS vulnerabilities if newUrl is a\n * user-/attacker-controlled value.\n *\n * @param {!Location} loc The Location object which is to be replaced.\n * @param {string|!goog.html.SafeUrl} url The URL to assign.\n * @see goog.html.SafeUrl#sanitize\n */\ngoog.dom.safe.replaceLocation = function(loc, url) {\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n loc.replace(goog.html.SafeUrl.unwrap(safeUrl));\n};\n\n\n/**\n * Safely opens a URL in a new window (via window.open).\n *\n * If url is of type goog.html.SafeUrl, its value is unwrapped and passed in to\n * window.open. If url is of type string however, it is first sanitized\n * using goog.html.SafeUrl.sanitize.\n *\n * Note that this function does not prevent leakages via the referer that is\n * sent by window.open. It is advised to only use this to open 1st party URLs.\n *\n * Example usage:\n * goog.dom.safe.openInWindow(url);\n * which is a safe alternative to\n * window.open(url);\n * The latter can result in XSS vulnerabilities if redirectUrl is a\n * user-/attacker-controlled value.\n *\n * @param {string|!goog.html.SafeUrl} url The URL to open.\n * @param {Window=} opt_openerWin Window of which to call the .open() method.\n * Defaults to the global window.\n * @param {!goog.string.Const=} opt_name Name of the window to open in. Can be\n * _top, etc as allowed by window.open().\n * @param {string=} opt_specs Comma-separated list of specifications, same as\n * in window.open().\n * @param {boolean=} opt_replace Whether to replace the current entry in browser\n * history, same as in window.open().\n * @return {Window} Window the url was opened in.\n */\ngoog.dom.safe.openInWindow = function(\n url, opt_openerWin, opt_name, opt_specs, opt_replace) {\n /** @type {!goog.html.SafeUrl} */\n var safeUrl;\n if (url instanceof goog.html.SafeUrl) {\n safeUrl = url;\n } else {\n safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);\n }\n var win = opt_openerWin || goog.global;\n return win.open(\n goog.html.SafeUrl.unwrap(safeUrl),\n // If opt_name is undefined, simply passing that in to open() causes IE to\n // reuse the current window instead of opening a new one. Thus we pass ''\n // in instead, which according to spec opens a new window. See\n // https://html.spec.whatwg.org/multipage/browsers.html#dom-open .\n opt_name ? goog.string.Const.unwrap(opt_name) : '', opt_specs,\n opt_replace);\n};\n\n\n/**\n * Parses the HTML as 'text/html'.\n * @param {!DOMParser} parser\n * @param {!goog.html.SafeHtml} html The HTML to be parsed.\n * @return {?Document}\n */\ngoog.dom.safe.parseFromStringHtml = function(parser, html) {\n return goog.dom.safe.parseFromString(parser, html, 'text/html');\n};\n\n\n/**\n * Parses the string.\n * @param {!DOMParser} parser\n * @param {!goog.html.SafeHtml} content Note: We don't have a special type for\n * XML od SVG supported by this function so we use SafeHtml.\n * @param {string} type\n * @return {?Document}\n */\ngoog.dom.safe.parseFromString = function(parser, content, type) {\n return parser.parseFromString(\n goog.html.SafeHtml.unwrapTrustedHTML(content), type);\n};\n\n\n/**\n * Safely creates an HTMLImageElement from a Blob.\n *\n * Example usage:\n * goog.dom.safe.createImageFromBlob(blob);\n * which is a safe alternative to\n * image.src = createObjectUrl(blob)\n * The latter can result in executing malicious same-origin scripts from a bad\n * Blob.\n * @param {!Blob} blob The blob to create the image from.\n * @return {!HTMLImageElement} The image element created from the blob.\n * @throws {!Error} If called with a Blob with a MIME type other than image/.*.\n */\ngoog.dom.safe.createImageFromBlob = function(blob) {\n // Any image/* MIME type is accepted as safe.\n if (!/^image\\/.*/g.test(blob.type)) {\n throw new Error(\n 'goog.dom.safe.createImageFromBlob only accepts MIME type image/.*.');\n }\n var objectUrl = goog.global.URL.createObjectURL(blob);\n var image = new goog.global.Image();\n image.onload = function() {\n goog.global.URL.revokeObjectURL(objectUrl);\n };\n goog.dom.safe.setImageSrc(\n image,\n goog.html.uncheckedconversions\n .safeUrlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from('Image blob URL.'), objectUrl));\n return image;\n};\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 schedule running a function as soon\n * as possible after the current JS execution stops and yields to the event\n * loop.\n */\n\ngoog.provide('goog.async.nextTick');\ngoog.provide('goog.async.throwException');\n\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.functions');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.string.Const');\n\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 */\ngoog.async.throwException = function(exception) {\n // Each throw needs to be in its own context.\n goog.global.setTimeout(function() { throw exception; }, 0);\n};\n\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) takes at least 4ms when called from\n * within another setTimeout(…, 0) for legacy reasons.\n *\n * This will not schedule the callback as a microtask (i.e. a task that can\n * preempt user input or networking callbacks). It is meant to emulate what\n * setTimeout(_, 0) would do if it were not throttled. If you desire microtask\n * behavior, use {@see goog.Promise} instead.\n *\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n * possible.\n * @param {SCOPE=} opt_context Object in whose scope to call the listener.\n * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that\n * ensures correctness at the cost of speed. See comments for details.\n * @template SCOPE\n */\ngoog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {\n var cb = callback;\n if (opt_context) {\n cb = goog.bind(callback, opt_context);\n }\n cb = goog.async.nextTick.wrapCallback_(cb);\n // Note we do allow callers to also request setImmediate if they are willing\n // to accept the possible tradeoffs of incorrectness in exchange for speed.\n // The IE fallback of readystate change is much slower. See useSetImmediate_\n // for details.\n if (goog.isFunction(goog.global.setImmediate) &&\n (opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) {\n goog.global.setImmediate(cb);\n return;\n }\n\n // Look for and cache the custom fallback version of setImmediate.\n if (!goog.async.nextTick.setImmediate_) {\n goog.async.nextTick.setImmediate_ =\n goog.async.nextTick.getSetImmediateEmulator_();\n }\n goog.async.nextTick.setImmediate_(cb);\n};\n\n\n/**\n * Returns whether should use setImmediate implementation currently on window.\n *\n * window.setImmediate was introduced and currently only supported by IE10+,\n * but due to a bug in the implementation it is not guaranteed that\n * setImmediate is faster than setTimeout nor that setImmediate N is before\n * setImmediate N+1. That is why we do not use the native version if\n * available. We do, however, call setImmediate if it is a non-native function\n * because that indicates that it has been replaced by goog.testing.MockClock\n * which we do want to support.\n * See\n * http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10\n *\n * @return {boolean} Whether to use the implementation of setImmediate defined\n * on Window.\n * @private\n * @suppress {missingProperties} For \"Window.prototype.setImmediate\"\n */\ngoog.async.nextTick.useSetImmediate_ = function() {\n // Not a browser environment.\n if (!goog.global.Window || !goog.global.Window.prototype) {\n return true;\n }\n\n // MS Edge has window.setImmediate natively, but it's not on Window.prototype.\n // Also, there's no clean way to detect if the goog.global.setImmediate has\n // been replaced by mockClock as its replacement also shows up as \"[native\n // code]\" when using toString. Therefore, just always use\n // goog.global.setImmediate for Edge. It's unclear if it suffers the same\n // issues as IE10/11, but based on\n // https://dev.modern.ie/testdrive/demos/setimmediatesorting/\n // it seems they've been working to ensure it's WAI.\n if (goog.labs.userAgent.browser.isEdge() ||\n goog.global.Window.prototype.setImmediate != goog.global.setImmediate) {\n // Something redefined setImmediate in which case we decide to use it (This\n // is so that we use the mockClock setImmediate).\n return true;\n }\n\n return false;\n};\n\n\n/**\n * Cache for the setImmediate implementation.\n * @type {function(function())}\n * @private\n */\ngoog.async.nextTick.setImmediate_;\n\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\ngoog.async.nextTick.getSetImmediateEmulator_ = function() {\n // Create a private message channel and use it to postMessage empty messages\n // to ourselves.\n /** @type {!Function|undefined} */\n var Channel = goog.global['MessageChannel'];\n // If MessageChannel is not available and we are in a browser, implement\n // an iframe based polyfill in browsers that have postMessage and\n // document.addEventListener. The latter excludes IE8 because it has a\n // synchronous postMessage implementation.\n if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&\n window.postMessage && window.addEventListener &&\n // Presto (The old pre-blink Opera engine) has problems with iframes\n // and contentWindow.\n !goog.labs.userAgent.engine.isPresto()) {\n /** @constructor */\n Channel = function() {\n // Make an empty, invisible iframe.\n var iframe = goog.dom.createElement(goog.dom.TagName.IFRAME);\n iframe.style.display = 'none';\n goog.dom.safe.setIframeSrc(\n iframe,\n goog.html.TrustedResourceUrl.fromConstant(goog.string.Const.EMPTY));\n document.documentElement.appendChild(iframe);\n var win = iframe.contentWindow;\n var doc = win.document;\n doc.open();\n goog.dom.safe.documentWrite(doc, goog.html.SafeHtml.EMPTY);\n doc.close();\n // Do not post anything sensitive over this channel, as the workaround for\n // pages with file: origin could allow that information to be modified or\n // intercepted.\n var message = 'callImmediate' + Math.random();\n // The same origin policy rejects attempts to postMessage from file: urls\n // unless the origin is '*'.\n var origin = win.location.protocol == 'file:' ?\n '*' :\n win.location.protocol + '//' + win.location.host;\n var onmessage = goog.bind(function(e) {\n // Validate origin and message to make sure that this message was\n // intended for us. If the origin is set to '*' (see above) only the\n // message needs to match since, for example, '*' != 'file://'. Allowing\n // the wildcard is ok, as we are not concerned with security here.\n if ((origin != '*' && e.origin != origin) || e.data != message) {\n return;\n }\n this['port1'].onmessage();\n }, this);\n win.addEventListener('message', onmessage, false);\n this['port1'] = {};\n this['port2'] = {\n postMessage: function() { win.postMessage(message, origin); }\n };\n };\n }\n if (typeof Channel !== 'undefined' && !goog.labs.userAgent.browser.isIE()) {\n // Exclude all of IE due to\n // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/\n // which allows starving postMessage with a busy setTimeout loop.\n // This currently affects IE10 and IE11 which would otherwise be able\n // to use the postMessage based fallbacks.\n var channel = new Channel();\n // Use a fifo linked list to call callbacks in the right order.\n var head = {};\n var tail = head;\n channel['port1'].onmessage = function() {\n if (head.next !== undefined) {\n head = head.next;\n var cb = head.cb;\n head.cb = null;\n cb();\n }\n };\n return function(cb) {\n tail.next = {cb: cb};\n tail = tail.next;\n channel['port2'].postMessage(0);\n };\n }\n // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n // or more.\n // NOTE(user): This fallback is used for IE.\n return function(cb) {\n goog.global.setTimeout(/** @type {function()} */ (cb), 0);\n };\n};\n\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\ngoog.async.nextTick.wrapCallback_ = goog.functions.identity;\n\n\n// Register the callback function as an entry point, so that it can be\n// monitored for exception handling, etc. This has to be done in this file\n// since it requires special code to handle all browsers.\ngoog.debug.entryPointRegistry.register(\n /**\n * @param {function(!Function): !Function} transformer The transforming\n * function.\n */\n function(transformer) { goog.async.nextTick.wrapCallback_ = transformer; });\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};\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 var splitParts = str.split('%s');\n var returnString = '';\n\n var 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 // 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 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 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 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 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 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 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 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 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 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 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 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 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 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 // 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 // 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 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 var tokens1 = str1.toLowerCase().match(tokenizerRegExp);\n var tokens2 = str2.toLowerCase().match(tokenizerRegExp);\n\n var count = Math.min(tokens1.length, tokens2.length);\n\n for (var i = 0; i < count; i++) {\n var a = tokens1[i];\n var 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 var num1 = parseInt(a, 10);\n if (!isNaN(num1)) {\n var 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 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 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 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 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 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 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 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 /** @type {!Object<string, string>} */\n var seen = {'&': '&', '<': '<', '>': '>', '"': '\"'};\n /** @type {!Element} */\n var 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 // Check for cached entity.\n var 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 var n = Number('0' + entity.substr(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 return str.replace(/&([^;]+);/g, function(s, entity) {\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 var n = Number('0' + entity.substr(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 // 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 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 var length = quoteChars.length;\n for (var i = 0; i < length; i++) {\n var 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 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 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 var endPoint = str.length - opt_trailingChars;\n var 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 var half = Math.floor(chars / 2);\n var 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 s = String(s);\n var sb = ['\"'];\n for (var i = 0; i < s.length; i++) {\n var ch = s.charAt(i);\n var 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 var sb = [];\n for (var 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 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 var rv = c;\n var 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 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 var 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.substr(0, index) +\n s.substr(index + stringLength, s.length - 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 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 var 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 var 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 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 // The native method is over 100 times faster than the alternative.\n return string.repeat(length);\n} : function(string, length) {\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 var s =\n (opt_precision !== undefined) ? num.toFixed(opt_precision) : String(num);\n var index = s.indexOf('.');\n if (index == -1) {\n index = s.length;\n }\n return 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 return obj == null ? '' : String(obj);\n};\n\n\n/**\n * Concatenates string expressions. This is useful\n * since some browsers are very inefficient when it comes to using plus to\n * concat strings. Be careful when using null and undefined here since\n * these will not be included in the result. If you need to represent these\n * be sure to cast the argument to a String first.\n * For example:\n * <pre>buildString('a', 'b', 'c', 'd') -> 'abcd'\n * buildString(null, undefined) -> ''\n * </pre>\n * @param {...*} var_args A list of strings to concatenate. If not a string,\n * it will be casted to one.\n * @return {string} The concatenation of `var_args`.\n */\ngoog.string.buildString = function(var_args) {\n return Array.prototype.join.call(arguments, '');\n};\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 var 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 var result = 0;\n for (var 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 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 var 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 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 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 return String(str).replace(/\\-([a-z])/g, function(all, match) {\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 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 var 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 var regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g');\n return str.replace(regexp, function(all, p1, p2) {\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 return String(str.charAt(0)).toUpperCase() +\n String(str.substr(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 // 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 var parts = str.split(separator);\n var 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 if (!separators) {\n return str;\n } else if (typeof separators == 'string') {\n separators = [separators];\n }\n\n var lastSeparatorIndex = -1;\n for (var i = 0; i < separators.length; i++) {\n if (separators[i] == '') {\n continue;\n }\n var 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 var v0 = [];\n var 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 (var i = 0; i < b.length + 1; i++) {\n v0[i] = i;\n }\n\n for (var i = 0; i < a.length; i++) {\n v1[0] = i + 1;\n\n for (var j = 0; j < b.length; j++) {\n var 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 (var 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 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 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 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 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[' '] = goog.nullFunction;\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\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 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 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');\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 return goog.labs.userAgent.util.getUserAgent();\n};\n\n\n/**\n * @return {?Navigator} The native navigator object.\n */\ngoog.userAgent.getNavigatorTyped = function() {\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 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 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 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 a X11 windowing\n * system.\n */\ngoog.userAgent.ASSUME_X11 = goog.define('goog.userAgent.ASSUME_X11', 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_X11 || goog.userAgent.ASSUME_ANDROID ||\n goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n 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 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 * @return {boolean} Whether the user agent is an X11 windowing system.\n * @private\n */\ngoog.userAgent.isX11_ = function() {\n var navigator = goog.userAgent.getNavigatorTyped();\n return !!navigator &&\n goog.string.contains(navigator['appVersion'] || '', 'X11');\n};\n\n\n/**\n * Whether the user agent is running on a X11 windowing system.\n * @type {boolean}\n */\ngoog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_X11 :\n goog.userAgent.isX11_();\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 // 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 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 // 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 return goog.string.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 return goog.userAgent.ASSUME_ANY_VERSION ||\n goog.reflect.cache(\n goog.userAgent.isVersionOrHigherCache_, version, function() {\n return goog.string.compareVersions(\n goog.userAgent.VERSION, version) >= 0;\n });\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isVersionOrHigher`.\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 * @deprecated Use goog.userAgent.isVersionOrHigher().\n */\ngoog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;\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 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 var doc = goog.global['document'];\n if (!doc || !goog.userAgent.IE) {\n return undefined;\n }\n return goog.userAgent.getDocumentMode_();\n})();\n","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\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 * @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.provide('goog.labs.userAgent.browser');\n\ngoog.require('goog.array');\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.object');\ngoog.require('goog.string.internal');\n\n\n// TODO(nnaze): Refactor to remove excessive exclusion logic in matching\n// functions.\n\n\n/**\n * @return {boolean} Whether the user's browser is Opera. Note: Chromium\n * based Opera (Opera 15+) is detected as Chrome to avoid unnecessary\n * special casing.\n * @private\n */\ngoog.labs.userAgent.browser.matchOpera_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Opera');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is IE.\n * @private\n */\ngoog.labs.userAgent.browser.matchIE_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Trident') ||\n goog.labs.userAgent.util.matchUserAgent('MSIE');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Edge. This refers to EdgeHTML\n * based Edge.\n * @private\n */\ngoog.labs.userAgent.browser.matchEdgeHtml_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Edge');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Chromium based Edge.\n * @private\n */\ngoog.labs.userAgent.browser.matchEdgeChromium_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Edg/');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Chromium based Opera.\n * @private\n */\ngoog.labs.userAgent.browser.matchOperaChromium_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('OPR');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Firefox.\n * @private\n */\ngoog.labs.userAgent.browser.matchFirefox_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Firefox') ||\n goog.labs.userAgent.util.matchUserAgent('FxiOS');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Safari.\n * @private\n */\ngoog.labs.userAgent.browser.matchSafari_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Safari') &&\n !(goog.labs.userAgent.browser.matchChrome_() ||\n goog.labs.userAgent.browser.matchCoast_() ||\n goog.labs.userAgent.browser.matchOpera_() ||\n goog.labs.userAgent.browser.matchEdgeHtml_() ||\n goog.labs.userAgent.browser.matchEdgeChromium_() ||\n goog.labs.userAgent.browser.matchOperaChromium_() ||\n goog.labs.userAgent.browser.matchFirefox_() ||\n goog.labs.userAgent.browser.isSilk() ||\n goog.labs.userAgent.util.matchUserAgent('Android'));\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\n * iOS browser).\n * @private\n */\ngoog.labs.userAgent.browser.matchCoast_ = function() {\n return goog.labs.userAgent.util.matchUserAgent('Coast');\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is iOS Webview.\n * @private\n */\ngoog.labs.userAgent.browser.matchIosWebview_ = function() {\n // iOS Webview does not show up as Chrome or Safari. Also check for Opera's\n // WebKit-based iOS browser, Coast.\n return (goog.labs.userAgent.util.matchUserAgent('iPad') ||\n goog.labs.userAgent.util.matchUserAgent('iPhone')) &&\n !goog.labs.userAgent.browser.matchSafari_() &&\n !goog.labs.userAgent.browser.matchChrome_() &&\n !goog.labs.userAgent.browser.matchCoast_() &&\n !goog.labs.userAgent.browser.matchFirefox_() &&\n goog.labs.userAgent.util.matchUserAgent('AppleWebKit');\n};\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 * @private\n */\ngoog.labs.userAgent.browser.matchChrome_ = function() {\n return (goog.labs.userAgent.util.matchUserAgent('Chrome') ||\n goog.labs.userAgent.util.matchUserAgent('CriOS')) &&\n !goog.labs.userAgent.browser.matchEdgeHtml_();\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is the Android browser.\n * @private\n */\ngoog.labs.userAgent.browser.matchAndroidBrowser_ = function() {\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 goog.labs.userAgent.util.matchUserAgent('Android') &&\n !(goog.labs.userAgent.browser.isChrome() ||\n goog.labs.userAgent.browser.isFirefox() ||\n goog.labs.userAgent.browser.isOpera() ||\n goog.labs.userAgent.browser.isSilk());\n};\n\n\n/**\n * @return {boolean} Whether the user's browser is Opera.\n */\ngoog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;\n\n\n/**\n * @return {boolean} Whether the user's browser is IE.\n */\ngoog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;\n\n\n/**\n * @return {boolean} Whether the user's browser is EdgeHTML based Edge.\n */\ngoog.labs.userAgent.browser.isEdge = goog.labs.userAgent.browser.matchEdgeHtml_;\n\n\n/**\n * @return {boolean} Whether the user's browser is Chromium based Edge.\n */\ngoog.labs.userAgent.browser.isEdgeChromium =\n goog.labs.userAgent.browser.matchEdgeChromium_;\n\n/**\n * @return {boolean} Whether the user's browser is Chromium based Opera.\n */\ngoog.labs.userAgent.browser.isOperaChromium =\n goog.labs.userAgent.browser.matchOperaChromium_;\n\n/**\n * @return {boolean} Whether the user's browser is Firefox.\n */\ngoog.labs.userAgent.browser.isFirefox =\n goog.labs.userAgent.browser.matchFirefox_;\n\n\n/**\n * @return {boolean} Whether the user's browser is Safari.\n */\ngoog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_;\n\n\n/**\n * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based\n * iOS browser).\n */\ngoog.labs.userAgent.browser.isCoast = goog.labs.userAgent.browser.matchCoast_;\n\n\n/**\n * @return {boolean} Whether the user's browser is iOS Webview.\n */\ngoog.labs.userAgent.browser.isIosWebview =\n goog.labs.userAgent.browser.matchIosWebview_;\n\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 */\ngoog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_;\n\n\n/**\n * @return {boolean} Whether the user's browser is the Android browser.\n */\ngoog.labs.userAgent.browser.isAndroidBrowser =\n goog.labs.userAgent.browser.matchAndroidBrowser_;\n\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 */\ngoog.labs.userAgent.browser.isSilk = function() {\n return goog.labs.userAgent.util.matchUserAgent('Silk');\n};\n\n\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 */\ngoog.labs.userAgent.browser.getVersion = function() {\n var userAgentString = goog.labs.userAgent.util.getUserAgent();\n // Special case IE since IE's version is inside the parenthesis and\n // without the '/'.\n if (goog.labs.userAgent.browser.isIE()) {\n return goog.labs.userAgent.browser.getIEVersion_(userAgentString);\n }\n\n var versionTuples =\n goog.labs.userAgent.util.extractVersionTuples(userAgentString);\n\n // Construct a map for easy lookup.\n var versionMap = {};\n goog.array.forEach(versionTuples, function(tuple) {\n // Note that the tuple is of length three, but we only care about the\n // first two.\n var key = tuple[0];\n var value = tuple[1];\n versionMap[key] = value;\n });\n\n var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap);\n\n // Gives the value with the first key it finds, otherwise empty string.\n function lookUpValueWithKeys(keys) {\n var key = goog.array.find(keys, versionMapHasKey);\n return versionMap[key] || '';\n }\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 (goog.labs.userAgent.browser.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 (goog.labs.userAgent.browser.isEdge()) {\n return lookUpValueWithKeys(['Edge']);\n }\n\n // Check Chromium Edge before Chrome since it has Chrome in the string.\n if (goog.labs.userAgent.browser.isEdgeChromium()) {\n return lookUpValueWithKeys(['Edg']);\n }\n\n if (goog.labs.userAgent.browser.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 var tuple = versionTuples[2];\n return tuple && tuple[1] || '';\n};\n\n\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 */\ngoog.labs.userAgent.browser.isVersionOrHigher = function(version) {\n return goog.string.internal.compareVersions(\n goog.labs.userAgent.browser.getVersion(), version) >= 0;\n};\n\n\n/**\n * Determines 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 *\n * @param {string} userAgent the User-Agent.\n * @return {string}\n * @private\n */\ngoog.labs.userAgent.browser.getIEVersion_ = function(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 var rv = /rv: *([\\d\\.]*)/.exec(userAgent);\n if (rv && rv[1]) {\n return rv[1];\n }\n\n var version = '';\n var 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 var 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","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\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 * @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.provide('goog.labs.userAgent.engine');\n\ngoog.require('goog.array');\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.string');\n\n\n/**\n * @return {boolean} Whether the rendering engine is Presto.\n */\ngoog.labs.userAgent.engine.isPresto = function() {\n return goog.labs.userAgent.util.matchUserAgent('Presto');\n};\n\n\n/**\n * @return {boolean} Whether the rendering engine is Trident.\n */\ngoog.labs.userAgent.engine.isTrident = function() {\n // IE only started including the Trident token in IE8.\n return goog.labs.userAgent.util.matchUserAgent('Trident') ||\n goog.labs.userAgent.util.matchUserAgent('MSIE');\n};\n\n\n/**\n * @return {boolean} Whether the rendering engine is EdgeHTML.\n */\ngoog.labs.userAgent.engine.isEdge = function() {\n return goog.labs.userAgent.util.matchUserAgent('Edge');\n};\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 */\ngoog.labs.userAgent.engine.isWebKit = function() {\n return goog.labs.userAgent.util.matchUserAgentIgnoreCase('WebKit') &&\n !goog.labs.userAgent.engine.isEdge();\n};\n\n\n/**\n * @return {boolean} Whether the rendering engine is Gecko.\n */\ngoog.labs.userAgent.engine.isGecko = function() {\n return goog.labs.userAgent.util.matchUserAgent('Gecko') &&\n !goog.labs.userAgent.engine.isWebKit() &&\n !goog.labs.userAgent.engine.isTrident() &&\n !goog.labs.userAgent.engine.isEdge();\n};\n\n\n/**\n * @return {string} The rendering engine's version or empty string if version\n * can't be determined.\n */\ngoog.labs.userAgent.engine.getVersion = function() {\n var userAgentString = goog.labs.userAgent.util.getUserAgent();\n if (userAgentString) {\n var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);\n\n var engineTuple = goog.labs.userAgent.engine.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 goog.labs.userAgent.engine.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 var browserTuple = tuples[0];\n var info;\n if (browserTuple && (info = browserTuple[2])) {\n var match = /Trident\\/([^\\s;]+)/.exec(info);\n if (match) {\n return match[1];\n }\n }\n }\n return '';\n};\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 * @private\n */\ngoog.labs.userAgent.engine.getEngineTuple_ = function(tuples) {\n if (!goog.labs.userAgent.engine.isEdge()) {\n return tuples[1];\n }\n for (var i = 0; i < tuples.length; i++) {\n var tuple = tuples[i];\n if (tuple[0] == 'Edge') {\n return tuple;\n }\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 */\ngoog.labs.userAgent.engine.isVersionOrHigher = function(version) {\n return goog.string.compareVersions(\n goog.labs.userAgent.engine.getVersion(), version) >= 0;\n};\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 * @private\n */\ngoog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) {\n // TODO(nnaze): Move to util if useful elsewhere.\n\n var pair = goog.array.find(tuples, function(pair) { return key == pair[0]; });\n\n return pair && pair[1] || '';\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 dom package.\n */\n\n\ngoog.provide('goog.dom.BrowserFeature');\n\ngoog.require('goog.userAgent');\n\n\n/**\n * @define {boolean} Whether we know at compile time that the browser doesn't\n * support OffscreenCanvas.\n */\ngoog.dom.BrowserFeature.ASSUME_NO_OFFSCREEN_CANVAS =\n goog.define('goog.dom.ASSUME_NO_OFFSCREEN_CANVAS', false);\n\n/**\n * @define {boolean} Whether we know at compile time that the browser supports\n * all OffscreenCanvas contexts.\n */\n// TODO(user): Eventually this should default to \"FEATURESET_YEAR >= 202X\".\ngoog.dom.BrowserFeature.ASSUME_OFFSCREEN_CANVAS =\n goog.define('goog.dom.ASSUME_OFFSCREEN_CANVAS', false);\n\n/**\n * Detects if a particular OffscreenCanvas context is supported.\n * @param {string} contextName name of the context to test.\n * @return {boolean} Whether the browser supports this OffscreenCanvas context.\n * @private\n */\ngoog.dom.BrowserFeature.detectOffscreenCanvas_ = function(contextName) {\n // This code only gets removed because we forced @nosideeffects on\n // the functions. See: b/138802376\n try {\n return Boolean(new self.OffscreenCanvas(0, 0).getContext(contextName));\n } catch (ex) {\n }\n return false;\n};\n\n/**\n * Whether the browser supports OffscreenCanvas 2D context.\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.OFFSCREEN_CANVAS_2D =\n !goog.dom.BrowserFeature.ASSUME_NO_OFFSCREEN_CANVAS &&\n (goog.dom.BrowserFeature.ASSUME_OFFSCREEN_CANVAS ||\n goog.dom.BrowserFeature.detectOffscreenCanvas_('2d'));\n\n/**\n * Whether attributes 'name' and 'type' can be added to an element after it's\n * created. False in Internet Explorer prior to version 9.\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES =\n !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9);\n\n/**\n * Whether we can use element.children to access an element's Element\n * children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment\n * nodes in the collection.)\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE =\n !goog.userAgent.GECKO && !goog.userAgent.IE ||\n goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9) ||\n goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.1');\n\n/**\n * Opera, Safari 3, and Internet Explorer 9 all support innerText but they\n * include text nodes in script and style tags. Not document-mode-dependent.\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.CAN_USE_INNER_TEXT =\n (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'));\n\n/**\n * MSIE, Opera, and Safari>=4 support element.parentElement to access an\n * element's parent if it is an Element.\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY =\n goog.userAgent.IE || goog.userAgent.OPERA || goog.userAgent.WEBKIT;\n\n/**\n * Whether NoScope elements need a scoped element written before them in\n * innerHTML.\n * MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT = goog.userAgent.IE;\n\n/**\n * Whether we use legacy IE range API.\n * @const {boolean}\n */\ngoog.dom.BrowserFeature.LEGACY_IE_RANGES =\n goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9);\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating the browser's Document Object Model\n * Inspiration taken *heavily* from mochikit (http://mochikit.com/).\n *\n * You can use {@link goog.dom.DomHelper} to create new dom helpers that refer\n * to a different document object. This is useful if you are working with\n * frames or multiple windows.\n *\n * @suppress {strictMissingProperties}\n */\n\n\n// TODO(arv): Rename/refactor getTextContent and getRawTextContent. The problem\n// is that getTextContent should mimic the DOM3 textContent. We should add a\n// getInnerText (or getText) which tries to return the visible text, innerText.\n\n\ngoog.provide('goog.dom');\ngoog.provide('goog.dom.Appendable');\ngoog.provide('goog.dom.DomHelper');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.dom.BrowserFeature');\ngoog.require('goog.dom.NodeType');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.math.Coordinate');\ngoog.require('goog.math.Size');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.string.Unicode');\ngoog.require('goog.userAgent');\n\n\n/**\n * @define {boolean} Whether we know at compile time that the browser is in\n * quirks mode.\n */\ngoog.dom.ASSUME_QUIRKS_MODE = goog.define('goog.dom.ASSUME_QUIRKS_MODE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile time that the browser is in\n * standards compliance mode.\n */\ngoog.dom.ASSUME_STANDARDS_MODE =\n goog.define('goog.dom.ASSUME_STANDARDS_MODE', false);\n\n\n/**\n * Whether we know the compatibility mode at compile time.\n * @type {boolean}\n * @private\n */\ngoog.dom.COMPAT_MODE_KNOWN_ =\n goog.dom.ASSUME_QUIRKS_MODE || goog.dom.ASSUME_STANDARDS_MODE;\n\n\n/**\n * Gets the DomHelper object for the document where the element resides.\n * @param {(Node|Window)=} opt_element If present, gets the DomHelper for this\n * element.\n * @return {!goog.dom.DomHelper} The DomHelper.\n */\ngoog.dom.getDomHelper = function(opt_element) {\n return opt_element ?\n new goog.dom.DomHelper(goog.dom.getOwnerDocument(opt_element)) :\n (goog.dom.defaultDomHelper_ ||\n (goog.dom.defaultDomHelper_ = new goog.dom.DomHelper()));\n};\n\n\n/**\n * Cached default DOM helper.\n * @type {!goog.dom.DomHelper|undefined}\n * @private\n */\ngoog.dom.defaultDomHelper_;\n\n\n/**\n * Gets the document object being used by the dom library.\n * @return {!Document} Document object.\n */\ngoog.dom.getDocument = function() {\n return document;\n};\n\n\n/**\n * Gets an element from the current document by element id.\n *\n * If an Element is passed in, it is returned.\n *\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n */\ngoog.dom.getElement = function(element) {\n return goog.dom.getElementHelper_(document, element);\n};\n\n\n/**\n * Gets an element by id from the given document (if present).\n * If an element is given, it is returned.\n * @param {!Document} doc\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The resulting element.\n * @private\n */\ngoog.dom.getElementHelper_ = function(doc, element) {\n return typeof element === 'string' ? doc.getElementById(element) : element;\n};\n\n\n/**\n * Gets an element by id, asserting that the element is found.\n *\n * This is used when an element is expected to exist, and should fail with\n * an assertion error if it does not (if assertions are enabled).\n *\n * @param {string} id Element ID.\n * @return {!Element} The element with the given ID, if it exists.\n */\ngoog.dom.getRequiredElement = function(id) {\n return goog.dom.getRequiredElementHelper_(document, id);\n};\n\n\n/**\n * Helper function for getRequiredElementHelper functions, both static and\n * on DomHelper. Asserts the element with the given id exists.\n * @param {!Document} doc\n * @param {string} id\n * @return {!Element} The element with the given ID, if it exists.\n * @private\n */\ngoog.dom.getRequiredElementHelper_ = function(doc, id) {\n // To prevent users passing in Elements as is permitted in getElement().\n goog.asserts.assertString(id);\n var element = goog.dom.getElementHelper_(doc, id);\n element =\n goog.asserts.assertElement(element, 'No element found with id: ' + id);\n return element;\n};\n\n\n/**\n * Alias for getElement.\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n * @deprecated Use {@link goog.dom.getElement} instead.\n */\ngoog.dom.$ = goog.dom.getElement;\n\n\n/**\n * Gets elements by tag name.\n * @param {!goog.dom.TagName<T>} tagName\n * @param {(!Document|!Element)=} opt_parent Parent element or document where to\n * look for elements. Defaults to document.\n * @return {!NodeList<R>} List of elements. The members of the list are\n * {!Element} if tagName is not a member of goog.dom.TagName or more\n * specific types if it is (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getElementsByTagName = function(tagName, opt_parent) {\n var parent = opt_parent || document;\n return parent.getElementsByTagName(String(tagName));\n};\n\n\n/**\n * Looks up elements by both tag and class name, using browser native functions\n * (`querySelectorAll`, `getElementsByTagName` or\n * `getElementsByClassName`) where possible. This function\n * is a useful, if limited, way of collecting a list of DOM elements\n * with certain characteristics. `querySelectorAll` offers a\n * more powerful and general solution which allows matching on CSS3\n * selector expressions.\n *\n * Note that tag names are case sensitive in the SVG namespace, and this\n * function converts opt_tag to uppercase for comparisons. For queries in the\n * SVG namespace you should use querySelector or querySelectorAll instead.\n * https://bugzilla.mozilla.org/show_bug.cgi?id=963870\n * https://bugs.webkit.org/show_bug.cgi?id=83438\n *\n * @see {https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll}\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n * and numerical indices are guaranteed to exist). The members of the array\n * are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n * specific types if it is (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {\n return goog.dom.getElementsByTagNameAndClass_(\n document, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Gets the first element matching the tag and the class.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {?R} Reference to a DOM node. The return type is {?Element} if\n * tagName is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getElementByTagNameAndClass = function(opt_tag, opt_class, opt_el) {\n return goog.dom.getElementByTagNameAndClass_(\n document, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Returns a static, array-like list of the elements with the provided\n * className.\n *\n * @param {string} className the name of the class to look for.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<!Element>} The items found with the class name provided.\n */\ngoog.dom.getElementsByClass = function(className, opt_el) {\n var parent = opt_el || document;\n if (goog.dom.canUseQuerySelector_(parent)) {\n return parent.querySelectorAll('.' + className);\n }\n return goog.dom.getElementsByTagNameAndClass_(\n document, '*', className, opt_el);\n};\n\n\n/**\n * Returns the first element with the provided className.\n *\n * @param {string} className the name of the class to look for.\n * @param {Element|Document=} opt_el Optional element to look in.\n * @return {Element} The first item with the class name provided.\n */\ngoog.dom.getElementByClass = function(className, opt_el) {\n var parent = opt_el || document;\n var retVal = null;\n if (parent.getElementsByClassName) {\n retVal = parent.getElementsByClassName(className)[0];\n } else {\n retVal =\n goog.dom.getElementByTagNameAndClass_(document, '*', className, opt_el);\n }\n return retVal || null;\n};\n\n\n/**\n * Ensures an element with the given className exists, and then returns the\n * first element with the provided className.\n *\n * @param {string} className the name of the class to look for.\n * @param {!Element|!Document=} opt_root Optional element or document to look\n * in.\n * @return {!Element} The first item with the class name provided.\n * @throws {goog.asserts.AssertionError} Thrown if no element is found.\n */\ngoog.dom.getRequiredElementByClass = function(className, opt_root) {\n var retValue = goog.dom.getElementByClass(className, opt_root);\n return goog.asserts.assert(\n retValue, 'No element found with className: ' + className);\n};\n\n\n/**\n * Prefer the standardized (http://www.w3.org/TR/selectors-api/), native and\n * fast W3C Selectors API.\n * @param {!(Element|Document)} parent The parent document object.\n * @return {boolean} whether or not we can use parent.querySelector* APIs.\n * @private\n */\ngoog.dom.canUseQuerySelector_ = function(parent) {\n return !!(parent.querySelectorAll && parent.querySelector);\n};\n\n\n/**\n * Helper for `getElementsByTagNameAndClass`.\n * @param {!Document} doc The document to get the elements in.\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n * and numerical indices are guaranteed to exist). The members of the array\n * are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n * specific types if it is (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @private\n */\ngoog.dom.getElementsByTagNameAndClass_ = function(\n doc, opt_tag, opt_class, opt_el) {\n var parent = opt_el || doc;\n var tagName =\n (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : '';\n\n if (goog.dom.canUseQuerySelector_(parent) && (tagName || opt_class)) {\n var query = tagName + (opt_class ? '.' + opt_class : '');\n return parent.querySelectorAll(query);\n }\n\n // Use the native getElementsByClassName if available, under the assumption\n // that even when the tag name is specified, there will be fewer elements to\n // filter through when going by class than by tag name\n if (opt_class && parent.getElementsByClassName) {\n var els = parent.getElementsByClassName(opt_class);\n\n if (tagName) {\n var arrayLike = {};\n var len = 0;\n\n // Filter for specific tags if requested.\n for (var i = 0, el; el = els[i]; i++) {\n if (tagName == el.nodeName) {\n arrayLike[len++] = el;\n }\n }\n arrayLike.length = len;\n\n return /** @type {!IArrayLike<!Element>} */ (arrayLike);\n } else {\n return els;\n }\n }\n\n var els = parent.getElementsByTagName(tagName || '*');\n\n if (opt_class) {\n var arrayLike = {};\n var len = 0;\n for (var i = 0, el; el = els[i]; i++) {\n var className = el.className;\n // Check if className has a split function since SVG className does not.\n if (typeof className.split == 'function' &&\n goog.array.contains(className.split(/\\s+/), opt_class)) {\n arrayLike[len++] = el;\n }\n }\n arrayLike.length = len;\n return /** @type {!IArrayLike<!Element>} */ (arrayLike);\n } else {\n return els;\n }\n};\n\n\n/**\n * Helper for goog.dom.getElementByTagNameAndClass.\n *\n * @param {!Document} doc The document to get the elements in.\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {?R} Reference to a DOM node. The return type is {?Element} if\n * tagName is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @private\n */\ngoog.dom.getElementByTagNameAndClass_ = function(\n doc, opt_tag, opt_class, opt_el) {\n var parent = opt_el || doc;\n var tag = (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : '';\n if (goog.dom.canUseQuerySelector_(parent) && (tag || opt_class)) {\n return parent.querySelector(tag + (opt_class ? '.' + opt_class : ''));\n }\n var elements =\n goog.dom.getElementsByTagNameAndClass_(doc, opt_tag, opt_class, opt_el);\n return elements[0] || null;\n};\n\n\n\n/**\n * Alias for `getElementsByTagNameAndClass`.\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {Element=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n * and numerical indices are guaranteed to exist). The members of the array\n * are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n * specific types if it is (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @deprecated Use {@link goog.dom.getElementsByTagNameAndClass} instead.\n */\ngoog.dom.$$ = goog.dom.getElementsByTagNameAndClass;\n\n\n/**\n * Sets multiple properties, and sometimes attributes, on an element. Note that\n * properties are simply object properties on the element instance, while\n * attributes are visible in the DOM. Many properties map to attributes with the\n * same names, some with different names, and there are also unmappable cases.\n *\n * This method sets properties by default (which means that custom attributes\n * are not supported). These are the exeptions (some of which is legacy):\n * - \"style\": Even though this is an attribute name, it is translated to a\n * property, \"style.cssText\". Note that this property sanitizes and formats\n * its value, unlike the attribute.\n * - \"class\": This is an attribute name, it is translated to the \"className\"\n * property.\n * - \"for\": This is an attribute name, it is translated to the \"htmlFor\"\n * property.\n * - Entries in {@see goog.dom.DIRECT_ATTRIBUTE_MAP_} are set as attributes,\n * this is probably due to browser quirks.\n * - \"aria-*\", \"data-*\": Always set as attributes, they have no property\n * counterparts.\n *\n * @param {Element} element DOM node to set properties on.\n * @param {Object} properties Hash of property:value pairs.\n * Property values can be strings or goog.string.TypedString values (such as\n * goog.html.SafeUrl).\n */\ngoog.dom.setProperties = function(element, properties) {\n goog.object.forEach(properties, function(val, key) {\n if (val && typeof val == 'object' && val.implementsGoogStringTypedString) {\n val = val.getTypedStringValue();\n }\n if (key == 'style') {\n element.style.cssText = val;\n } else if (key == 'class') {\n element.className = val;\n } else if (key == 'for') {\n element.htmlFor = val;\n } else if (goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty(key)) {\n element.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[key], val);\n } else if (\n goog.string.startsWith(key, 'aria-') ||\n goog.string.startsWith(key, 'data-')) {\n element.setAttribute(key, val);\n } else {\n element[key] = val;\n }\n });\n};\n\n\n/**\n * Map of attributes that should be set using\n * element.setAttribute(key, val) instead of element[key] = val. Used\n * by goog.dom.setProperties.\n *\n * @private {!Object<string, string>}\n * @const\n */\ngoog.dom.DIRECT_ATTRIBUTE_MAP_ = {\n 'cellpadding': 'cellPadding',\n 'cellspacing': 'cellSpacing',\n 'colspan': 'colSpan',\n 'frameborder': 'frameBorder',\n 'height': 'height',\n 'maxlength': 'maxLength',\n 'nonce': 'nonce',\n 'role': 'role',\n 'rowspan': 'rowSpan',\n 'type': 'type',\n 'usemap': 'useMap',\n 'valign': 'vAlign',\n 'width': 'width'\n};\n\n\n/**\n * Gets the dimensions of the viewport.\n *\n * Gecko Standards mode:\n * docEl.clientWidth Width of viewport excluding scrollbar.\n * win.innerWidth Width of viewport including scrollbar.\n * body.clientWidth Width of body element.\n *\n * docEl.clientHeight Height of viewport excluding scrollbar.\n * win.innerHeight Height of viewport including scrollbar.\n * body.clientHeight Height of document.\n *\n * Gecko Backwards compatible mode:\n * docEl.clientWidth Width of viewport excluding scrollbar.\n * win.innerWidth Width of viewport including scrollbar.\n * body.clientWidth Width of viewport excluding scrollbar.\n *\n * docEl.clientHeight Height of document.\n * win.innerHeight Height of viewport including scrollbar.\n * body.clientHeight Height of viewport excluding scrollbar.\n *\n * IE6/7 Standards mode:\n * docEl.clientWidth Width of viewport excluding scrollbar.\n * win.innerWidth Undefined.\n * body.clientWidth Width of body element.\n *\n * docEl.clientHeight Height of viewport excluding scrollbar.\n * win.innerHeight Undefined.\n * body.clientHeight Height of document element.\n *\n * IE5 + IE6/7 Backwards compatible mode:\n * docEl.clientWidth 0.\n * win.innerWidth Undefined.\n * body.clientWidth Width of viewport excluding scrollbar.\n *\n * docEl.clientHeight 0.\n * win.innerHeight Undefined.\n * body.clientHeight Height of viewport excluding scrollbar.\n *\n * Opera 9 Standards and backwards compatible mode:\n * docEl.clientWidth Width of viewport excluding scrollbar.\n * win.innerWidth Width of viewport including scrollbar.\n * body.clientWidth Width of viewport excluding scrollbar.\n *\n * docEl.clientHeight Height of document.\n * win.innerHeight Height of viewport including scrollbar.\n * body.clientHeight Height of viewport excluding scrollbar.\n *\n * WebKit:\n * Safari 2\n * docEl.clientHeight Same as scrollHeight.\n * docEl.clientWidth Same as innerWidth.\n * win.innerWidth Width of viewport excluding scrollbar.\n * win.innerHeight Height of the viewport including scrollbar.\n * frame.innerHeight Height of the viewport exluding scrollbar.\n *\n * Safari 3 (tested in 522)\n *\n * docEl.clientWidth Width of viewport excluding scrollbar.\n * docEl.clientHeight Height of viewport excluding scrollbar in strict mode.\n * body.clientHeight Height of viewport excluding scrollbar in quirks mode.\n *\n * @param {Window=} opt_window Optional window element to test.\n * @return {!goog.math.Size} Object with values 'width' and 'height'.\n */\ngoog.dom.getViewportSize = function(opt_window) {\n // TODO(arv): This should not take an argument\n return goog.dom.getViewportSize_(opt_window || window);\n};\n\n\n/**\n * Helper for `getViewportSize`.\n * @param {Window} win The window to get the view port size for.\n * @return {!goog.math.Size} Object with values 'width' and 'height'.\n * @private\n */\ngoog.dom.getViewportSize_ = function(win) {\n var doc = win.document;\n var el = goog.dom.isCss1CompatMode_(doc) ? doc.documentElement : doc.body;\n return new goog.math.Size(el.clientWidth, el.clientHeight);\n};\n\n\n/**\n * Calculates the height of the document.\n *\n * @return {number} The height of the current document.\n */\ngoog.dom.getDocumentHeight = function() {\n return goog.dom.getDocumentHeight_(window);\n};\n\n/**\n * Calculates the height of the document of the given window.\n *\n * @param {!Window} win The window whose document height to retrieve.\n * @return {number} The height of the document of the given window.\n */\ngoog.dom.getDocumentHeightForWindow = function(win) {\n return goog.dom.getDocumentHeight_(win);\n};\n\n/**\n * Calculates the height of the document of the given window.\n *\n * Function code copied from the opensocial gadget api:\n * gadgets.window.adjustHeight(opt_height)\n *\n * @private\n * @param {!Window} win The window whose document height to retrieve.\n * @return {number} The height of the document of the given window.\n */\ngoog.dom.getDocumentHeight_ = function(win) {\n // NOTE(eae): This method will return the window size rather than the document\n // size in webkit quirks mode.\n var doc = win.document;\n var height = 0;\n\n if (doc) {\n // Calculating inner content height is hard and different between\n // browsers rendering in Strict vs. Quirks mode. We use a combination of\n // three properties within document.body and document.documentElement:\n // - scrollHeight\n // - offsetHeight\n // - clientHeight\n // These values differ significantly between browsers and rendering modes.\n // But there are patterns. It just takes a lot of time and persistence\n // to figure out.\n\n var body = doc.body;\n var docEl = /** @type {!HTMLElement} */ (doc.documentElement);\n if (!(docEl && body)) {\n return 0;\n }\n\n // Get the height of the viewport\n var vh = goog.dom.getViewportSize_(win).height;\n if (goog.dom.isCss1CompatMode_(doc) && docEl.scrollHeight) {\n // In Strict mode:\n // The inner content height is contained in either:\n // document.documentElement.scrollHeight\n // document.documentElement.offsetHeight\n // Based on studying the values output by different browsers,\n // use the value that's NOT equal to the viewport height found above.\n height =\n docEl.scrollHeight != vh ? docEl.scrollHeight : docEl.offsetHeight;\n } else {\n // In Quirks mode:\n // documentElement.clientHeight is equal to documentElement.offsetHeight\n // except in IE. In most browsers, document.documentElement can be used\n // to calculate the inner content height.\n // However, in other browsers (e.g. IE), document.body must be used\n // instead. How do we know which one to use?\n // If document.documentElement.clientHeight does NOT equal\n // document.documentElement.offsetHeight, then use document.body.\n var sh = docEl.scrollHeight;\n var oh = docEl.offsetHeight;\n if (docEl.clientHeight != oh) {\n sh = body.scrollHeight;\n oh = body.offsetHeight;\n }\n\n // Detect whether the inner content height is bigger or smaller\n // than the bounding box (viewport). If bigger, take the larger\n // value. If smaller, take the smaller value.\n if (sh > vh) {\n // Content is larger\n height = sh > oh ? sh : oh;\n } else {\n // Content is smaller\n height = sh < oh ? sh : oh;\n }\n }\n }\n\n return height;\n};\n\n\n/**\n * Gets the page scroll distance as a coordinate object.\n *\n * @param {Window=} opt_window Optional window element to test.\n * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.\n * @deprecated Use {@link goog.dom.getDocumentScroll} instead.\n */\ngoog.dom.getPageScroll = function(opt_window) {\n var win = opt_window || goog.global || window;\n return goog.dom.getDomHelper(win.document).getDocumentScroll();\n};\n\n\n/**\n * Gets the document scroll distance as a coordinate object.\n *\n * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.\n */\ngoog.dom.getDocumentScroll = function() {\n return goog.dom.getDocumentScroll_(document);\n};\n\n\n/**\n * Helper for `getDocumentScroll`.\n *\n * @param {!Document} doc The document to get the scroll for.\n * @return {!goog.math.Coordinate} Object with values 'x' and 'y'.\n * @private\n */\ngoog.dom.getDocumentScroll_ = function(doc) {\n var el = goog.dom.getDocumentScrollElement_(doc);\n var win = goog.dom.getWindow_(doc);\n if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher('10') &&\n win.pageYOffset != el.scrollTop) {\n // The keyboard on IE10 touch devices shifts the page using the pageYOffset\n // without modifying scrollTop. For this case, we want the body scroll\n // offsets.\n return new goog.math.Coordinate(el.scrollLeft, el.scrollTop);\n }\n return new goog.math.Coordinate(\n win.pageXOffset || el.scrollLeft, win.pageYOffset || el.scrollTop);\n};\n\n\n/**\n * Gets the document scroll element.\n * @return {!Element} Scrolling element.\n */\ngoog.dom.getDocumentScrollElement = function() {\n return goog.dom.getDocumentScrollElement_(document);\n};\n\n\n/**\n * Helper for `getDocumentScrollElement`.\n * @param {!Document} doc The document to get the scroll element for.\n * @return {!Element} Scrolling element.\n * @private\n */\ngoog.dom.getDocumentScrollElement_ = function(doc) {\n // Old WebKit needs body.scrollLeft in both quirks mode and strict mode. We\n // also default to the documentElement if the document does not have a body\n // (e.g. a SVG document).\n // Uses http://dev.w3.org/csswg/cssom-view/#dom-document-scrollingelement to\n // avoid trying to guess about browser behavior from the UA string.\n if (doc.scrollingElement) {\n return doc.scrollingElement;\n }\n if (!goog.userAgent.WEBKIT && goog.dom.isCss1CompatMode_(doc)) {\n return doc.documentElement;\n }\n return doc.body || doc.documentElement;\n};\n\n\n/**\n * Gets the window object associated with the given document.\n *\n * @param {Document=} opt_doc Document object to get window for.\n * @return {!Window} The window associated with the given document.\n */\ngoog.dom.getWindow = function(opt_doc) {\n // TODO(arv): This should not take an argument.\n return opt_doc ? goog.dom.getWindow_(opt_doc) : window;\n};\n\n\n/**\n * Helper for `getWindow`.\n *\n * @param {!Document} doc Document object to get window for.\n * @return {!Window} The window associated with the given document.\n * @private\n */\ngoog.dom.getWindow_ = function(doc) {\n return /** @type {!Window} */ (doc.parentWindow || doc.defaultView);\n};\n\n\n/**\n * Returns a dom node with a set of attributes. This function accepts varargs\n * for subsequent nodes to be added. Subsequent nodes will be added to the\n * first node as childNodes.\n *\n * So:\n * <code>createDom(goog.dom.TagName.DIV, null, createDom(goog.dom.TagName.P),\n * createDom(goog.dom.TagName.P));</code> would return a div with two child\n * paragraphs\n *\n * This function uses {@link goog.dom.setProperties} to set attributes: the\n * `opt_attributes` parameter follows the same rules.\n *\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n * of name-value pairs for attributes. If a string, then this is the\n * className of the new element. If an array, the elements will be joined\n * together as the className of the new element.\n * @param {...(Object|string|Array|NodeList|null|undefined)} var_args Further\n * DOM nodes or strings for text nodes. If one of the var_args is an array\n * or NodeList, its elements will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n * is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.createDom = function(tagName, opt_attributes, var_args) {\n return goog.dom.createDom_(document, arguments);\n};\n\n\n/**\n * Helper for `createDom`.\n * @param {!Document} doc The document to create the DOM in.\n * @param {!Arguments} args Argument object passed from the callers. See\n * `goog.dom.createDom` for details.\n * @return {!Element} Reference to a DOM node.\n * @private\n */\ngoog.dom.createDom_ = function(doc, args) {\n var tagName = String(args[0]);\n var attributes = args[1];\n\n // Internet Explorer is dumb:\n // name: https://msdn.microsoft.com/en-us/library/ms534184(v=vs.85).aspx\n // type: https://msdn.microsoft.com/en-us/library/ms534700(v=vs.85).aspx\n // Also does not allow setting of 'type' attribute on 'input' or 'button'.\n if (!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES && attributes &&\n (attributes.name || attributes.type)) {\n var tagNameArr = ['<', tagName];\n if (attributes.name) {\n tagNameArr.push(' name=\"', goog.string.htmlEscape(attributes.name), '\"');\n }\n if (attributes.type) {\n tagNameArr.push(' type=\"', goog.string.htmlEscape(attributes.type), '\"');\n\n // Clone attributes map to remove 'type' without mutating the input.\n var clone = {};\n goog.object.extend(clone, attributes);\n\n // JSCompiler can't see how goog.object.extend added this property,\n // because it was essentially added by reflection.\n // So it needs to be quoted.\n delete clone['type'];\n\n attributes = clone;\n }\n tagNameArr.push('>');\n tagName = tagNameArr.join('');\n }\n\n var element = goog.dom.createElement_(doc, tagName);\n\n if (attributes) {\n if (typeof attributes === 'string') {\n element.className = attributes;\n } else if (Array.isArray(attributes)) {\n element.className = attributes.join(' ');\n } else {\n goog.dom.setProperties(element, attributes);\n }\n }\n\n if (args.length > 2) {\n goog.dom.append_(doc, element, args, 2);\n }\n\n return element;\n};\n\n\n/**\n * Appends a node with text or other nodes.\n * @param {!Document} doc The document to create new nodes in.\n * @param {!Node} parent The node to append nodes to.\n * @param {!Arguments} args The values to add. See `goog.dom.append`.\n * @param {number} startIndex The index of the array to start from.\n * @private\n */\ngoog.dom.append_ = function(doc, parent, args, startIndex) {\n function childHandler(child) {\n // TODO(user): More coercion, ala MochiKit?\n if (child) {\n parent.appendChild(\n typeof child === 'string' ? doc.createTextNode(child) : child);\n }\n }\n\n for (var i = startIndex; i < args.length; i++) {\n var arg = args[i];\n // TODO(attila): Fix isArrayLike to return false for a text node.\n if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) {\n // If the argument is a node list, not a real array, use a clone,\n // because forEach can't be used to mutate a NodeList.\n goog.array.forEach(\n goog.dom.isNodeList(arg) ? goog.array.toArray(arg) : arg,\n childHandler);\n } else {\n childHandler(arg);\n }\n }\n};\n\n\n/**\n * Alias for `createDom`.\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n * of name-value pairs for attributes. If a string, then this is the\n * className of the new element. If an array, the elements will be joined\n * together as the className of the new element.\n * @param {...(Object|string|Array|NodeList|null|undefined)} var_args Further\n * DOM nodes or strings for text nodes. If one of the var_args is an array,\n * its children will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n * is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @deprecated Use {@link goog.dom.createDom} instead.\n */\ngoog.dom.$dom = goog.dom.createDom;\n\n\n/**\n * Creates a new element.\n * @param {string|!goog.dom.TagName<T>} name Tag to create.\n * @return {R} The new element. The return type is {!Element} if name is\n * a string or a more specific type if it is a member of goog.dom.TagName\n * (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.createElement = function(name) {\n return goog.dom.createElement_(document, name);\n};\n\n\n/**\n * Creates a new element.\n * @param {!Document} doc The document to create the element in.\n * @param {string|!goog.dom.TagName<T>} name Tag to create.\n * @return {R} The new element. The return type is {!Element} if name is\n * a string or a more specific type if it is a member of goog.dom.TagName\n * (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @private\n */\ngoog.dom.createElement_ = function(doc, name) {\n name = String(name);\n if (doc.contentType === 'application/xhtml+xml') name = name.toLowerCase();\n return doc.createElement(name);\n};\n\n\n/**\n * Creates a new text node.\n * @param {number|string} content Content.\n * @return {!Text} The new text node.\n */\ngoog.dom.createTextNode = function(content) {\n return document.createTextNode(String(content));\n};\n\n\n/**\n * Create a table.\n * @param {number} rows The number of rows in the table. Must be >= 1.\n * @param {number} columns The number of columns in the table. Must be >= 1.\n * @param {boolean=} opt_fillWithNbsp If true, fills table entries with\n * `goog.string.Unicode.NBSP` characters.\n * @return {!Element} The created table.\n */\ngoog.dom.createTable = function(rows, columns, opt_fillWithNbsp) {\n // TODO(mlourenco): Return HTMLTableElement, also in prototype function.\n // Callers need to be updated to e.g. not assign numbers to table.cellSpacing.\n return goog.dom.createTable_(document, rows, columns, !!opt_fillWithNbsp);\n};\n\n\n/**\n * Create a table.\n * @param {!Document} doc Document object to use to create the table.\n * @param {number} rows The number of rows in the table. Must be >= 1.\n * @param {number} columns The number of columns in the table. Must be >= 1.\n * @param {boolean} fillWithNbsp If true, fills table entries with\n * `goog.string.Unicode.NBSP` characters.\n * @return {!HTMLTableElement} The created table.\n * @private\n */\ngoog.dom.createTable_ = function(doc, rows, columns, fillWithNbsp) {\n var table = goog.dom.createElement_(doc, goog.dom.TagName.TABLE);\n var tbody =\n table.appendChild(goog.dom.createElement_(doc, goog.dom.TagName.TBODY));\n for (var i = 0; i < rows; i++) {\n var tr = goog.dom.createElement_(doc, goog.dom.TagName.TR);\n for (var j = 0; j < columns; j++) {\n var td = goog.dom.createElement_(doc, goog.dom.TagName.TD);\n // IE <= 9 will create a text node if we set text content to the empty\n // string, so we avoid doing it unless necessary. This ensures that the\n // same DOM tree is returned on all browsers.\n if (fillWithNbsp) {\n goog.dom.setTextContent(td, goog.string.Unicode.NBSP);\n }\n tr.appendChild(td);\n }\n tbody.appendChild(tr);\n }\n return table;\n};\n\n\n\n/**\n * Creates a new Node from constant strings of HTML markup.\n * @param {...!goog.string.Const} var_args The HTML strings to concatenate then\n * convert into a node.\n * @return {!Node}\n */\ngoog.dom.constHtmlToNode = function(var_args) {\n var stringArray = goog.array.map(arguments, goog.string.Const.unwrap);\n var safeHtml =\n goog.html.uncheckedconversions\n .safeHtmlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from(\n 'Constant HTML string, that gets turned into a ' +\n 'Node later, so it will be automatically balanced.'),\n stringArray.join(''));\n return goog.dom.safeHtmlToNode(safeHtml);\n};\n\n\n/**\n * Converts HTML markup into a node. This is a safe version of\n * `goog.dom.htmlToDocumentFragment` which is now deleted.\n * @param {!goog.html.SafeHtml} html The HTML markup to convert.\n * @return {!Node} The resulting node.\n */\ngoog.dom.safeHtmlToNode = function(html) {\n return goog.dom.safeHtmlToNode_(document, html);\n};\n\n\n/**\n * Helper for `safeHtmlToNode`.\n * @param {!Document} doc The document.\n * @param {!goog.html.SafeHtml} html The HTML markup to convert.\n * @return {!Node} The resulting node.\n * @private\n */\ngoog.dom.safeHtmlToNode_ = function(doc, html) {\n var tempDiv = goog.dom.createElement_(doc, goog.dom.TagName.DIV);\n if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) {\n goog.dom.safe.setInnerHtml(\n tempDiv, goog.html.SafeHtml.concat(goog.html.SafeHtml.BR, html));\n tempDiv.removeChild(goog.asserts.assert(tempDiv.firstChild));\n } else {\n goog.dom.safe.setInnerHtml(tempDiv, html);\n }\n return goog.dom.childrenToNode_(doc, tempDiv);\n};\n\n\n/**\n * Helper for `safeHtmlToNode_`.\n * @param {!Document} doc The document.\n * @param {!Node} tempDiv The input node.\n * @return {!Node} The resulting node.\n * @private\n */\ngoog.dom.childrenToNode_ = function(doc, tempDiv) {\n if (tempDiv.childNodes.length == 1) {\n return tempDiv.removeChild(goog.asserts.assert(tempDiv.firstChild));\n } else {\n var fragment = doc.createDocumentFragment();\n while (tempDiv.firstChild) {\n fragment.appendChild(tempDiv.firstChild);\n }\n return fragment;\n }\n};\n\n\n/**\n * Returns true if the browser is in \"CSS1-compatible\" (standards-compliant)\n * mode, false otherwise.\n * @return {boolean} True if in CSS1-compatible mode.\n */\ngoog.dom.isCss1CompatMode = function() {\n return goog.dom.isCss1CompatMode_(document);\n};\n\n\n/**\n * Returns true if the browser is in \"CSS1-compatible\" (standards-compliant)\n * mode, false otherwise.\n * @param {!Document} doc The document to check.\n * @return {boolean} True if in CSS1-compatible mode.\n * @private\n */\ngoog.dom.isCss1CompatMode_ = function(doc) {\n if (goog.dom.COMPAT_MODE_KNOWN_) {\n return goog.dom.ASSUME_STANDARDS_MODE;\n }\n\n return doc.compatMode == 'CSS1Compat';\n};\n\n\n/**\n * Determines if the given node can contain children, intended to be used for\n * HTML generation.\n *\n * IE natively supports node.canHaveChildren but has inconsistent behavior.\n * Prior to IE8 the base tag allows children and in IE9 all nodes return true\n * for canHaveChildren.\n *\n * In practice all non-IE browsers allow you to add children to any node, but\n * the behavior is inconsistent:\n *\n * <pre>\n * var a = goog.dom.createElement(goog.dom.TagName.BR);\n * a.appendChild(document.createTextNode('foo'));\n * a.appendChild(document.createTextNode('bar'));\n * console.log(a.childNodes.length); // 2\n * console.log(a.innerHTML); // Chrome: \"\", IE9: \"foobar\", FF3.5: \"foobar\"\n * </pre>\n *\n * For more information, see:\n * http://dev.w3.org/html5/markup/syntax.html#syntax-elements\n *\n * TODO(user): Rename shouldAllowChildren() ?\n *\n * @param {Node} node The node to check.\n * @return {boolean} Whether the node can contain children.\n */\ngoog.dom.canHaveChildren = function(node) {\n if (node.nodeType != goog.dom.NodeType.ELEMENT) {\n return false;\n }\n switch (/** @type {!Element} */ (node).tagName) {\n case String(goog.dom.TagName.APPLET):\n case String(goog.dom.TagName.AREA):\n case String(goog.dom.TagName.BASE):\n case String(goog.dom.TagName.BR):\n case String(goog.dom.TagName.COL):\n case String(goog.dom.TagName.COMMAND):\n case String(goog.dom.TagName.EMBED):\n case String(goog.dom.TagName.FRAME):\n case String(goog.dom.TagName.HR):\n case String(goog.dom.TagName.IMG):\n case String(goog.dom.TagName.INPUT):\n case String(goog.dom.TagName.IFRAME):\n case String(goog.dom.TagName.ISINDEX):\n case String(goog.dom.TagName.KEYGEN):\n case String(goog.dom.TagName.LINK):\n case String(goog.dom.TagName.NOFRAMES):\n case String(goog.dom.TagName.NOSCRIPT):\n case String(goog.dom.TagName.META):\n case String(goog.dom.TagName.OBJECT):\n case String(goog.dom.TagName.PARAM):\n case String(goog.dom.TagName.SCRIPT):\n case String(goog.dom.TagName.SOURCE):\n case String(goog.dom.TagName.STYLE):\n case String(goog.dom.TagName.TRACK):\n case String(goog.dom.TagName.WBR):\n return false;\n }\n return true;\n};\n\n\n/**\n * Appends a child to a node.\n * @param {Node} parent Parent.\n * @param {Node} child Child.\n */\ngoog.dom.appendChild = function(parent, child) {\n goog.asserts.assert(\n parent != null && child != null,\n 'goog.dom.appendChild expects non-null arguments');\n parent.appendChild(child);\n};\n\n\n/**\n * Appends a node with text or other nodes.\n * @param {!Node} parent The node to append nodes to.\n * @param {...goog.dom.Appendable} var_args The things to append to the node.\n * If this is a Node it is appended as is.\n * If this is a string then a text node is appended.\n * If this is an array like object then fields 0 to length - 1 are appended.\n */\ngoog.dom.append = function(parent, var_args) {\n goog.dom.append_(goog.dom.getOwnerDocument(parent), parent, arguments, 1);\n};\n\n\n/**\n * Removes all the child nodes on a DOM node.\n * @param {Node} node Node to remove children from.\n */\ngoog.dom.removeChildren = function(node) {\n // Note: Iterations over live collections can be slow, this is the fastest\n // we could find. The double parenthesis are used to prevent JsCompiler and\n // strict warnings.\n var child;\n while ((child = node.firstChild)) {\n node.removeChild(child);\n }\n};\n\n\n/**\n * Inserts a new node before an existing reference node (i.e. as the previous\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert before.\n */\ngoog.dom.insertSiblingBefore = function(newNode, refNode) {\n goog.asserts.assert(\n newNode != null && refNode != null,\n 'goog.dom.insertSiblingBefore expects non-null arguments');\n if (refNode.parentNode) {\n refNode.parentNode.insertBefore(newNode, refNode);\n }\n};\n\n\n/**\n * Inserts a new node after an existing reference node (i.e. as the next\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert after.\n */\ngoog.dom.insertSiblingAfter = function(newNode, refNode) {\n goog.asserts.assert(\n newNode != null && refNode != null,\n 'goog.dom.insertSiblingAfter expects non-null arguments');\n if (refNode.parentNode) {\n refNode.parentNode.insertBefore(newNode, refNode.nextSibling);\n }\n};\n\n\n/**\n * Insert a child at a given index. If index is larger than the number of child\n * nodes that the parent currently has, the node is inserted as the last child\n * node.\n * @param {Element} parent The element into which to insert the child.\n * @param {Node} child The element to insert.\n * @param {number} index The index at which to insert the new child node. Must\n * not be negative.\n */\ngoog.dom.insertChildAt = function(parent, child, index) {\n // Note that if the second argument is null, insertBefore\n // will append the child at the end of the list of children.\n goog.asserts.assert(\n parent != null, 'goog.dom.insertChildAt expects a non-null parent');\n parent.insertBefore(\n /** @type {!Node} */ (child), parent.childNodes[index] || null);\n};\n\n\n/**\n * Removes a node from its parent.\n * @param {Node} node The node to remove.\n * @return {Node} The node removed if removed; else, null.\n */\ngoog.dom.removeNode = function(node) {\n return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n};\n\n\n/**\n * Replaces a node in the DOM tree. Will do nothing if `oldNode` has no\n * parent.\n * @param {Node} newNode Node to insert.\n * @param {Node} oldNode Node to replace.\n */\ngoog.dom.replaceNode = function(newNode, oldNode) {\n goog.asserts.assert(\n newNode != null && oldNode != null,\n 'goog.dom.replaceNode expects non-null arguments');\n var parent = oldNode.parentNode;\n if (parent) {\n parent.replaceChild(newNode, oldNode);\n }\n};\n\n\n/**\n * Flattens an element. That is, removes it and replace it with its children.\n * Does nothing if the element is not in the document.\n * @param {Element} element The element to flatten.\n * @return {Element|undefined} The original element, detached from the document\n * tree, sans children; or undefined, if the element was not in the document\n * to begin with.\n */\ngoog.dom.flattenElement = function(element) {\n var child, parent = element.parentNode;\n if (parent && parent.nodeType != goog.dom.NodeType.DOCUMENT_FRAGMENT) {\n // Use IE DOM method (supported by Opera too) if available\n if (element.removeNode) {\n return /** @type {Element} */ (element.removeNode(false));\n } else {\n // Move all children of the original node up one level.\n while ((child = element.firstChild)) {\n parent.insertBefore(child, element);\n }\n\n // Detach the original element.\n return /** @type {Element} */ (goog.dom.removeNode(element));\n }\n }\n};\n\n\n/**\n * Returns an array containing just the element children of the given element.\n * @param {Element} element The element whose element children we want.\n * @return {!(Array<!Element>|NodeList<!Element>)} An array or array-like list\n * of just the element children of the given element.\n */\ngoog.dom.getChildren = function(element) {\n // We check if the children attribute is supported for child elements\n // since IE8 misuses the attribute by also including comments.\n if (goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE &&\n element.children != undefined) {\n return element.children;\n }\n // Fall back to manually filtering the element's child nodes.\n return goog.array.filter(element.childNodes, function(node) {\n return node.nodeType == goog.dom.NodeType.ELEMENT;\n });\n};\n\n\n/**\n * Returns the first child node that is an element.\n * @param {Node} node The node to get the first child element of.\n * @return {Element} The first child node of `node` that is an element.\n */\ngoog.dom.getFirstElementChild = function(node) {\n if (node.firstElementChild !== undefined) {\n return /** @type {!Element} */ (node).firstElementChild;\n }\n return goog.dom.getNextElementNode_(node.firstChild, true);\n};\n\n\n/**\n * Returns the last child node that is an element.\n * @param {Node} node The node to get the last child element of.\n * @return {Element} The last child node of `node` that is an element.\n */\ngoog.dom.getLastElementChild = function(node) {\n if (node.lastElementChild !== undefined) {\n return /** @type {!Element} */ (node).lastElementChild;\n }\n return goog.dom.getNextElementNode_(node.lastChild, false);\n};\n\n\n/**\n * Returns the first next sibling that is an element.\n * @param {Node} node The node to get the next sibling element of.\n * @return {Element} The next sibling of `node` that is an element.\n */\ngoog.dom.getNextElementSibling = function(node) {\n if (node.nextElementSibling !== undefined) {\n return /** @type {!Element} */ (node).nextElementSibling;\n }\n return goog.dom.getNextElementNode_(node.nextSibling, true);\n};\n\n\n/**\n * Returns the first previous sibling that is an element.\n * @param {Node} node The node to get the previous sibling element of.\n * @return {Element} The first previous sibling of `node` that is\n * an element.\n */\ngoog.dom.getPreviousElementSibling = function(node) {\n if (node.previousElementSibling !== undefined) {\n return /** @type {!Element} */ (node).previousElementSibling;\n }\n return goog.dom.getNextElementNode_(node.previousSibling, false);\n};\n\n\n/**\n * Returns the first node that is an element in the specified direction,\n * starting with `node`.\n * @param {Node} node The node to get the next element from.\n * @param {boolean} forward Whether to look forwards or backwards.\n * @return {Element} The first element.\n * @private\n */\ngoog.dom.getNextElementNode_ = function(node, forward) {\n while (node && node.nodeType != goog.dom.NodeType.ELEMENT) {\n node = forward ? node.nextSibling : node.previousSibling;\n }\n\n return /** @type {Element} */ (node);\n};\n\n\n/**\n * Returns the next node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The next node in the DOM tree, or null if this was the last\n * node.\n */\ngoog.dom.getNextNode = function(node) {\n if (!node) {\n return null;\n }\n\n if (node.firstChild) {\n return node.firstChild;\n }\n\n while (node && !node.nextSibling) {\n node = node.parentNode;\n }\n\n return node ? node.nextSibling : null;\n};\n\n\n/**\n * Returns the previous node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The previous node in the DOM tree, or null if this was the\n * first node.\n */\ngoog.dom.getPreviousNode = function(node) {\n if (!node) {\n return null;\n }\n\n if (!node.previousSibling) {\n return node.parentNode;\n }\n\n node = node.previousSibling;\n while (node && node.lastChild) {\n node = node.lastChild;\n }\n\n return node;\n};\n\n\n/**\n * Whether the object looks like a DOM node.\n * @param {?} obj The object being tested for node likeness.\n * @return {boolean} Whether the object looks like a DOM node.\n */\ngoog.dom.isNodeLike = function(obj) {\n return goog.isObject(obj) && obj.nodeType > 0;\n};\n\n\n/**\n * Whether the object looks like an Element.\n * @param {?} obj The object being tested for Element likeness.\n * @return {boolean} Whether the object looks like an Element.\n */\ngoog.dom.isElement = function(obj) {\n return goog.isObject(obj) && obj.nodeType == goog.dom.NodeType.ELEMENT;\n};\n\n\n/**\n * Returns true if the specified value is a Window object. This includes the\n * global window for HTML pages, and iframe windows.\n * @param {?} obj Variable to test.\n * @return {boolean} Whether the variable is a window.\n */\ngoog.dom.isWindow = function(obj) {\n return goog.isObject(obj) && obj['window'] == obj;\n};\n\n\n/**\n * Returns an element's parent, if it's an Element.\n * @param {Element} element The DOM element.\n * @return {Element} The parent, or null if not an Element.\n */\ngoog.dom.getParentElement = function(element) {\n var parent;\n if (goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY) {\n var isIe9 = goog.userAgent.IE && goog.userAgent.isVersionOrHigher('9') &&\n !goog.userAgent.isVersionOrHigher('10');\n // SVG elements in IE9 can't use the parentElement property.\n // goog.global['SVGElement'] is not defined in IE9 quirks mode.\n if (!(isIe9 && goog.global['SVGElement'] &&\n element instanceof goog.global['SVGElement'])) {\n parent = element.parentElement;\n if (parent) {\n return parent;\n }\n }\n }\n parent = element.parentNode;\n return goog.dom.isElement(parent) ? /** @type {!Element} */ (parent) : null;\n};\n\n\n/**\n * Whether a node contains another node.\n * @param {?Node|undefined} parent The node that should contain the other node.\n * @param {?Node|undefined} descendant The node to test presence of.\n * @return {boolean} Whether the parent node contains the descendant node.\n */\ngoog.dom.contains = function(parent, descendant) {\n if (!parent || !descendant) {\n return false;\n }\n // We use browser specific methods for this if available since it is faster\n // that way.\n\n // IE DOM\n if (parent.contains && descendant.nodeType == goog.dom.NodeType.ELEMENT) {\n return parent == descendant || parent.contains(descendant);\n }\n\n // W3C DOM Level 3\n if (typeof parent.compareDocumentPosition != 'undefined') {\n return parent == descendant ||\n Boolean(parent.compareDocumentPosition(descendant) & 16);\n }\n\n // W3C DOM Level 1\n while (descendant && parent != descendant) {\n descendant = descendant.parentNode;\n }\n return descendant == parent;\n};\n\n\n/**\n * Compares the document order of two nodes, returning 0 if they are the same\n * node, a negative number if node1 is before node2, and a positive number if\n * node2 is before node1. Note that we compare the order the tags appear in the\n * document so in the tree <b><i>text</i></b> the B node is considered to be\n * before the I node.\n *\n * @param {Node} node1 The first node to compare.\n * @param {Node} node2 The second node to compare.\n * @return {number} 0 if the nodes are the same node, a negative number if node1\n * is before node2, and a positive number if node2 is before node1.\n */\ngoog.dom.compareNodeOrder = function(node1, node2) {\n // Fall out quickly for equality.\n if (node1 == node2) {\n return 0;\n }\n\n // Use compareDocumentPosition where available\n if (node1.compareDocumentPosition) {\n // 4 is the bitmask for FOLLOWS.\n return node1.compareDocumentPosition(node2) & 2 ? 1 : -1;\n }\n\n // Special case for document nodes on IE 7 and 8.\n if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {\n if (node1.nodeType == goog.dom.NodeType.DOCUMENT) {\n return -1;\n }\n if (node2.nodeType == goog.dom.NodeType.DOCUMENT) {\n return 1;\n }\n }\n\n // Process in IE using sourceIndex - we check to see if the first node has\n // a source index or if its parent has one.\n if ('sourceIndex' in node1 ||\n (node1.parentNode && 'sourceIndex' in node1.parentNode)) {\n var isElement1 = node1.nodeType == goog.dom.NodeType.ELEMENT;\n var isElement2 = node2.nodeType == goog.dom.NodeType.ELEMENT;\n\n if (isElement1 && isElement2) {\n return node1.sourceIndex - node2.sourceIndex;\n } else {\n var parent1 = node1.parentNode;\n var parent2 = node2.parentNode;\n\n if (parent1 == parent2) {\n return goog.dom.compareSiblingOrder_(node1, node2);\n }\n\n if (!isElement1 && goog.dom.contains(parent1, node2)) {\n return -1 * goog.dom.compareParentsDescendantNodeIe_(node1, node2);\n }\n\n\n if (!isElement2 && goog.dom.contains(parent2, node1)) {\n return goog.dom.compareParentsDescendantNodeIe_(node2, node1);\n }\n\n return (isElement1 ? node1.sourceIndex : parent1.sourceIndex) -\n (isElement2 ? node2.sourceIndex : parent2.sourceIndex);\n }\n }\n\n // For Safari, we compare ranges.\n var doc = goog.dom.getOwnerDocument(node1);\n\n var range1, range2;\n range1 = doc.createRange();\n range1.selectNode(node1);\n range1.collapse(true);\n\n range2 = doc.createRange();\n range2.selectNode(node2);\n range2.collapse(true);\n\n return range1.compareBoundaryPoints(\n goog.global['Range'].START_TO_END, range2);\n};\n\n\n/**\n * Utility function to compare the position of two nodes, when\n * `textNode`'s parent is an ancestor of `node`. If this entry\n * condition is not met, this function will attempt to reference a null object.\n * @param {!Node} textNode The textNode to compare.\n * @param {Node} node The node to compare.\n * @return {number} -1 if node is before textNode, +1 otherwise.\n * @private\n */\ngoog.dom.compareParentsDescendantNodeIe_ = function(textNode, node) {\n var parent = textNode.parentNode;\n if (parent == node) {\n // If textNode is a child of node, then node comes first.\n return -1;\n }\n var sibling = node;\n while (sibling.parentNode != parent) {\n sibling = sibling.parentNode;\n }\n return goog.dom.compareSiblingOrder_(sibling, textNode);\n};\n\n\n/**\n * Utility function to compare the position of two nodes known to be non-equal\n * siblings.\n * @param {Node} node1 The first node to compare.\n * @param {!Node} node2 The second node to compare.\n * @return {number} -1 if node1 is before node2, +1 otherwise.\n * @private\n */\ngoog.dom.compareSiblingOrder_ = function(node1, node2) {\n var s = node2;\n while ((s = s.previousSibling)) {\n if (s == node1) {\n // We just found node1 before node2.\n return -1;\n }\n }\n\n // Since we didn't find it, node1 must be after node2.\n return 1;\n};\n\n\n/**\n * Find the deepest common ancestor of the given nodes.\n * @param {...Node} var_args The nodes to find a common ancestor of.\n * @return {Node} The common ancestor of the nodes, or null if there is none.\n * null will only be returned if two or more of the nodes are from different\n * documents.\n */\ngoog.dom.findCommonAncestor = function(var_args) {\n var i, count = arguments.length;\n if (!count) {\n return null;\n } else if (count == 1) {\n return arguments[0];\n }\n\n var paths = [];\n var minLength = Infinity;\n for (i = 0; i < count; i++) {\n // Compute the list of ancestors.\n var ancestors = [];\n var node = arguments[i];\n while (node) {\n ancestors.unshift(node);\n node = node.parentNode;\n }\n\n // Save the list for comparison.\n paths.push(ancestors);\n minLength = Math.min(minLength, ancestors.length);\n }\n var output = null;\n for (i = 0; i < minLength; i++) {\n var first = paths[0][i];\n for (var j = 1; j < count; j++) {\n if (first != paths[j][i]) {\n return output;\n }\n }\n output = first;\n }\n return output;\n};\n\n\n/**\n * Returns whether node is in a document or detached. Throws an error if node\n * itself is a document. This specifically handles two cases beyond naive use of\n * builtins: (1) it works correctly in IE, and (2) it works for elements from\n * different documents/iframes. If neither of these considerations are relevant\n * then a simple `document.contains(node)` may be used instead.\n * @param {!Node} node\n * @return {boolean}\n */\ngoog.dom.isInDocument = function(node) {\n return (node.ownerDocument.compareDocumentPosition(node) & 16) == 16;\n};\n\n\n/**\n * Returns the owner document for a node.\n * @param {Node|Window} node The node to get the document for.\n * @return {!Document} The document owning the node.\n */\ngoog.dom.getOwnerDocument = function(node) {\n // TODO(nnaze): Update param signature to be non-nullable.\n goog.asserts.assert(node, 'Node cannot be null or undefined.');\n return /** @type {!Document} */ (\n node.nodeType == goog.dom.NodeType.DOCUMENT ? node : node.ownerDocument ||\n node.document);\n};\n\n\n/**\n * Cross-browser function for getting the document element of a frame or iframe.\n * @param {Element} frame Frame element.\n * @return {!Document} The frame content document.\n */\ngoog.dom.getFrameContentDocument = function(frame) {\n return frame.contentDocument ||\n /** @type {!HTMLFrameElement} */ (frame).contentWindow.document;\n};\n\n\n/**\n * Cross-browser function for getting the window of a frame or iframe.\n * @param {Element} frame Frame element.\n * @return {Window} The window associated with the given frame, or null if none\n * exists.\n */\ngoog.dom.getFrameContentWindow = function(frame) {\n try {\n return frame.contentWindow ||\n (frame.contentDocument ? goog.dom.getWindow(frame.contentDocument) :\n null);\n } catch (e) {\n // NOTE(user): In IE8, checking the contentWindow or contentDocument\n // properties will throw a \"Unspecified Error\" exception if the iframe is\n // not inserted in the DOM. If we get this we can be sure that no window\n // exists, so return null.\n }\n return null;\n};\n\n\n/**\n * Sets the text content of a node, with cross-browser support.\n * @param {Node} node The node to change the text content of.\n * @param {string|number} text The value that should replace the node's content.\n */\ngoog.dom.setTextContent = function(node, text) {\n goog.asserts.assert(\n node != null,\n 'goog.dom.setTextContent expects a non-null value for node');\n\n if ('textContent' in node) {\n node.textContent = text;\n } else if (node.nodeType == goog.dom.NodeType.TEXT) {\n /** @type {!Text} */ (node).data = String(text);\n } else if (\n node.firstChild && node.firstChild.nodeType == goog.dom.NodeType.TEXT) {\n // If the first child is a text node we just change its data and remove the\n // rest of the children.\n while (node.lastChild != node.firstChild) {\n node.removeChild(goog.asserts.assert(node.lastChild));\n }\n /** @type {!Text} */ (node.firstChild).data = String(text);\n } else {\n goog.dom.removeChildren(node);\n var doc = goog.dom.getOwnerDocument(node);\n node.appendChild(doc.createTextNode(String(text)));\n }\n};\n\n\n/**\n * Gets the outerHTML of a node, which is like innerHTML, except that it\n * actually contains the HTML of the node itself.\n * @param {Element} element The element to get the HTML of.\n * @return {string} The outerHTML of the given element.\n */\ngoog.dom.getOuterHtml = function(element) {\n goog.asserts.assert(\n element !== null,\n 'goog.dom.getOuterHtml expects a non-null value for element');\n // IE, Opera and WebKit all have outerHTML.\n if ('outerHTML' in element) {\n return element.outerHTML;\n } else {\n var doc = goog.dom.getOwnerDocument(element);\n var div = goog.dom.createElement_(doc, goog.dom.TagName.DIV);\n div.appendChild(element.cloneNode(true));\n return div.innerHTML;\n }\n};\n\n\n/**\n * Finds the first descendant node that matches the filter function, using depth\n * first search. This function offers the most general purpose way of finding a\n * matching element.\n *\n * Prefer using `querySelector` if the matching criteria can be expressed as a\n * CSS selector, or `goog.dom.findElement` if you would filter for `nodeType ==\n * Node.ELEMENT_NODE`.\n *\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {Node|undefined} The found node or undefined if none is found.\n */\ngoog.dom.findNode = function(root, p) {\n var rv = [];\n var found = goog.dom.findNodes_(root, p, rv, true);\n return found ? rv[0] : undefined;\n};\n\n\n/**\n * Finds all the descendant nodes that match the filter function, using depth\n * first search. This function offers the most general-purpose way\n * of finding a set of matching elements.\n *\n * Prefer using `querySelectorAll` if the matching criteria can be expressed as\n * a CSS selector, or `goog.dom.findElements` if you would filter for\n * `nodeType == Node.ELEMENT_NODE`.\n *\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {!Array<!Node>} The found nodes or an empty array if none are found.\n */\ngoog.dom.findNodes = function(root, p) {\n var rv = [];\n goog.dom.findNodes_(root, p, rv, false);\n return rv;\n};\n\n\n/**\n * Finds the first or all the descendant nodes that match the filter function,\n * using a depth first search.\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @param {!Array<!Node>} rv The found nodes are added to this array.\n * @param {boolean} findOne If true we exit after the first found node.\n * @return {boolean} Whether the search is complete or not. True in case findOne\n * is true and the node is found. False otherwise.\n * @private\n */\ngoog.dom.findNodes_ = function(root, p, rv, findOne) {\n if (root != null) {\n var child = root.firstChild;\n while (child) {\n if (p(child)) {\n rv.push(child);\n if (findOne) {\n return true;\n }\n }\n if (goog.dom.findNodes_(child, p, rv, findOne)) {\n return true;\n }\n child = child.nextSibling;\n }\n }\n return false;\n};\n\n\n/**\n * Finds the first descendant element (excluding `root`) that matches the filter\n * function, using depth first search. Prefer using `querySelector` if the\n * matching criteria can be expressed as a CSS selector.\n *\n * @param {!Element | !Document} root\n * @param {function(!Element): boolean} pred Filter function.\n * @return {?Element} First matching element or null if there is none.\n */\ngoog.dom.findElement = function(root, pred) {\n var stack = goog.dom.getChildrenReverse_(root);\n while (stack.length > 0) {\n var next = stack.pop();\n if (pred(next)) return next;\n for (var c = next.lastElementChild; c; c = c.previousElementSibling) {\n stack.push(c);\n }\n }\n return null;\n};\n\n\n/**\n * Finds all the descendant elements (excluding `root`) that match the filter\n * function, using depth first search. Prefer using `querySelectorAll` if the\n * matching criteria can be expressed as a CSS selector.\n *\n * @param {!Element | !Document} root\n * @param {function(!Element): boolean} pred Filter function.\n * @return {!Array<!Element>}\n */\ngoog.dom.findElements = function(root, pred) {\n var result = [], stack = goog.dom.getChildrenReverse_(root);\n while (stack.length > 0) {\n var next = stack.pop();\n if (pred(next)) result.push(next);\n for (var c = next.lastElementChild; c; c = c.previousElementSibling) {\n stack.push(c);\n }\n }\n return result;\n};\n\n\n/**\n * @param {!Element | !Document} node\n * @return {!Array<!Element>} node's child elements in reverse order.\n * @private\n */\ngoog.dom.getChildrenReverse_ = function(node) {\n // document.lastElementChild doesn't exist in IE9; fall back to\n // documentElement.\n if (node.nodeType == goog.dom.NodeType.DOCUMENT) {\n return [node.documentElement];\n } else {\n var children = [];\n for (var c = node.lastElementChild; c; c = c.previousElementSibling) {\n children.push(c);\n }\n return children;\n }\n};\n\n\n/**\n * Map of tags whose content to ignore when calculating text length.\n * @private {!Object<string, number>}\n * @const\n */\ngoog.dom.TAGS_TO_IGNORE_ = {\n 'SCRIPT': 1,\n 'STYLE': 1,\n 'HEAD': 1,\n 'IFRAME': 1,\n 'OBJECT': 1\n};\n\n\n/**\n * Map of tags which have predefined values with regard to whitespace.\n * @private {!Object<string, string>}\n * @const\n */\ngoog.dom.PREDEFINED_TAG_VALUES_ = {\n 'IMG': ' ',\n 'BR': '\\n'\n};\n\n\n/**\n * Returns true if the element has a tab index that allows it to receive\n * keyboard focus (tabIndex >= 0), false otherwise. Note that some elements\n * natively support keyboard focus, even if they have no tab index.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element has a tab index that allows keyboard\n * focus.\n */\ngoog.dom.isFocusableTabIndex = function(element) {\n return goog.dom.hasSpecifiedTabIndex_(element) &&\n goog.dom.isTabIndexFocusable_(element);\n};\n\n\n/**\n * Enables or disables keyboard focus support on the element via its tab index.\n * Only elements for which {@link goog.dom.isFocusableTabIndex} returns true\n * (or elements that natively support keyboard focus, like form elements) can\n * receive keyboard focus. See http://go/tabindex for more info.\n * @param {Element} element Element whose tab index is to be changed.\n * @param {boolean} enable Whether to set or remove a tab index on the element\n * that supports keyboard focus.\n */\ngoog.dom.setFocusableTabIndex = function(element, enable) {\n if (enable) {\n element.tabIndex = 0;\n } else {\n // Set tabIndex to -1 first, then remove it. This is a workaround for\n // Safari (confirmed in version 4 on Windows). When removing the attribute\n // without setting it to -1 first, the element remains keyboard focusable\n // despite not having a tabIndex attribute anymore.\n element.tabIndex = -1;\n element.removeAttribute('tabIndex'); // Must be camelCase!\n }\n};\n\n\n/**\n * Returns true if the element can be focused, i.e. it has a tab index that\n * allows it to receive keyboard focus (tabIndex >= 0), or it is an element\n * that natively supports keyboard focus.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element allows keyboard focus.\n */\ngoog.dom.isFocusable = function(element) {\n var focusable;\n // Some elements can have unspecified tab index and still receive focus.\n if (goog.dom.nativelySupportsFocus_(element)) {\n // Make sure the element is not disabled ...\n focusable = !element.disabled &&\n // ... and if a tab index is specified, it allows focus.\n (!goog.dom.hasSpecifiedTabIndex_(element) ||\n goog.dom.isTabIndexFocusable_(element));\n } else {\n focusable = goog.dom.isFocusableTabIndex(element);\n }\n\n // IE requires elements to be visible in order to focus them.\n return focusable && goog.userAgent.IE ?\n goog.dom.hasNonZeroBoundingRect_(/** @type {!HTMLElement} */ (element)) :\n focusable;\n};\n\n\n/**\n * Returns true if the element has a specified tab index.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element has a specified tab index.\n * @private\n */\ngoog.dom.hasSpecifiedTabIndex_ = function(element) {\n // IE8 and below don't support hasAttribute(), instead check whether the\n // 'tabindex' attributeNode is specified. Otherwise check hasAttribute().\n if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')) {\n var attrNode = element.getAttributeNode('tabindex'); // Must be lowercase!\n return attrNode != null && attrNode.specified;\n } else {\n return element.hasAttribute('tabindex');\n }\n};\n\n\n/**\n * Returns true if the element's tab index allows the element to be focused.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element's tab index allows focus.\n * @private\n */\ngoog.dom.isTabIndexFocusable_ = function(element) {\n var index = /** @type {!HTMLElement} */ (element).tabIndex;\n // NOTE: IE9 puts tabIndex in 16-bit int, e.g. -2 is 65534.\n return typeof (index) === 'number' && index >= 0 && index < 32768;\n};\n\n\n/**\n * Returns true if the element is focusable even when tabIndex is not set.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element natively supports focus.\n * @private\n */\ngoog.dom.nativelySupportsFocus_ = function(element) {\n return (\n element.tagName == goog.dom.TagName.A && element.hasAttribute('href') ||\n element.tagName == goog.dom.TagName.INPUT ||\n element.tagName == goog.dom.TagName.TEXTAREA ||\n element.tagName == goog.dom.TagName.SELECT ||\n element.tagName == goog.dom.TagName.BUTTON);\n};\n\n\n/**\n * Returns true if the element has a bounding rectangle that would be visible\n * (i.e. its width and height are greater than zero).\n * @param {!HTMLElement} element Element to check.\n * @return {boolean} Whether the element has a non-zero bounding rectangle.\n * @private\n */\ngoog.dom.hasNonZeroBoundingRect_ = function(element) {\n var rect;\n if (!goog.isFunction(element['getBoundingClientRect']) ||\n // In IE, getBoundingClientRect throws on detached nodes.\n (goog.userAgent.IE && element.parentElement == null)) {\n rect = {'height': element.offsetHeight, 'width': element.offsetWidth};\n } else {\n rect = element.getBoundingClientRect();\n }\n return rect != null && rect.height > 0 && rect.width > 0;\n};\n\n\n/**\n * Returns the text content of the current node, without markup and invisible\n * symbols. New lines are stripped and whitespace is collapsed,\n * such that each character would be visible.\n *\n * In browsers that support it, innerText is used. Other browsers attempt to\n * simulate it via node traversal. Line breaks are canonicalized in IE.\n *\n * @param {Node} node The node from which we are getting content.\n * @return {string} The text content.\n */\ngoog.dom.getTextContent = function(node) {\n var textContent;\n // Note(arv): IE9, Opera, and Safari 3 support innerText but they include\n // text nodes in script tags. So we revert to use a user agent test here.\n if (goog.dom.BrowserFeature.CAN_USE_INNER_TEXT && node !== null &&\n ('innerText' in node)) {\n textContent = goog.string.canonicalizeNewlines(node.innerText);\n // Unfortunately .innerText() returns text with ­ symbols\n // We need to filter it out and then remove duplicate whitespaces\n } else {\n var buf = [];\n goog.dom.getTextContent_(node, buf, true);\n textContent = buf.join('');\n }\n\n // Strip ­ entities. goog.format.insertWordBreaks inserts them in Opera.\n textContent = textContent.replace(/ \\xAD /g, ' ').replace(/\\xAD/g, '');\n // Strip ​ entities. goog.format.insertWordBreaks inserts them in IE8.\n textContent = textContent.replace(/\\u200B/g, '');\n\n // Skip this replacement on old browsers with working innerText, which\n // automatically turns into ' ' and / +/ into ' ' when reading\n // innerText.\n if (!goog.dom.BrowserFeature.CAN_USE_INNER_TEXT) {\n textContent = textContent.replace(/ +/g, ' ');\n }\n if (textContent != ' ') {\n textContent = textContent.replace(/^\\s*/, '');\n }\n\n return textContent;\n};\n\n\n/**\n * Returns the text content of the current node, without markup.\n *\n * Unlike `getTextContent` this method does not collapse whitespaces\n * or normalize lines breaks.\n *\n * @param {Node} node The node from which we are getting content.\n * @return {string} The raw text content.\n */\ngoog.dom.getRawTextContent = function(node) {\n var buf = [];\n goog.dom.getTextContent_(node, buf, false);\n\n return buf.join('');\n};\n\n\n/**\n * Recursive support function for text content retrieval.\n *\n * @param {Node} node The node from which we are getting content.\n * @param {Array<string>} buf string buffer.\n * @param {boolean} normalizeWhitespace Whether to normalize whitespace.\n * @private\n */\ngoog.dom.getTextContent_ = function(node, buf, normalizeWhitespace) {\n if (node.nodeName in goog.dom.TAGS_TO_IGNORE_) {\n // ignore certain tags\n } else if (node.nodeType == goog.dom.NodeType.TEXT) {\n if (normalizeWhitespace) {\n buf.push(String(node.nodeValue).replace(/(\\r\\n|\\r|\\n)/g, ''));\n } else {\n buf.push(node.nodeValue);\n }\n } else if (node.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {\n buf.push(goog.dom.PREDEFINED_TAG_VALUES_[node.nodeName]);\n } else {\n var child = node.firstChild;\n while (child) {\n goog.dom.getTextContent_(child, buf, normalizeWhitespace);\n child = child.nextSibling;\n }\n }\n};\n\n\n/**\n * Returns the text length of the text contained in a node, without markup. This\n * is equivalent to the selection length if the node was selected, or the number\n * of cursor movements to traverse the node. Images & BRs take one space. New\n * lines are ignored.\n *\n * @param {Node} node The node whose text content length is being calculated.\n * @return {number} The length of `node`'s text content.\n */\ngoog.dom.getNodeTextLength = function(node) {\n return goog.dom.getTextContent(node).length;\n};\n\n\n/**\n * Returns the text offset of a node relative to one of its ancestors. The text\n * length is the same as the length calculated by goog.dom.getNodeTextLength.\n *\n * @param {Node} node The node whose offset is being calculated.\n * @param {Node=} opt_offsetParent The node relative to which the offset will\n * be calculated. Defaults to the node's owner document's body.\n * @return {number} The text offset.\n */\ngoog.dom.getNodeTextOffset = function(node, opt_offsetParent) {\n var root = opt_offsetParent || goog.dom.getOwnerDocument(node).body;\n var buf = [];\n while (node && node != root) {\n var cur = node;\n while ((cur = cur.previousSibling)) {\n buf.unshift(goog.dom.getTextContent(cur));\n }\n node = node.parentNode;\n }\n // Trim left to deal with FF cases when there might be line breaks and empty\n // nodes at the front of the text\n return goog.string.trimLeft(buf.join('')).replace(/ +/g, ' ').length;\n};\n\n\n/**\n * Returns the node at a given offset in a parent node. If an object is\n * provided for the optional third parameter, the node and the remainder of the\n * offset will stored as properties of this object.\n * @param {Node} parent The parent node.\n * @param {number} offset The offset into the parent node.\n * @param {Object=} opt_result Object to be used to store the return value. The\n * return value will be stored in the form {node: Node, remainder: number}\n * if this object is provided.\n * @return {Node} The node at the given offset.\n */\ngoog.dom.getNodeAtOffset = function(parent, offset, opt_result) {\n var stack = [parent], pos = 0, cur = null;\n while (stack.length > 0 && pos < offset) {\n cur = stack.pop();\n if (cur.nodeName in goog.dom.TAGS_TO_IGNORE_) {\n // ignore certain tags\n } else if (cur.nodeType == goog.dom.NodeType.TEXT) {\n var text = cur.nodeValue.replace(/(\\r\\n|\\r|\\n)/g, '').replace(/ +/g, ' ');\n pos += text.length;\n } else if (cur.nodeName in goog.dom.PREDEFINED_TAG_VALUES_) {\n pos += goog.dom.PREDEFINED_TAG_VALUES_[cur.nodeName].length;\n } else {\n for (var i = cur.childNodes.length - 1; i >= 0; i--) {\n stack.push(cur.childNodes[i]);\n }\n }\n }\n if (goog.isObject(opt_result)) {\n opt_result.remainder = cur ? cur.nodeValue.length + offset - pos - 1 : 0;\n opt_result.node = cur;\n }\n\n return cur;\n};\n\n\n/**\n * Returns true if the object is a `NodeList`. To qualify as a NodeList,\n * the object must have a numeric length property and an item function (which\n * has type 'string' on IE for some reason).\n * @param {Object} val Object to test.\n * @return {boolean} Whether the object is a NodeList.\n */\ngoog.dom.isNodeList = function(val) {\n // TODO(attila): Now the isNodeList is part of goog.dom we can use\n // goog.userAgent to make this simpler.\n // A NodeList must have a length property of type 'number' on all platforms.\n if (val && typeof val.length == 'number') {\n // A NodeList is an object everywhere except Safari, where it's a function.\n if (goog.isObject(val)) {\n // A NodeList must have an item function (on non-IE platforms) or an item\n // property of type 'string' (on IE).\n return typeof val.item == 'function' || typeof val.item == 'string';\n } else if (goog.isFunction(val)) {\n // On Safari, a NodeList is a function with an item property that is also\n // a function.\n return typeof /** @type {?} */ (val.item) == 'function';\n }\n }\n\n // Not a NodeList.\n return false;\n};\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * tag name and/or class name. If the passed element matches the specified\n * criteria, the element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {?(goog.dom.TagName<T>|string)=} opt_tag The tag name to match (or\n * null/undefined to match only based on class name).\n * @param {?string=} opt_class The class name to match (or null/undefined to\n * match only based on tag name).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n * dom.\n * @return {?R} The first ancestor that matches the passed criteria, or\n * null if no match is found. The return type is {?Element} if opt_tag is\n * not a member of goog.dom.TagName or a more specific type if it is (e.g.\n * {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.getAncestorByTagNameAndClass = function(\n element, opt_tag, opt_class, opt_maxSearchSteps) {\n if (!opt_tag && !opt_class) {\n return null;\n }\n var tagName = opt_tag ? String(opt_tag).toUpperCase() : null;\n return /** @type {Element} */ (goog.dom.getAncestor(element, function(node) {\n return (!tagName || node.nodeName == tagName) &&\n (!opt_class ||\n typeof node.className === 'string' &&\n goog.array.contains(node.className.split(/\\s+/), opt_class));\n }, true, opt_maxSearchSteps));\n};\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * class name. If the passed element matches the specified criteria, the\n * element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {string} className The class name to match.\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n * dom.\n * @return {Element} The first ancestor that matches the passed criteria, or\n * null if none match.\n */\ngoog.dom.getAncestorByClass = function(element, className, opt_maxSearchSteps) {\n return goog.dom.getAncestorByTagNameAndClass(\n element, null, className, opt_maxSearchSteps);\n};\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that passes the\n * matcher function.\n * @param {Node} element The DOM node to start with.\n * @param {function(Node) : boolean} matcher A function that returns true if the\n * passed node matches the desired criteria.\n * @param {boolean=} opt_includeNode If true, the node itself is included in\n * the search (the first call to the matcher will pass startElement as\n * the node to test).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n * dom.\n * @return {Node} DOM node that matched the matcher, or null if there was\n * no match.\n */\ngoog.dom.getAncestor = function(\n element, matcher, opt_includeNode, opt_maxSearchSteps) {\n if (element && !opt_includeNode) {\n element = element.parentNode;\n }\n var steps = 0;\n while (element &&\n (opt_maxSearchSteps == null || steps <= opt_maxSearchSteps)) {\n goog.asserts.assert(element.name != 'parentNode');\n if (matcher(element)) {\n return element;\n }\n element = element.parentNode;\n steps++;\n }\n // Reached the root of the DOM without a match\n return null;\n};\n\n\n/**\n * Determines the active element in the given document.\n * @param {Document} doc The document to look in.\n * @return {Element} The active element.\n */\ngoog.dom.getActiveElement = function(doc) {\n // While in an iframe, IE9 will throw \"Unspecified error\" when accessing\n // activeElement.\n try {\n var activeElement = doc && doc.activeElement;\n // While not in an iframe, IE9-11 sometimes gives null.\n // While in an iframe, IE11 sometimes returns an empty object.\n return activeElement && activeElement.nodeName ? activeElement : null;\n } catch (e) {\n return null;\n }\n};\n\n\n/**\n * Gives the current devicePixelRatio.\n *\n * By default, this is the value of window.devicePixelRatio (which should be\n * preferred if present).\n *\n * If window.devicePixelRatio is not present, the ratio is calculated with\n * window.matchMedia, if present. Otherwise, gives 1.0.\n *\n * Some browsers (including Chrome) consider the browser zoom level in the pixel\n * ratio, so the value may change across multiple calls.\n *\n * @return {number} The number of actual pixels per virtual pixel.\n */\ngoog.dom.getPixelRatio = function() {\n var win = goog.dom.getWindow();\n if (win.devicePixelRatio !== undefined) {\n return win.devicePixelRatio;\n } else if (win.matchMedia) {\n // Should be for IE10 and FF6-17 (this basically clamps to lower)\n // Note that the order of these statements is important\n return goog.dom.matchesPixelRatio_(3) || goog.dom.matchesPixelRatio_(2) ||\n goog.dom.matchesPixelRatio_(1.5) || goog.dom.matchesPixelRatio_(1) ||\n .75;\n }\n return 1;\n};\n\n\n/**\n * Calculates a mediaQuery to check if the current device supports the\n * given actual to virtual pixel ratio.\n * @param {number} pixelRatio The ratio of actual pixels to virtual pixels.\n * @return {number} pixelRatio if applicable, otherwise 0.\n * @private\n */\ngoog.dom.matchesPixelRatio_ = function(pixelRatio) {\n var win = goog.dom.getWindow();\n /**\n * Due to the 1:96 fixed ratio of CSS in to CSS px, 1dppx is equivalent to\n * 96dpi.\n * @const {number}\n */\n var dpiPerDppx = 96;\n var query =\n // FF16-17\n '(min-resolution: ' + pixelRatio + 'dppx),' +\n // FF6-15\n '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' +\n // IE10 (this works for the two browsers above too but I don't want to\n // trust the 1:96 fixed ratio magic)\n '(min-resolution: ' + (pixelRatio * dpiPerDppx) + 'dpi)';\n return win.matchMedia(query).matches ? pixelRatio : 0;\n};\n\n\n/**\n * Gets '2d' context of a canvas. Shortcut for canvas.getContext('2d') with a\n * type information.\n * @param {!HTMLCanvasElement|!OffscreenCanvas} canvas\n * @return {!CanvasRenderingContext2D}\n */\ngoog.dom.getCanvasContext2D = function(canvas) {\n return /** @type {!CanvasRenderingContext2D} */ (canvas.getContext('2d'));\n};\n\n\n\n/**\n * Create an instance of a DOM helper with a new document object.\n * @param {Document=} opt_document Document object to associate with this\n * DOM helper.\n * @constructor\n */\ngoog.dom.DomHelper = function(opt_document) {\n /**\n * Reference to the document object to use\n * @type {!Document}\n * @private\n */\n this.document_ = opt_document || goog.global.document || document;\n};\n\n\n/**\n * Gets the dom helper object for the document where the element resides.\n * @param {Node=} opt_node If present, gets the DomHelper for this node.\n * @return {!goog.dom.DomHelper} The DomHelper.\n */\ngoog.dom.DomHelper.prototype.getDomHelper = goog.dom.getDomHelper;\n\n\n/**\n * Sets the document object.\n * @param {!Document} document Document object.\n */\ngoog.dom.DomHelper.prototype.setDocument = function(document) {\n this.document_ = document;\n};\n\n\n/**\n * Gets the document object being used by the dom library.\n * @return {!Document} Document object.\n */\ngoog.dom.DomHelper.prototype.getDocument = function() {\n return this.document_;\n};\n\n\n/**\n * Alias for `getElementById`. If a DOM node is passed in then we just\n * return that.\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n */\ngoog.dom.DomHelper.prototype.getElement = function(element) {\n return goog.dom.getElementHelper_(this.document_, element);\n};\n\n\n/**\n * Gets an element by id, asserting that the element is found.\n *\n * This is used when an element is expected to exist, and should fail with\n * an assertion error if it does not (if assertions are enabled).\n *\n * @param {string} id Element ID.\n * @return {!Element} The element with the given ID, if it exists.\n */\ngoog.dom.DomHelper.prototype.getRequiredElement = function(id) {\n return goog.dom.getRequiredElementHelper_(this.document_, id);\n};\n\n\n/**\n * Alias for `getElement`.\n * @param {string|Element} element Element ID or a DOM node.\n * @return {Element} The element with the given ID, or the node passed in.\n * @deprecated Use {@link goog.dom.DomHelper.prototype.getElement} instead.\n */\ngoog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement;\n\n\n/**\n * Gets elements by tag name.\n * @param {!goog.dom.TagName<T>} tagName\n * @param {(!Document|!Element)=} opt_parent Parent element or document where to\n * look for elements. Defaults to document of this DomHelper.\n * @return {!NodeList<R>} List of elements. The members of the list are\n * {!Element} if tagName is not a member of goog.dom.TagName or more\n * specific types if it is (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getElementsByTagName =\n function(tagName, opt_parent) {\n var parent = opt_parent || this.document_;\n return parent.getElementsByTagName(String(tagName));\n};\n\n\n/**\n * Looks up elements by both tag and class name, using browser native functions\n * (`querySelectorAll`, `getElementsByTagName` or\n * `getElementsByClassName`) where possible. The returned array is a live\n * NodeList or a static list depending on the code path taken.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name or * for all\n * tags.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n * and numerical indices are guaranteed to exist). The members of the array\n * are {!Element} if opt_tag is not a member of goog.dom.TagName or more\n * specific types if it is (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(\n opt_tag, opt_class, opt_el) {\n return goog.dom.getElementsByTagNameAndClass_(\n this.document_, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Gets the first element matching the tag and the class.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {(Document|Element)=} opt_el Optional element to look in.\n * @return {?R} Reference to a DOM node. The return type is {?Element} if\n * tagName is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getElementByTagNameAndClass = function(\n opt_tag, opt_class, opt_el) {\n return goog.dom.getElementByTagNameAndClass_(\n this.document_, opt_tag, opt_class, opt_el);\n};\n\n\n/**\n * Returns an array of all the elements with the provided className.\n * @param {string} className the name of the class to look for.\n * @param {Element|Document=} opt_el Optional element to look in.\n * @return {!IArrayLike<!Element>} The items found with the class name provided.\n */\ngoog.dom.DomHelper.prototype.getElementsByClass = function(className, opt_el) {\n var doc = opt_el || this.document_;\n return goog.dom.getElementsByClass(className, doc);\n};\n\n\n/**\n * Returns the first element we find matching the provided class name.\n * @param {string} className the name of the class to look for.\n * @param {(Element|Document)=} opt_el Optional element to look in.\n * @return {Element} The first item found with the class name provided.\n */\ngoog.dom.DomHelper.prototype.getElementByClass = function(className, opt_el) {\n var doc = opt_el || this.document_;\n return goog.dom.getElementByClass(className, doc);\n};\n\n\n/**\n * Ensures an element with the given className exists, and then returns the\n * first element with the provided className.\n * @param {string} className the name of the class to look for.\n * @param {(!Element|!Document)=} opt_root Optional element or document to look\n * in.\n * @return {!Element} The first item found with the class name provided.\n * @throws {goog.asserts.AssertionError} Thrown if no element is found.\n */\ngoog.dom.DomHelper.prototype.getRequiredElementByClass = function(\n className, opt_root) {\n var root = opt_root || this.document_;\n return goog.dom.getRequiredElementByClass(className, root);\n};\n\n\n/**\n * Alias for `getElementsByTagNameAndClass`.\n * @deprecated Use DomHelper getElementsByTagNameAndClass.\n *\n * @param {(string|?goog.dom.TagName<T>)=} opt_tag Element tag name.\n * @param {?string=} opt_class Optional class name.\n * @param {Element=} opt_el Optional element to look in.\n * @return {!IArrayLike<R>} Array-like list of elements (only a length property\n * and numerical indices are guaranteed to exist). The members of the array\n * are {!Element} if opt_tag is a string or more specific types if it is\n * a member of goog.dom.TagName (e.g. {!HTMLAnchorElement} for\n * goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.$$ =\n goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;\n\n\n/**\n * Sets a number of properties on a node.\n * @param {Element} element DOM node to set properties on.\n * @param {Object} properties Hash of property:value pairs.\n */\ngoog.dom.DomHelper.prototype.setProperties = goog.dom.setProperties;\n\n\n/**\n * Gets the dimensions of the viewport.\n * @param {Window=} opt_window Optional window element to test. Defaults to\n * the window of the Dom Helper.\n * @return {!goog.math.Size} Object with values 'width' and 'height'.\n */\ngoog.dom.DomHelper.prototype.getViewportSize = function(opt_window) {\n // TODO(arv): This should not take an argument. That breaks the rule of a\n // a DomHelper representing a single frame/window/document.\n return goog.dom.getViewportSize(opt_window || this.getWindow());\n};\n\n\n/**\n * Calculates the height of the document.\n *\n * @return {number} The height of the document.\n */\ngoog.dom.DomHelper.prototype.getDocumentHeight = function() {\n return goog.dom.getDocumentHeight_(this.getWindow());\n};\n\n\n/**\n * Typedef for use with goog.dom.createDom and goog.dom.append.\n * @typedef {Object|string|Array|NodeList}\n */\ngoog.dom.Appendable;\n\n\n/**\n * Returns a dom node with a set of attributes. This function accepts varargs\n * for subsequent nodes to be added. Subsequent nodes will be added to the\n * first node as childNodes.\n *\n * So:\n * <code>createDom(goog.dom.TagName.DIV, null, createDom(goog.dom.TagName.P),\n * createDom(goog.dom.TagName.P));</code> would return a div with two child\n * paragraphs\n *\n * An easy way to move all child nodes of an existing element to a new parent\n * element is:\n * <code>createDom(goog.dom.TagName.DIV, null, oldElement.childNodes);</code>\n * which will remove all child nodes from the old element and add them as\n * child nodes of the new DIV.\n *\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n * of name-value pairs for attributes. If a string, then this is the\n * className of the new element. If an array, the elements will be joined\n * together as the className of the new element.\n * @param {...(goog.dom.Appendable|undefined)} var_args Further DOM nodes or\n * strings for text nodes. If one of the var_args is an array or\n * NodeList, its elements will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n * is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.createDom = function(\n tagName, opt_attributes, var_args) {\n return goog.dom.createDom_(this.document_, arguments);\n};\n\n\n/**\n * Alias for `createDom`.\n * @param {string|!goog.dom.TagName<T>} tagName Tag to create.\n * @param {?Object|?Array<string>|string=} opt_attributes If object, then a map\n * of name-value pairs for attributes. If a string, then this is the\n * className of the new element. If an array, the elements will be joined\n * together as the className of the new element.\n * @param {...(goog.dom.Appendable|undefined)} var_args Further DOM nodes or\n * strings for text nodes. If one of the var_args is an array, its children\n * will be added as childNodes instead.\n * @return {R} Reference to a DOM node. The return type is {!Element} if tagName\n * is a string or a more specific type if it is a member of\n * goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n * @deprecated Use {@link goog.dom.DomHelper.prototype.createDom} instead.\n */\ngoog.dom.DomHelper.prototype.$dom = goog.dom.DomHelper.prototype.createDom;\n\n\n/**\n * Creates a new element.\n * @param {string|!goog.dom.TagName<T>} name Tag to create.\n * @return {R} The new element. The return type is {!Element} if name is\n * a string or a more specific type if it is a member of goog.dom.TagName\n * (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.createElement = function(name) {\n return goog.dom.createElement_(this.document_, name);\n};\n\n\n/**\n * Creates a new text node.\n * @param {number|string} content Content.\n * @return {!Text} The new text node.\n */\ngoog.dom.DomHelper.prototype.createTextNode = function(content) {\n return this.document_.createTextNode(String(content));\n};\n\n\n/**\n * Create a table.\n * @param {number} rows The number of rows in the table. Must be >= 1.\n * @param {number} columns The number of columns in the table. Must be >= 1.\n * @param {boolean=} opt_fillWithNbsp If true, fills table entries with\n * `goog.string.Unicode.NBSP` characters.\n * @return {!HTMLElement} The created table.\n */\ngoog.dom.DomHelper.prototype.createTable = function(\n rows, columns, opt_fillWithNbsp) {\n return goog.dom.createTable_(\n this.document_, rows, columns, !!opt_fillWithNbsp);\n};\n\n\n/**\n * Converts an HTML into a node or a document fragment. A single Node is used if\n * `html` only generates a single node. If `html` generates multiple\n * nodes then these are put inside a `DocumentFragment`. This is a safe\n * version of `goog.dom.DomHelper#htmlToDocumentFragment` which is now\n * deleted.\n * @param {!goog.html.SafeHtml} html The HTML markup to convert.\n * @return {!Node} The resulting node.\n */\ngoog.dom.DomHelper.prototype.safeHtmlToNode = function(html) {\n return goog.dom.safeHtmlToNode_(this.document_, html);\n};\n\n\n/**\n * Returns true if the browser is in \"CSS1-compatible\" (standards-compliant)\n * mode, false otherwise.\n * @return {boolean} True if in CSS1-compatible mode.\n */\ngoog.dom.DomHelper.prototype.isCss1CompatMode = function() {\n return goog.dom.isCss1CompatMode_(this.document_);\n};\n\n\n/**\n * Gets the window object associated with the document.\n * @return {!Window} The window associated with the given document.\n */\ngoog.dom.DomHelper.prototype.getWindow = function() {\n return goog.dom.getWindow_(this.document_);\n};\n\n\n/**\n * Gets the document scroll element.\n * @return {!Element} Scrolling element.\n */\ngoog.dom.DomHelper.prototype.getDocumentScrollElement = function() {\n return goog.dom.getDocumentScrollElement_(this.document_);\n};\n\n\n/**\n * Gets the document scroll distance as a coordinate object.\n * @return {!goog.math.Coordinate} Object with properties 'x' and 'y'.\n */\ngoog.dom.DomHelper.prototype.getDocumentScroll = function() {\n return goog.dom.getDocumentScroll_(this.document_);\n};\n\n\n/**\n * Determines the active element in the given document.\n * @param {Document=} opt_doc The document to look in.\n * @return {Element} The active element.\n */\ngoog.dom.DomHelper.prototype.getActiveElement = function(opt_doc) {\n return goog.dom.getActiveElement(opt_doc || this.document_);\n};\n\n\n/**\n * Appends a child to a node.\n * @param {Node} parent Parent.\n * @param {Node} child Child.\n */\ngoog.dom.DomHelper.prototype.appendChild = goog.dom.appendChild;\n\n\n/**\n * Appends a node with text or other nodes.\n * @param {!Node} parent The node to append nodes to.\n * @param {...goog.dom.Appendable} var_args The things to append to the node.\n * If this is a Node it is appended as is.\n * If this is a string then a text node is appended.\n * If this is an array like object then fields 0 to length - 1 are appended.\n */\ngoog.dom.DomHelper.prototype.append = goog.dom.append;\n\n\n/**\n * Determines if the given node can contain children, intended to be used for\n * HTML generation.\n *\n * @param {Node} node The node to check.\n * @return {boolean} Whether the node can contain children.\n */\ngoog.dom.DomHelper.prototype.canHaveChildren = goog.dom.canHaveChildren;\n\n\n/**\n * Removes all the child nodes on a DOM node.\n * @param {Node} node Node to remove children from.\n */\ngoog.dom.DomHelper.prototype.removeChildren = goog.dom.removeChildren;\n\n\n/**\n * Inserts a new node before an existing reference node (i.e., as the previous\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert before.\n */\ngoog.dom.DomHelper.prototype.insertSiblingBefore = goog.dom.insertSiblingBefore;\n\n\n/**\n * Inserts a new node after an existing reference node (i.e., as the next\n * sibling). If the reference node has no parent, then does nothing.\n * @param {Node} newNode Node to insert.\n * @param {Node} refNode Reference node to insert after.\n */\ngoog.dom.DomHelper.prototype.insertSiblingAfter = goog.dom.insertSiblingAfter;\n\n\n/**\n * Insert a child at a given index. If index is larger than the number of child\n * nodes that the parent currently has, the node is inserted as the last child\n * node.\n * @param {Element} parent The element into which to insert the child.\n * @param {Node} child The element to insert.\n * @param {number} index The index at which to insert the new child node. Must\n * not be negative.\n */\ngoog.dom.DomHelper.prototype.insertChildAt = goog.dom.insertChildAt;\n\n\n/**\n * Removes a node from its parent.\n * @param {Node} node The node to remove.\n * @return {Node} The node removed if removed; else, null.\n */\ngoog.dom.DomHelper.prototype.removeNode = goog.dom.removeNode;\n\n\n/**\n * Replaces a node in the DOM tree. Will do nothing if `oldNode` has no\n * parent.\n * @param {Node} newNode Node to insert.\n * @param {Node} oldNode Node to replace.\n */\ngoog.dom.DomHelper.prototype.replaceNode = goog.dom.replaceNode;\n\n\n/**\n * Flattens an element. That is, removes it and replace it with its children.\n * @param {Element} element The element to flatten.\n * @return {Element|undefined} The original element, detached from the document\n * tree, sans children, or undefined if the element was already not in the\n * document.\n */\ngoog.dom.DomHelper.prototype.flattenElement = goog.dom.flattenElement;\n\n\n/**\n * Returns an array containing just the element children of the given element.\n * @param {Element} element The element whose element children we want.\n * @return {!(Array<!Element>|NodeList<!Element>)} An array or array-like list\n * of just the element children of the given element.\n */\ngoog.dom.DomHelper.prototype.getChildren = goog.dom.getChildren;\n\n\n/**\n * Returns the first child node that is an element.\n * @param {Node} node The node to get the first child element of.\n * @return {Element} The first child node of `node` that is an element.\n */\ngoog.dom.DomHelper.prototype.getFirstElementChild =\n goog.dom.getFirstElementChild;\n\n\n/**\n * Returns the last child node that is an element.\n * @param {Node} node The node to get the last child element of.\n * @return {Element} The last child node of `node` that is an element.\n */\ngoog.dom.DomHelper.prototype.getLastElementChild = goog.dom.getLastElementChild;\n\n\n/**\n * Returns the first next sibling that is an element.\n * @param {Node} node The node to get the next sibling element of.\n * @return {Element} The next sibling of `node` that is an element.\n */\ngoog.dom.DomHelper.prototype.getNextElementSibling =\n goog.dom.getNextElementSibling;\n\n\n/**\n * Returns the first previous sibling that is an element.\n * @param {Node} node The node to get the previous sibling element of.\n * @return {Element} The first previous sibling of `node` that is\n * an element.\n */\ngoog.dom.DomHelper.prototype.getPreviousElementSibling =\n goog.dom.getPreviousElementSibling;\n\n\n/**\n * Returns the next node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The next node in the DOM tree, or null if this was the last\n * node.\n */\ngoog.dom.DomHelper.prototype.getNextNode = goog.dom.getNextNode;\n\n\n/**\n * Returns the previous node in source order from the given node.\n * @param {Node} node The node.\n * @return {Node} The previous node in the DOM tree, or null if this was the\n * first node.\n */\ngoog.dom.DomHelper.prototype.getPreviousNode = goog.dom.getPreviousNode;\n\n\n/**\n * Whether the object looks like a DOM node.\n * @param {?} obj The object being tested for node likeness.\n * @return {boolean} Whether the object looks like a DOM node.\n */\ngoog.dom.DomHelper.prototype.isNodeLike = goog.dom.isNodeLike;\n\n\n/**\n * Whether the object looks like an Element.\n * @param {?} obj The object being tested for Element likeness.\n * @return {boolean} Whether the object looks like an Element.\n */\ngoog.dom.DomHelper.prototype.isElement = goog.dom.isElement;\n\n\n/**\n * Returns true if the specified value is a Window object. This includes the\n * global window for HTML pages, and iframe windows.\n * @param {?} obj Variable to test.\n * @return {boolean} Whether the variable is a window.\n */\ngoog.dom.DomHelper.prototype.isWindow = goog.dom.isWindow;\n\n\n/**\n * Returns an element's parent, if it's an Element.\n * @param {Element} element The DOM element.\n * @return {Element} The parent, or null if not an Element.\n */\ngoog.dom.DomHelper.prototype.getParentElement = goog.dom.getParentElement;\n\n\n/**\n * Whether a node contains another node.\n * @param {Node} parent The node that should contain the other node.\n * @param {Node} descendant The node to test presence of.\n * @return {boolean} Whether the parent node contains the descendant node.\n */\ngoog.dom.DomHelper.prototype.contains = goog.dom.contains;\n\n\n/**\n * Compares the document order of two nodes, returning 0 if they are the same\n * node, a negative number if node1 is before node2, and a positive number if\n * node2 is before node1. Note that we compare the order the tags appear in the\n * document so in the tree <b><i>text</i></b> the B node is considered to be\n * before the I node.\n *\n * @param {Node} node1 The first node to compare.\n * @param {Node} node2 The second node to compare.\n * @return {number} 0 if the nodes are the same node, a negative number if node1\n * is before node2, and a positive number if node2 is before node1.\n */\ngoog.dom.DomHelper.prototype.compareNodeOrder = goog.dom.compareNodeOrder;\n\n\n/**\n * Find the deepest common ancestor of the given nodes.\n * @param {...Node} var_args The nodes to find a common ancestor of.\n * @return {Node} The common ancestor of the nodes, or null if there is none.\n * null will only be returned if two or more of the nodes are from different\n * documents.\n */\ngoog.dom.DomHelper.prototype.findCommonAncestor = goog.dom.findCommonAncestor;\n\n\n/**\n * Returns the owner document for a node.\n * @param {Node} node The node to get the document for.\n * @return {!Document} The document owning the node.\n */\ngoog.dom.DomHelper.prototype.getOwnerDocument = goog.dom.getOwnerDocument;\n\n\n/**\n * Cross browser function for getting the document element of an iframe.\n * @param {Element} iframe Iframe element.\n * @return {!Document} The frame content document.\n */\ngoog.dom.DomHelper.prototype.getFrameContentDocument =\n goog.dom.getFrameContentDocument;\n\n\n/**\n * Cross browser function for getting the window of a frame or iframe.\n * @param {Element} frame Frame element.\n * @return {Window} The window associated with the given frame.\n */\ngoog.dom.DomHelper.prototype.getFrameContentWindow =\n goog.dom.getFrameContentWindow;\n\n\n/**\n * Sets the text content of a node, with cross-browser support.\n * @param {Node} node The node to change the text content of.\n * @param {string|number} text The value that should replace the node's content.\n */\ngoog.dom.DomHelper.prototype.setTextContent = goog.dom.setTextContent;\n\n\n/**\n * Gets the outerHTML of a node, which islike innerHTML, except that it\n * actually contains the HTML of the node itself.\n * @param {Element} element The element to get the HTML of.\n * @return {string} The outerHTML of the given element.\n */\ngoog.dom.DomHelper.prototype.getOuterHtml = goog.dom.getOuterHtml;\n\n\n/**\n * Finds the first descendant node that matches the filter function. This does\n * a depth first search.\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {Node|undefined} The found node or undefined if none is found.\n */\ngoog.dom.DomHelper.prototype.findNode = goog.dom.findNode;\n\n\n/**\n * Finds all the descendant nodes that matches the filter function. This does a\n * depth first search.\n * @param {Node} root The root of the tree to search.\n * @param {function(Node) : boolean} p The filter function.\n * @return {Array<Node>} The found nodes or an empty array if none are found.\n */\ngoog.dom.DomHelper.prototype.findNodes = goog.dom.findNodes;\n\n\n/**\n * Returns true if the element has a tab index that allows it to receive\n * keyboard focus (tabIndex >= 0), false otherwise. Note that some elements\n * natively support keyboard focus, even if they have no tab index.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element has a tab index that allows keyboard\n * focus.\n */\ngoog.dom.DomHelper.prototype.isFocusableTabIndex = goog.dom.isFocusableTabIndex;\n\n\n/**\n * Enables or disables keyboard focus support on the element via its tab index.\n * Only elements for which {@link goog.dom.isFocusableTabIndex} returns true\n * (or elements that natively support keyboard focus, like form elements) can\n * receive keyboard focus. See http://go/tabindex for more info.\n * @param {Element} element Element whose tab index is to be changed.\n * @param {boolean} enable Whether to set or remove a tab index on the element\n * that supports keyboard focus.\n */\ngoog.dom.DomHelper.prototype.setFocusableTabIndex =\n goog.dom.setFocusableTabIndex;\n\n\n/**\n * Returns true if the element can be focused, i.e. it has a tab index that\n * allows it to receive keyboard focus (tabIndex >= 0), or it is an element\n * that natively supports keyboard focus.\n * @param {!Element} element Element to check.\n * @return {boolean} Whether the element allows keyboard focus.\n */\ngoog.dom.DomHelper.prototype.isFocusable = goog.dom.isFocusable;\n\n\n/**\n * Returns the text contents of the current node, without markup. New lines are\n * stripped and whitespace is collapsed, such that each character would be\n * visible.\n *\n * In browsers that support it, innerText is used. Other browsers attempt to\n * simulate it via node traversal. Line breaks are canonicalized in IE.\n *\n * @param {Node} node The node from which we are getting content.\n * @return {string} The text content.\n */\ngoog.dom.DomHelper.prototype.getTextContent = goog.dom.getTextContent;\n\n\n/**\n * Returns the text length of the text contained in a node, without markup. This\n * is equivalent to the selection length if the node was selected, or the number\n * of cursor movements to traverse the node. Images & BRs take one space. New\n * lines are ignored.\n *\n * @param {Node} node The node whose text content length is being calculated.\n * @return {number} The length of `node`'s text content.\n */\ngoog.dom.DomHelper.prototype.getNodeTextLength = goog.dom.getNodeTextLength;\n\n\n/**\n * Returns the text offset of a node relative to one of its ancestors. The text\n * length is the same as the length calculated by\n * `goog.dom.getNodeTextLength`.\n *\n * @param {Node} node The node whose offset is being calculated.\n * @param {Node=} opt_offsetParent Defaults to the node's owner document's body.\n * @return {number} The text offset.\n */\ngoog.dom.DomHelper.prototype.getNodeTextOffset = goog.dom.getNodeTextOffset;\n\n\n/**\n * Returns the node at a given offset in a parent node. If an object is\n * provided for the optional third parameter, the node and the remainder of the\n * offset will stored as properties of this object.\n * @param {Node} parent The parent node.\n * @param {number} offset The offset into the parent node.\n * @param {Object=} opt_result Object to be used to store the return value. The\n * return value will be stored in the form {node: Node, remainder: number}\n * if this object is provided.\n * @return {Node} The node at the given offset.\n */\ngoog.dom.DomHelper.prototype.getNodeAtOffset = goog.dom.getNodeAtOffset;\n\n\n/**\n * Returns true if the object is a `NodeList`. To qualify as a NodeList,\n * the object must have a numeric length property and an item function (which\n * has type 'string' on IE for some reason).\n * @param {Object} val Object to test.\n * @return {boolean} Whether the object is a NodeList.\n */\ngoog.dom.DomHelper.prototype.isNodeList = goog.dom.isNodeList;\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * tag name and/or class name. If the passed element matches the specified\n * criteria, the element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {?(goog.dom.TagName<T>|string)=} opt_tag The tag name to match (or\n * null/undefined to match only based on class name).\n * @param {?string=} opt_class The class name to match (or null/undefined to\n * match only based on tag name).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n * dom.\n * @return {?R} The first ancestor that matches the passed criteria, or\n * null if no match is found. The return type is {?Element} if opt_tag is\n * not a member of goog.dom.TagName or a more specific type if it is (e.g.\n * {?HTMLAnchorElement} for goog.dom.TagName.A).\n * @template T\n * @template R := cond(isUnknown(T), 'Element', T) =:\n */\ngoog.dom.DomHelper.prototype.getAncestorByTagNameAndClass =\n goog.dom.getAncestorByTagNameAndClass;\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that has the passed\n * class name. If the passed element matches the specified criteria, the\n * element itself is returned.\n * @param {Node} element The DOM node to start with.\n * @param {string} class The class name to match.\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n * dom.\n * @return {Element} The first ancestor that matches the passed criteria, or\n * null if none match.\n */\ngoog.dom.DomHelper.prototype.getAncestorByClass = goog.dom.getAncestorByClass;\n\n\n/**\n * Walks up the DOM hierarchy returning the first ancestor that passes the\n * matcher function.\n * @param {Node} element The DOM node to start with.\n * @param {function(Node) : boolean} matcher A function that returns true if the\n * passed node matches the desired criteria.\n * @param {boolean=} opt_includeNode If true, the node itself is included in\n * the search (the first call to the matcher will pass startElement as\n * the node to test).\n * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the\n * dom.\n * @return {Node} DOM node that matched the matcher, or null if there was\n * no match.\n */\ngoog.dom.DomHelper.prototype.getAncestor = goog.dom.getAncestor;\n\n\n/**\n * Gets '2d' context of a canvas. Shortcut for canvas.getContext('2d') with a\n * type information.\n * @param {!HTMLCanvasElement} canvas\n * @return {!CanvasRenderingContext2D}\n */\ngoog.dom.DomHelper.prototype.getCanvasContext2D = goog.dom.getCanvasContext2D;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.Promise');\n\ngoog.require('goog.Thenable');\ngoog.require('goog.asserts');\ngoog.require('goog.async.FreeList');\ngoog.require('goog.async.run');\ngoog.require('goog.async.throwException');\ngoog.require('goog.debug.Error');\ngoog.require('goog.promise.Resolver');\n\n\n\n/**\n * NOTE: This class was created in anticipation of the built-in Promise type\n * being standardized and implemented across browsers. Now that Promise is\n * available in modern browsers, and is automatically polyfilled by the Closure\n * Compiler, by default, most new code should use native `Promise`\n * instead of `goog.Promise`. However, `goog.Promise` has the\n * concept of cancellation which native Promises do not yet have. So code\n * needing cancellation may still want to use `goog.Promise`.\n *\n * Promises provide a result that may be resolved asynchronously. A Promise may\n * be resolved by being fulfilled with a fulfillment value, rejected with a\n * rejection reason, or blocked by another Promise. A Promise is said to be\n * settled if it is either fulfilled or rejected. Once settled, the Promise\n * result is immutable.\n *\n * Promises may represent results of any type, including undefined. Rejection\n * reasons are typically Errors, but may also be of any type. Closure Promises\n * allow for optional type annotations that enforce that fulfillment values are\n * of the appropriate types at compile time.\n *\n * The result of a Promise is accessible by calling `then` and registering\n * `onFulfilled` and `onRejected` callbacks. Once the Promise\n * is settled, the relevant callbacks are invoked with the fulfillment value or\n * rejection reason as argument. Callbacks are always invoked in the order they\n * were registered, even when additional `then` calls are made from inside\n * another callback. A callback is always run asynchronously sometime after the\n * scope containing the registering `then` invocation has returned.\n *\n * If a Promise is resolved with another Promise, the first Promise will block\n * until the second is settled, and then assumes the same result as the second\n * Promise. This allows Promises to depend on the results of other Promises,\n * linking together multiple asynchronous operations.\n *\n * This implementation is compatible with the Promises/A+ specification and\n * passes that specification's conformance test suite. A Closure Promise may be\n * resolved with a Promise instance (or sufficiently compatible Promise-like\n * object) created by other Promise implementations. From the specification,\n * Promise-like objects are known as \"Thenables\".\n *\n * @see http://promisesaplus.com/\n *\n * @param {function(\n * this:RESOLVER_CONTEXT,\n * function((TYPE|IThenable<TYPE>|Thenable)=),\n * function(*=)): void} resolver\n * Initialization function that is invoked immediately with `resolve`\n * and `reject` functions as arguments. The Promise is resolved or\n * rejected with the first argument passed to either function.\n * @param {RESOLVER_CONTEXT=} opt_context An optional context for executing the\n * resolver function. If unspecified, the resolver function will be executed\n * in the default scope.\n * @constructor\n * @struct\n * @final\n * @implements {goog.Thenable<TYPE>}\n * @template TYPE,RESOLVER_CONTEXT\n */\ngoog.Promise = function(resolver, opt_context) {\n /**\n * The internal state of this Promise. Either PENDING, FULFILLED, REJECTED, or\n * BLOCKED.\n * @private {goog.Promise.State_}\n */\n this.state_ = goog.Promise.State_.PENDING;\n\n /**\n * The settled result of the Promise. Immutable once set with either a\n * fulfillment value or rejection reason.\n * @private {*}\n */\n this.result_ = undefined;\n\n /**\n * For Promises created by calling `then()`, the originating parent.\n * @private {?goog.Promise}\n */\n this.parent_ = null;\n\n /**\n * The linked list of `onFulfilled` and `onRejected` callbacks\n * added to this Promise by calls to `then()`.\n * @private {?goog.Promise.CallbackEntry_}\n */\n this.callbackEntries_ = null;\n\n /**\n * The tail of the linked list of `onFulfilled` and `onRejected`\n * callbacks added to this Promise by calls to `then()`.\n * @private {?goog.Promise.CallbackEntry_}\n */\n this.callbackEntriesTail_ = null;\n\n /**\n * Whether the Promise is in the queue of Promises to execute.\n * @private {boolean}\n */\n this.executing_ = false;\n\n if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {\n /**\n * A timeout ID used when the `UNHANDLED_REJECTION_DELAY` is greater\n * than 0 milliseconds. The ID is set when the Promise is rejected, and\n * cleared only if an `onRejected` callback is invoked for the\n * Promise (or one of its descendants) before the delay is exceeded.\n *\n * If the rejection is not handled before the timeout completes, the\n * rejection reason is passed to the unhandled rejection handler.\n * @private {number}\n */\n this.unhandledRejectionId_ = 0;\n } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {\n /**\n * When the `UNHANDLED_REJECTION_DELAY` is set to 0 milliseconds, a\n * boolean that is set if the Promise is rejected, and reset to false if an\n * `onRejected` callback is invoked for the Promise (or one of its\n * descendants). If the rejection is not handled before the next timestep,\n * the rejection reason is passed to the unhandled rejection handler.\n * @private {boolean}\n */\n this.hadUnhandledRejection_ = false;\n }\n\n if (goog.Promise.LONG_STACK_TRACES) {\n /**\n * A list of stack trace frames pointing to the locations where this Promise\n * was created or had callbacks added to it. Saved to add additional context\n * to stack traces when an exception is thrown.\n * @private {!Array<string>}\n */\n this.stack_ = [];\n this.addStackTrace_(new Error('created'));\n\n /**\n * Index of the most recently executed stack frame entry.\n * @private {number}\n */\n this.currentStep_ = 0;\n }\n\n // As an optimization, we can skip this if resolver is goog.nullFunction.\n // This value is passed internally when creating a promise which will be\n // resolved through a more optimized path.\n if (resolver != goog.nullFunction) {\n try {\n var self = this;\n resolver.call(\n opt_context,\n function(value) {\n self.resolve_(goog.Promise.State_.FULFILLED, value);\n },\n function(reason) {\n if (goog.DEBUG &&\n !(reason instanceof goog.Promise.CancellationError)) {\n try {\n // Promise was rejected. Step up one call frame to see why.\n if (reason instanceof Error) {\n throw reason;\n } else {\n throw new Error('Promise rejected.');\n }\n } catch (e) {\n // Only thrown so browser dev tools can catch rejections of\n // promises when the option to break on caught exceptions is\n // activated.\n }\n }\n self.resolve_(goog.Promise.State_.REJECTED, reason);\n });\n } catch (e) {\n this.resolve_(goog.Promise.State_.REJECTED, e);\n }\n }\n};\n\n\n/**\n * @define {boolean} Whether traces of `then` calls should be included in\n * exceptions thrown\n */\ngoog.Promise.LONG_STACK_TRACES =\n goog.define('goog.Promise.LONG_STACK_TRACES', false);\n\n\n/**\n * @define {number} The delay in milliseconds before a rejected Promise's reason\n * is passed to the rejection handler. By default, the rejection handler\n * rethrows the rejection reason so that it appears in the developer console or\n * `window.onerror` handler.\n *\n * Rejections are rethrown as quickly as possible by default. A negative value\n * disables rejection handling entirely.\n */\ngoog.Promise.UNHANDLED_REJECTION_DELAY =\n goog.define('goog.Promise.UNHANDLED_REJECTION_DELAY', 0);\n\n\n/**\n * The possible internal states for a Promise. These states are not directly\n * observable to external callers.\n * @enum {number}\n * @private\n */\ngoog.Promise.State_ = {\n /** The Promise is waiting for resolution. */\n PENDING: 0,\n\n /** The Promise is blocked waiting for the result of another Thenable. */\n BLOCKED: 1,\n\n /** The Promise has been resolved with a fulfillment value. */\n FULFILLED: 2,\n\n /** The Promise has been resolved with a rejection reason. */\n REJECTED: 3\n};\n\n\n\n/**\n * Entries in the callback chain. Each call to `then`,\n * `thenCatch`, or `thenAlways` creates an entry containing the\n * functions that may be invoked once the Promise is settled.\n *\n * @private @final @struct @constructor\n */\ngoog.Promise.CallbackEntry_ = function() {\n /** @type {?goog.Promise} */\n this.child = null;\n /** @type {?Function} */\n this.onFulfilled = null;\n /** @type {?Function} */\n this.onRejected = null;\n /** @type {?} */\n this.context = null;\n /** @type {?goog.Promise.CallbackEntry_} */\n this.next = null;\n\n /**\n * A boolean value to indicate this is a \"thenAlways\" callback entry.\n * Unlike a normal \"then/thenVoid\" a \"thenAlways doesn't participate\n * in \"cancel\" considerations but is simply an observer and requires\n * special handling.\n * @type {boolean}\n */\n this.always = false;\n};\n\n\n/** clear the object prior to reuse */\ngoog.Promise.CallbackEntry_.prototype.reset = function() {\n this.child = null;\n this.onFulfilled = null;\n this.onRejected = null;\n this.context = null;\n this.always = false;\n};\n\n\n/**\n * @define {number} The number of currently unused objects to keep around for\n * reuse.\n */\ngoog.Promise.DEFAULT_MAX_UNUSED =\n goog.define('goog.Promise.DEFAULT_MAX_UNUSED', 100);\n\n\n/** @const @private {goog.async.FreeList<!goog.Promise.CallbackEntry_>} */\ngoog.Promise.freelist_ = new goog.async.FreeList(\n function() { return new goog.Promise.CallbackEntry_(); },\n function(item) { item.reset(); }, goog.Promise.DEFAULT_MAX_UNUSED);\n\n\n/**\n * @param {Function} onFulfilled\n * @param {Function} onRejected\n * @param {?} context\n * @return {!goog.Promise.CallbackEntry_}\n * @private\n */\ngoog.Promise.getCallbackEntry_ = function(onFulfilled, onRejected, context) {\n var entry = goog.Promise.freelist_.get();\n entry.onFulfilled = onFulfilled;\n entry.onRejected = onRejected;\n entry.context = context;\n return entry;\n};\n\n\n/**\n * @param {!goog.Promise.CallbackEntry_} entry\n * @private\n */\ngoog.Promise.returnEntry_ = function(entry) {\n goog.Promise.freelist_.put(entry);\n};\n\n\n// NOTE: this is the same template expression as is used for\n// goog.IThenable.prototype.then\n\n\n/**\n * @param {VALUE=} opt_value\n * @return {RESULT} A new Promise that is immediately resolved\n * with the given value. If the input value is already a goog.Promise, it\n * will be returned immediately without creating a new instance.\n * @template VALUE\n * @template RESULT := type('goog.Promise',\n * cond(isUnknown(VALUE), unknown(),\n * mapunion(VALUE, (V) =>\n * cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'),\n * templateTypeOf(V, 0),\n * cond(sub(V, 'Thenable'),\n * unknown(),\n * V)))))\n * =:\n */\ngoog.Promise.resolve = function(opt_value) {\n if (opt_value instanceof goog.Promise) {\n // Avoid creating a new object if we already have a promise object\n // of the correct type.\n return opt_value;\n }\n\n // Passing goog.nullFunction will cause the constructor to take an optimized\n // path that skips calling the resolver function.\n var promise = new goog.Promise(goog.nullFunction);\n promise.resolve_(goog.Promise.State_.FULFILLED, opt_value);\n return promise;\n};\n\n\n/**\n * @param {*=} opt_reason\n * @return {!goog.Promise} A new Promise that is immediately rejected with the\n * given reason.\n */\ngoog.Promise.reject = function(opt_reason) {\n return new goog.Promise(function(resolve, reject) { reject(opt_reason); });\n};\n\n\n/**\n * This is identical to\n * {@code goog.Promise.resolve(value).then(onFulfilled, onRejected)}, but it\n * avoids creating an unnecessary wrapper Promise when `value` is already\n * thenable.\n *\n * @param {?(goog.Thenable<TYPE>|Thenable|TYPE)} value\n * @param {function(TYPE): ?} onFulfilled\n * @param {function(*): *} onRejected\n * @template TYPE\n * @private\n */\ngoog.Promise.resolveThen_ = function(value, onFulfilled, onRejected) {\n var isThenable =\n goog.Promise.maybeThen_(value, onFulfilled, onRejected, null);\n if (!isThenable) {\n goog.async.run(goog.partial(onFulfilled, value));\n }\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n * promises\n * @return {!goog.Promise<TYPE>} A Promise that receives the result of the\n * first Promise (or Promise-like) input to settle immediately after it\n * settles.\n * @template TYPE\n */\ngoog.Promise.race = function(promises) {\n return new goog.Promise(function(resolve, reject) {\n if (!promises.length) {\n resolve(undefined);\n }\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n goog.Promise.resolveThen_(promise, resolve, reject);\n }\n });\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n * promises\n * @return {!goog.Promise<!Array<TYPE>>} A Promise that receives a list of\n * every fulfilled value once every input Promise (or Promise-like) is\n * successfully fulfilled, or is rejected with the first rejection reason\n * immediately after it is rejected.\n * @template TYPE\n */\ngoog.Promise.all = function(promises) {\n return new goog.Promise(function(resolve, reject) {\n var toFulfill = promises.length;\n var values = [];\n\n if (!toFulfill) {\n resolve(values);\n return;\n }\n\n var onFulfill = function(index, value) {\n toFulfill--;\n values[index] = value;\n if (toFulfill == 0) {\n resolve(values);\n }\n };\n\n var onReject = function(reason) { reject(reason); };\n\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n goog.Promise.resolveThen_(promise, goog.partial(onFulfill, i), onReject);\n }\n });\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n * promises\n * @return {!goog.Promise<!Array<{\n * fulfilled: boolean,\n * value: (TYPE|undefined),\n * reason: (*|undefined)}>>} A Promise that resolves with a list of\n * result objects once all input Promises (or Promise-like) have\n * settled. Each result object contains a 'fulfilled' boolean indicating\n * whether an input Promise was fulfilled or rejected. For fulfilled\n * Promises, the resulting value is stored in the 'value' field. For\n * rejected Promises, the rejection reason is stored in the 'reason'\n * field.\n * @template TYPE\n */\ngoog.Promise.allSettled = function(promises) {\n return new goog.Promise(function(resolve, reject) {\n var toSettle = promises.length;\n var results = [];\n\n if (!toSettle) {\n resolve(results);\n return;\n }\n\n var onSettled = function(index, fulfilled, result) {\n toSettle--;\n results[index] = fulfilled ? {fulfilled: true, value: result} :\n {fulfilled: false, reason: result};\n if (toSettle == 0) {\n resolve(results);\n }\n };\n\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n goog.Promise.resolveThen_(\n promise, goog.partial(onSettled, i, true /* fulfilled */),\n goog.partial(onSettled, i, false /* fulfilled */));\n }\n });\n};\n\n\n/**\n * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>}\n * promises\n * @return {!goog.Promise<TYPE>} A Promise that receives the value of the first\n * input to be fulfilled, or is rejected with a list of every rejection\n * reason if all inputs are rejected.\n * @template TYPE\n */\ngoog.Promise.firstFulfilled = function(promises) {\n return new goog.Promise(function(resolve, reject) {\n var toReject = promises.length;\n var reasons = [];\n\n if (!toReject) {\n resolve(undefined);\n return;\n }\n\n var onFulfill = function(value) { resolve(value); };\n\n var onReject = function(index, reason) {\n toReject--;\n reasons[index] = reason;\n if (toReject == 0) {\n reject(reasons);\n }\n };\n\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n goog.Promise.resolveThen_(promise, onFulfill, goog.partial(onReject, i));\n }\n });\n};\n\n\n/**\n * @return {!goog.promise.Resolver<TYPE>} Resolver wrapping the promise and its\n * resolve / reject functions. Resolving or rejecting the resolver\n * resolves or rejects the promise.\n * @template TYPE\n */\ngoog.Promise.withResolver = function() {\n var resolve, reject;\n var promise = new goog.Promise(function(rs, rj) {\n resolve = rs;\n reject = rj;\n });\n return new goog.Promise.Resolver_(promise, resolve, reject);\n};\n\n\n/**\n * Adds callbacks that will operate on the result of the Promise, returning a\n * new child Promise.\n *\n * If the Promise is fulfilled, the `onFulfilled` callback will be invoked\n * with the fulfillment value as argument, and the child Promise will be\n * fulfilled with the return value of the callback. If the callback throws an\n * exception, the child Promise will be rejected with the thrown value instead.\n *\n * If the Promise is rejected, the `onRejected` callback will be invoked\n * with the rejection reason as argument, and the child Promise will be resolved\n * with the return value or rejected with the thrown value of the callback.\n *\n * @override\n */\ngoog.Promise.prototype.then = function(\n opt_onFulfilled, opt_onRejected, opt_context) {\n\n if (opt_onFulfilled != null) {\n goog.asserts.assertFunction(\n opt_onFulfilled, 'opt_onFulfilled should be a function.');\n }\n if (opt_onRejected != null) {\n goog.asserts.assertFunction(\n opt_onRejected,\n 'opt_onRejected should be a function. Did you pass opt_context ' +\n 'as the second argument instead of the third?');\n }\n\n if (goog.Promise.LONG_STACK_TRACES) {\n this.addStackTrace_(new Error('then'));\n }\n\n return this.addChildPromise_(\n goog.isFunction(opt_onFulfilled) ? opt_onFulfilled : null,\n goog.isFunction(opt_onRejected) ? opt_onRejected : null, opt_context);\n};\ngoog.Thenable.addImplementation(goog.Promise);\n\n\n/**\n * Adds callbacks that will operate on the result of the Promise without\n * returning a child Promise (unlike \"then\").\n *\n * If the Promise is fulfilled, the `onFulfilled` callback will be invoked\n * with the fulfillment value as argument.\n *\n * If the Promise is rejected, the `onRejected` callback will be invoked\n * with the rejection reason as argument.\n *\n * @param {?(function(this:THIS, TYPE):?)=} opt_onFulfilled A\n * function that will be invoked with the fulfillment value if the Promise\n * is fulfilled.\n * @param {?(function(this:THIS, *): *)=} opt_onRejected A function that will\n * be invoked with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * with the default this.\n * @package\n * @template THIS\n */\ngoog.Promise.prototype.thenVoid = function(\n opt_onFulfilled, opt_onRejected, opt_context) {\n\n if (opt_onFulfilled != null) {\n goog.asserts.assertFunction(\n opt_onFulfilled, 'opt_onFulfilled should be a function.');\n }\n if (opt_onRejected != null) {\n goog.asserts.assertFunction(\n opt_onRejected,\n 'opt_onRejected should be a function. Did you pass opt_context ' +\n 'as the second argument instead of the third?');\n }\n\n if (goog.Promise.LONG_STACK_TRACES) {\n this.addStackTrace_(new Error('then'));\n }\n\n // Note: no default rejection handler is provided here as we need to\n // distinguish unhandled rejections.\n this.addCallbackEntry_(\n goog.Promise.getCallbackEntry_(\n opt_onFulfilled || goog.nullFunction, opt_onRejected || null,\n opt_context));\n};\n\n\n/**\n * Adds a callback that will be invoked when the Promise is settled (fulfilled\n * or rejected). The callback receives no argument, and no new child Promise is\n * created. This is useful for ensuring that cleanup takes place after certain\n * asynchronous operations. Callbacks added with `thenAlways` will be\n * executed in the same order with other calls to `then`,\n * `thenAlways`, or `thenCatch`.\n *\n * Since it does not produce a new child Promise, cancellation propagation is\n * not prevented by adding callbacks with `thenAlways`. A Promise that has\n * a cleanup handler added with `thenAlways` will be canceled if all of\n * its children created by `then` (or `thenCatch`) are canceled.\n * Additionally, since any rejections are not passed to the callback, it does\n * not stop the unhandled rejection handler from running.\n *\n * @param {function(this:THIS): void} onSettled A function that will be invoked\n * when the Promise is settled (fulfilled or rejected).\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * in the global scope.\n * @return {!goog.Promise<TYPE>} This Promise, for chaining additional calls.\n * @template THIS\n */\ngoog.Promise.prototype.thenAlways = function(onSettled, opt_context) {\n if (goog.Promise.LONG_STACK_TRACES) {\n this.addStackTrace_(new Error('thenAlways'));\n }\n\n var entry = goog.Promise.getCallbackEntry_(onSettled, onSettled, opt_context);\n entry.always = true;\n this.addCallbackEntry_(entry);\n return this;\n};\n\n\n/**\n * Adds a callback that will be invoked only if the Promise is rejected. This\n * is equivalent to `then(null, onRejected)`.\n *\n * @param {function(this:THIS, *): *} onRejected A function that will be\n * invoked with the rejection reason if this Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * in the global scope.\n * @return {!goog.Promise} A new Promise that will resolve either to the\n * value of this promise, or if this promise is rejected, the result of\n * `onRejected`. The returned Promise will reject if `onRejected` throws.\n * @template THIS\n */\ngoog.Promise.prototype.thenCatch = function(onRejected, opt_context) {\n if (goog.Promise.LONG_STACK_TRACES) {\n this.addStackTrace_(new Error('thenCatch'));\n }\n return this.addChildPromise_(null, onRejected, opt_context);\n};\n\n\n/**\n * Cancels the Promise if it is still pending by rejecting it with a cancel\n * Error. No action is performed if the Promise is already resolved.\n *\n * All child Promises of the canceled Promise will be rejected with the same\n * cancel error, as with normal Promise rejection. If the Promise to be canceled\n * is the only child of a pending Promise, the parent Promise will also be\n * canceled. Cancellation may propagate upward through multiple generations.\n *\n * @param {string=} opt_message An optional debugging message for describing the\n * cancellation reason.\n */\ngoog.Promise.prototype.cancel = function(opt_message) {\n if (this.state_ == goog.Promise.State_.PENDING) {\n // Instantiate Error object synchronously. This ensures Error::stack points\n // to the cancel() callsite.\n var err = new goog.Promise.CancellationError(opt_message);\n goog.async.run(function() {\n this.cancelInternal_(err);\n }, this);\n }\n};\n\n\n/**\n * Cancels this Promise with the given error.\n *\n * @param {!Error} err The cancellation error.\n * @private\n */\ngoog.Promise.prototype.cancelInternal_ = function(err) {\n if (this.state_ == goog.Promise.State_.PENDING) {\n if (this.parent_) {\n // Cancel the Promise and remove it from the parent's child list.\n this.parent_.cancelChild_(this, err);\n this.parent_ = null;\n } else {\n this.resolve_(goog.Promise.State_.REJECTED, err);\n }\n }\n};\n\n\n/**\n * Cancels a child Promise from the list of callback entries. If the Promise has\n * not already been resolved, reject it with a cancel error. If there are no\n * other children in the list of callback entries, propagate the cancellation\n * by canceling this Promise as well.\n *\n * @param {!goog.Promise} childPromise The Promise to cancel.\n * @param {!Error} err The cancel error to use for rejecting the Promise.\n * @private\n */\ngoog.Promise.prototype.cancelChild_ = function(childPromise, err) {\n if (!this.callbackEntries_) {\n return;\n }\n var childCount = 0;\n var childEntry = null;\n var beforeChildEntry = null;\n\n // Find the callback entry for the childPromise, and count whether there are\n // additional child Promises.\n for (var entry = this.callbackEntries_; entry; entry = entry.next) {\n if (!entry.always) {\n childCount++;\n if (entry.child == childPromise) {\n childEntry = entry;\n }\n if (childEntry && childCount > 1) {\n break;\n }\n }\n if (!childEntry) {\n beforeChildEntry = entry;\n }\n }\n\n // Can a child entry be missing?\n\n // If the child Promise was the only child, cancel this Promise as well.\n // Otherwise, reject only the child Promise with the cancel error.\n if (childEntry) {\n if (this.state_ == goog.Promise.State_.PENDING && childCount == 1) {\n this.cancelInternal_(err);\n } else {\n if (beforeChildEntry) {\n this.removeEntryAfter_(beforeChildEntry);\n } else {\n this.popEntry_();\n }\n\n this.executeCallback_(childEntry, goog.Promise.State_.REJECTED, err);\n }\n }\n};\n\n\n/**\n * Adds a callback entry to the current Promise, and schedules callback\n * execution if the Promise has already been settled.\n *\n * @param {goog.Promise.CallbackEntry_} callbackEntry Record containing\n * `onFulfilled` and `onRejected` callbacks to execute after\n * the Promise is settled.\n * @private\n */\ngoog.Promise.prototype.addCallbackEntry_ = function(callbackEntry) {\n if (!this.hasEntry_() && (this.state_ == goog.Promise.State_.FULFILLED ||\n this.state_ == goog.Promise.State_.REJECTED)) {\n this.scheduleCallbacks_();\n }\n this.queueEntry_(callbackEntry);\n};\n\n\n/**\n * Creates a child Promise and adds it to the callback entry list. The result of\n * the child Promise is determined by the state of the parent Promise and the\n * result of the `onFulfilled` or `onRejected` callbacks as\n * specified in the Promise resolution procedure.\n *\n * @see http://promisesaplus.com/#the__method\n *\n * @param {?function(this:THIS, TYPE):\n * (RESULT|goog.Promise<RESULT>|Thenable)} onFulfilled A callback that\n * will be invoked if the Promise is fulfilled, or null.\n * @param {?function(this:THIS, *): *} onRejected A callback that will be\n * invoked if the Promise is rejected, or null.\n * @param {THIS=} opt_context An optional execution context for the callbacks.\n * in the default calling context.\n * @return {!goog.Promise} The child Promise.\n * @template RESULT,THIS\n * @private\n */\ngoog.Promise.prototype.addChildPromise_ = function(\n onFulfilled, onRejected, opt_context) {\n\n /** @type {goog.Promise.CallbackEntry_} */\n var callbackEntry = goog.Promise.getCallbackEntry_(null, null, null);\n\n callbackEntry.child = new goog.Promise(function(resolve, reject) {\n // Invoke onFulfilled, or resolve with the parent's value if absent.\n callbackEntry.onFulfilled = onFulfilled ? function(value) {\n try {\n var result = onFulfilled.call(opt_context, value);\n resolve(result);\n } catch (err) {\n reject(err);\n }\n } : resolve;\n\n // Invoke onRejected, or reject with the parent's reason if absent.\n callbackEntry.onRejected = onRejected ? function(reason) {\n try {\n var result = onRejected.call(opt_context, reason);\n if (result === undefined &&\n reason instanceof goog.Promise.CancellationError) {\n // Propagate cancellation to children if no other result is returned.\n reject(reason);\n } else {\n resolve(result);\n }\n } catch (err) {\n reject(err);\n }\n } : reject;\n });\n\n callbackEntry.child.parent_ = this;\n this.addCallbackEntry_(callbackEntry);\n return callbackEntry.child;\n};\n\n\n/**\n * Unblocks the Promise and fulfills it with the given value.\n *\n * @param {TYPE} value\n * @private\n */\ngoog.Promise.prototype.unblockAndFulfill_ = function(value) {\n goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED);\n this.state_ = goog.Promise.State_.PENDING;\n this.resolve_(goog.Promise.State_.FULFILLED, value);\n};\n\n\n/**\n * Unblocks the Promise and rejects it with the given rejection reason.\n *\n * @param {*} reason\n * @private\n */\ngoog.Promise.prototype.unblockAndReject_ = function(reason) {\n goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED);\n this.state_ = goog.Promise.State_.PENDING;\n this.resolve_(goog.Promise.State_.REJECTED, reason);\n};\n\n\n/**\n * Attempts to resolve a Promise with a given resolution state and value. This\n * is a no-op if the given Promise has already been resolved.\n *\n * If the given result is a Thenable (such as another Promise), the Promise will\n * be settled with the same state and result as the Thenable once it is itself\n * settled.\n *\n * If the given result is not a Thenable, the Promise will be settled (fulfilled\n * or rejected) with that result based on the given state.\n *\n * @see http://promisesaplus.com/#the_promise_resolution_procedure\n *\n * @param {goog.Promise.State_} state\n * @param {*} x The result to apply to the Promise.\n * @private\n */\ngoog.Promise.prototype.resolve_ = function(state, x) {\n if (this.state_ != goog.Promise.State_.PENDING) {\n return;\n }\n\n if (this === x) {\n state = goog.Promise.State_.REJECTED;\n x = new TypeError('Promise cannot resolve to itself');\n }\n\n this.state_ = goog.Promise.State_.BLOCKED;\n var isThenable = goog.Promise.maybeThen_(\n x, this.unblockAndFulfill_, this.unblockAndReject_, this);\n if (isThenable) {\n return;\n }\n\n this.result_ = x;\n this.state_ = state;\n // Since we can no longer be canceled, remove link to parent, so that the\n // child promise does not keep the parent promise alive.\n this.parent_ = null;\n this.scheduleCallbacks_();\n\n if (state == goog.Promise.State_.REJECTED &&\n !(x instanceof goog.Promise.CancellationError)) {\n goog.Promise.addUnhandledRejection_(this, x);\n }\n};\n\n\n/**\n * Invokes the \"then\" method of an input value if that value is a Thenable. This\n * is a no-op if the value is not thenable.\n *\n * @param {?} value A potentially thenable value.\n * @param {!Function} onFulfilled\n * @param {!Function} onRejected\n * @param {?} context\n * @return {boolean} Whether the input value was thenable.\n * @private\n */\ngoog.Promise.maybeThen_ = function(value, onFulfilled, onRejected, context) {\n if (value instanceof goog.Promise) {\n value.thenVoid(onFulfilled, onRejected, context);\n return true;\n } else if (goog.Thenable.isImplementedBy(value)) {\n value = /** @type {!goog.Thenable} */ (value);\n value.then(onFulfilled, onRejected, context);\n return true;\n } else if (goog.isObject(value)) {\n const thenable = /** @type {!Thenable} */ (value);\n try {\n var then = thenable.then;\n if (goog.isFunction(then)) {\n goog.Promise.tryThen_(thenable, then, onFulfilled, onRejected, context);\n return true;\n }\n } catch (e) {\n onRejected.call(context, e);\n return true;\n }\n }\n\n return false;\n};\n\n\n/**\n * Attempts to call the `then` method on an object in the hopes that it is\n * a Promise-compatible instance. This allows interoperation between different\n * Promise implementations, however a non-compliant object may cause a Promise\n * to hang indefinitely. If the `then` method throws an exception, the\n * dependent Promise will be rejected with the thrown value.\n *\n * @see http://promisesaplus.com/#point-70\n *\n * @param {Thenable} thenable An object with a `then` method that may be\n * compatible with the Promise/A+ specification.\n * @param {!Function} then The `then` method of the Thenable object.\n * @param {!Function} onFulfilled\n * @param {!Function} onRejected\n * @param {*} context\n * @private\n */\ngoog.Promise.tryThen_ = function(\n thenable, then, onFulfilled, onRejected, context) {\n\n var called = false;\n var resolve = function(value) {\n if (!called) {\n called = true;\n onFulfilled.call(context, value);\n }\n };\n\n var reject = function(reason) {\n if (!called) {\n called = true;\n onRejected.call(context, reason);\n }\n };\n\n try {\n then.call(thenable, resolve, reject);\n } catch (e) {\n reject(e);\n }\n};\n\n\n/**\n * Executes the pending callbacks of a settled Promise after a timeout.\n *\n * Section 2.2.4 of the Promises/A+ specification requires that Promise\n * callbacks must only be invoked from a call stack that only contains Promise\n * implementation code, which we accomplish by invoking callback execution after\n * a timeout. If `startExecution_` is called multiple times for the same\n * Promise, the callback chain will be evaluated only once. Additional callbacks\n * may be added during the evaluation phase, and will be executed in the same\n * event loop.\n *\n * All Promises added to the waiting list during the same browser event loop\n * will be executed in one batch to avoid using a separate timeout per Promise.\n *\n * @private\n */\ngoog.Promise.prototype.scheduleCallbacks_ = function() {\n if (!this.executing_) {\n this.executing_ = true;\n goog.async.run(this.executeCallbacks_, this);\n }\n};\n\n\n/**\n * @return {boolean} Whether there are any pending callbacks queued.\n * @private\n */\ngoog.Promise.prototype.hasEntry_ = function() {\n return !!this.callbackEntries_;\n};\n\n\n/**\n * @param {goog.Promise.CallbackEntry_} entry\n * @private\n */\ngoog.Promise.prototype.queueEntry_ = function(entry) {\n goog.asserts.assert(entry.onFulfilled != null);\n\n if (this.callbackEntriesTail_) {\n this.callbackEntriesTail_.next = entry;\n this.callbackEntriesTail_ = entry;\n } else {\n // It the work queue was empty set the head too.\n this.callbackEntries_ = entry;\n this.callbackEntriesTail_ = entry;\n }\n};\n\n\n/**\n * @return {goog.Promise.CallbackEntry_} entry\n * @private\n */\ngoog.Promise.prototype.popEntry_ = function() {\n var entry = null;\n if (this.callbackEntries_) {\n entry = this.callbackEntries_;\n this.callbackEntries_ = entry.next;\n entry.next = null;\n }\n // It the work queue is empty clear the tail too.\n if (!this.callbackEntries_) {\n this.callbackEntriesTail_ = null;\n }\n\n if (entry != null) {\n goog.asserts.assert(entry.onFulfilled != null);\n }\n return entry;\n};\n\n\n/**\n * @param {goog.Promise.CallbackEntry_} previous\n * @private\n */\ngoog.Promise.prototype.removeEntryAfter_ = function(previous) {\n goog.asserts.assert(this.callbackEntries_);\n goog.asserts.assert(previous != null);\n // If the last entry is being removed, update the tail\n if (previous.next == this.callbackEntriesTail_) {\n this.callbackEntriesTail_ = previous;\n }\n\n previous.next = previous.next.next;\n};\n\n\n/**\n * Executes all pending callbacks for this Promise.\n *\n * @private\n */\ngoog.Promise.prototype.executeCallbacks_ = function() {\n var entry = null;\n while (entry = this.popEntry_()) {\n if (goog.Promise.LONG_STACK_TRACES) {\n this.currentStep_++;\n }\n this.executeCallback_(entry, this.state_, this.result_);\n }\n this.executing_ = false;\n};\n\n\n/**\n * Executes a pending callback for this Promise. Invokes an `onFulfilled`\n * or `onRejected` callback based on the settled state of the Promise.\n *\n * @param {!goog.Promise.CallbackEntry_} callbackEntry An entry containing the\n * onFulfilled and/or onRejected callbacks for this step.\n * @param {goog.Promise.State_} state The resolution status of the Promise,\n * either FULFILLED or REJECTED.\n * @param {*} result The settled result of the Promise.\n * @private\n */\ngoog.Promise.prototype.executeCallback_ = function(\n callbackEntry, state, result) {\n // Cancel an unhandled rejection if the then/thenVoid call had an onRejected.\n if (state == goog.Promise.State_.REJECTED && callbackEntry.onRejected &&\n !callbackEntry.always) {\n this.removeUnhandledRejection_();\n }\n\n if (callbackEntry.child) {\n // When the parent is settled, the child no longer needs to hold on to it,\n // as the parent can no longer be canceled.\n callbackEntry.child.parent_ = null;\n goog.Promise.invokeCallback_(callbackEntry, state, result);\n } else {\n // Callbacks created with thenAlways or thenVoid do not have the rejection\n // handling code normally set up in the child Promise.\n try {\n callbackEntry.always ?\n callbackEntry.onFulfilled.call(callbackEntry.context) :\n goog.Promise.invokeCallback_(callbackEntry, state, result);\n } catch (err) {\n goog.Promise.handleRejection_.call(null, err);\n }\n }\n goog.Promise.returnEntry_(callbackEntry);\n};\n\n\n/**\n * Executes the onFulfilled or onRejected callback for a callbackEntry.\n *\n * @param {!goog.Promise.CallbackEntry_} callbackEntry\n * @param {goog.Promise.State_} state\n * @param {*} result\n * @private\n */\ngoog.Promise.invokeCallback_ = function(callbackEntry, state, result) {\n if (state == goog.Promise.State_.FULFILLED) {\n callbackEntry.onFulfilled.call(callbackEntry.context, result);\n } else if (callbackEntry.onRejected) {\n callbackEntry.onRejected.call(callbackEntry.context, result);\n }\n};\n\n\n/**\n * Records a stack trace entry for functions that call `then` or the\n * Promise constructor. May be disabled by unsetting `LONG_STACK_TRACES`.\n *\n * @param {!Error} err An Error object created by the calling function for\n * providing a stack trace.\n * @private\n */\ngoog.Promise.prototype.addStackTrace_ = function(err) {\n if (goog.Promise.LONG_STACK_TRACES && typeof err.stack === 'string') {\n // Extract the third line of the stack trace, which is the entry for the\n // user function that called into Promise code.\n var trace = err.stack.split('\\n', 4)[3];\n var message = err.message;\n\n // Pad the message to align the traces.\n message += Array(11 - message.length).join(' ');\n this.stack_.push(message + trace);\n }\n};\n\n\n/**\n * Adds extra stack trace information to an exception for the list of\n * asynchronous `then` calls that have been run for this Promise. Stack\n * trace information is recorded in {@see #addStackTrace_}, and appended to\n * rethrown errors when `LONG_STACK_TRACES` is enabled.\n *\n * @param {?} err An unhandled exception captured during callback execution.\n * @private\n */\ngoog.Promise.prototype.appendLongStack_ = function(err) {\n if (goog.Promise.LONG_STACK_TRACES && err && typeof err.stack === 'string' &&\n this.stack_.length) {\n var longTrace = ['Promise trace:'];\n\n for (var promise = this; promise; promise = promise.parent_) {\n for (var i = this.currentStep_; i >= 0; i--) {\n longTrace.push(promise.stack_[i]);\n }\n longTrace.push(\n 'Value: ' +\n '[' + (promise.state_ == goog.Promise.State_.REJECTED ? 'REJECTED' :\n 'FULFILLED') +\n '] ' +\n '<' + String(promise.result_) + '>');\n }\n err.stack += '\\n\\n' + longTrace.join('\\n');\n }\n};\n\n\n/**\n * Marks this rejected Promise as having being handled. Also marks any parent\n * Promises in the rejected state as handled. The rejection handler will no\n * longer be invoked for this Promise (if it has not been called already).\n *\n * @private\n */\ngoog.Promise.prototype.removeUnhandledRejection_ = function() {\n if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {\n for (var p = this; p && p.unhandledRejectionId_; p = p.parent_) {\n goog.global.clearTimeout(p.unhandledRejectionId_);\n p.unhandledRejectionId_ = 0;\n }\n } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {\n for (var p = this; p && p.hadUnhandledRejection_; p = p.parent_) {\n p.hadUnhandledRejection_ = false;\n }\n }\n};\n\n\n/**\n * Marks this rejected Promise as unhandled. If no `onRejected` callback\n * is called for this Promise before the `UNHANDLED_REJECTION_DELAY`\n * expires, the reason will be passed to the unhandled rejection handler. The\n * handler typically rethrows the rejection reason so that it becomes visible in\n * the developer console.\n *\n * @param {!goog.Promise} promise The rejected Promise.\n * @param {*} reason The Promise rejection reason.\n * @private\n */\ngoog.Promise.addUnhandledRejection_ = function(promise, reason) {\n if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) {\n promise.unhandledRejectionId_ = goog.global.setTimeout(function() {\n promise.appendLongStack_(reason);\n goog.Promise.handleRejection_.call(null, reason);\n }, goog.Promise.UNHANDLED_REJECTION_DELAY);\n\n } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) {\n promise.hadUnhandledRejection_ = true;\n goog.async.run(function() {\n if (promise.hadUnhandledRejection_) {\n promise.appendLongStack_(reason);\n goog.Promise.handleRejection_.call(null, reason);\n }\n });\n }\n};\n\n\n/**\n * A method that is invoked with the rejection reasons for Promises that are\n * rejected but have no `onRejected` callbacks registered yet.\n * @type {function(*)}\n * @private\n */\ngoog.Promise.handleRejection_ = goog.async.throwException;\n\n\n/**\n * Sets a handler that will be called with reasons from unhandled rejected\n * Promises. If the rejected Promise (or one of its descendants) has an\n * `onRejected` callback registered, the rejection will be considered\n * handled, and the rejection handler will not be called.\n *\n * By default, unhandled rejections are rethrown so that the error may be\n * captured by the developer console or a `window.onerror` handler.\n *\n * @param {function(*)} handler A function that will be called with reasons from\n * rejected Promises. Defaults to `goog.async.throwException`.\n */\ngoog.Promise.setUnhandledRejectionHandler = function(handler) {\n goog.Promise.handleRejection_ = handler;\n};\n\n\n\n/**\n * Error used as a rejection reason for canceled Promises.\n *\n * @param {string=} opt_message\n * @constructor\n * @extends {goog.debug.Error}\n * @final\n */\ngoog.Promise.CancellationError = function(opt_message) {\n goog.Promise.CancellationError.base(this, 'constructor', opt_message);\n};\ngoog.inherits(goog.Promise.CancellationError, goog.debug.Error);\n\n\n/** @override */\ngoog.Promise.CancellationError.prototype.name = 'cancel';\n\n\n\n/**\n * Internal implementation of the resolver interface.\n *\n * @param {!goog.Promise<TYPE>} promise\n * @param {function((TYPE|goog.Promise<TYPE>|Thenable)=)} resolve\n * @param {function(*=): void} reject\n * @implements {goog.promise.Resolver<TYPE>}\n * @final @struct\n * @constructor\n * @private\n * @template TYPE\n */\ngoog.Promise.Resolver_ = function(promise, resolve, reject) {\n /** @const */\n this.promise = promise;\n\n /** @const */\n this.resolve = resolve;\n\n /** @const */\n this.reject = reject;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements the disposable interface. The dispose method is used\n * to clean up references and resources.\n */\n\n\ngoog.provide('goog.Disposable');\ngoog.provide('goog.dispose');\ngoog.provide('goog.disposeAll');\n\ngoog.require('goog.disposable.IDisposable');\n\n\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 /**\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 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 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 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 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 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 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 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 if (obj && typeof obj.isDisposed == 'function') {\n return obj.isDisposed();\n }\n return false;\n};\n\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 */\ngoog.dispose = function(obj) {\n if (obj && typeof obj.dispose == 'function') {\n obj.dispose();\n }\n};\n\n\n/**\n * Calls `dispose` on each member of the list that supports it. (If the\n * member is an ArrayLike, then `goog.disposeAll()` will be called\n * recursively on each of its members.) If the member is not an object with a\n * `dispose()` method, then it is ignored.\n * @param {...*} var_args The list.\n */\ngoog.disposeAll = function(var_args) {\n for (var i = 0, len = arguments.length; i < len; ++i) {\n var disposable = arguments[i];\n if (goog.isArrayLike(disposable)) {\n goog.disposeAll.apply(null, disposable);\n } else {\n goog.dispose(disposable);\n }\n }\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Logging and debugging utilities.\n *\n * @see ../demos/debug.html\n */\n\ngoog.provide('goog.debug');\n\ngoog.require('goog.array');\ngoog.require('goog.debug.errorcontext');\ngoog.require('goog.userAgent');\n\n\n/** @define {boolean} Whether logging should be enabled. */\ngoog.debug.LOGGING_ENABLED =\n goog.define('goog.debug.LOGGING_ENABLED', goog.DEBUG);\n\n\n/** @define {boolean} Whether to force \"sloppy\" stack building. */\ngoog.debug.FORCE_SLOPPY_STACKS =\n goog.define('goog.debug.FORCE_SLOPPY_STACKS', false);\n\n\n/**\n * Catches onerror events fired by windows and similar objects.\n * @param {function(Object)} logFunc The function to call with the error\n * information.\n * @param {boolean=} opt_cancel Whether to stop the error from reaching the\n * browser.\n * @param {Object=} opt_target Object that fires onerror events.\n * @suppress {strictMissingProperties} onerror is not defined as a property\n * on Object.\n */\ngoog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) {\n var target = opt_target || goog.global;\n var oldErrorHandler = target.onerror;\n var retVal = !!opt_cancel;\n\n // Chrome interprets onerror return value backwards (http://crbug.com/92062)\n // until it was fixed in webkit revision r94061 (Webkit 535.3). This\n // workaround still needs to be skipped in Safari after the webkit change\n // gets pushed out in Safari.\n // See https://bugs.webkit.org/show_bug.cgi?id=67119\n if (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('535.3')) {\n retVal = !retVal;\n }\n\n /**\n * New onerror handler for this target. This onerror handler follows the spec\n * according to\n * http://www.whatwg.org/specs/web-apps/current-work/#runtime-script-errors\n * The spec was changed in August 2013 to support receiving column information\n * and an error object for all scripts on the same origin or cross origin\n * scripts with the proper headers. See\n * https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror\n *\n * @param {string} message The error message. For cross-origin errors, this\n * will be scrubbed to just \"Script error.\". For new browsers that have\n * updated to follow the latest spec, errors that come from origins that\n * have proper cross origin headers will not be scrubbed.\n * @param {string} url The URL of the script that caused the error. The URL\n * will be scrubbed to \"\" for cross origin scripts unless the script has\n * proper cross origin headers and the browser has updated to the latest\n * spec.\n * @param {number} line The line number in the script that the error\n * occurred on.\n * @param {number=} opt_col The optional column number that the error\n * occurred on. Only browsers that have updated to the latest spec will\n * include this.\n * @param {Error=} opt_error The optional actual error object for this\n * error that should include the stack. Only browsers that have updated\n * to the latest spec will inlude this parameter.\n * @return {boolean} Whether to prevent the error from reaching the browser.\n */\n target.onerror = function(message, url, line, opt_col, opt_error) {\n if (oldErrorHandler) {\n oldErrorHandler(message, url, line, opt_col, opt_error);\n }\n logFunc({\n message: message,\n fileName: url,\n line: line,\n lineNumber: line,\n col: opt_col,\n error: opt_error\n });\n return retVal;\n };\n};\n\n\n/**\n * Creates a string representing an object and all its properties.\n * @param {Object|null|undefined} obj Object to expose.\n * @param {boolean=} opt_showFn Show the functions as well as the properties,\n * default is false.\n * @return {string} The string representation of `obj`.\n */\ngoog.debug.expose = function(obj, opt_showFn) {\n if (typeof obj == 'undefined') {\n return 'undefined';\n }\n if (obj == null) {\n return 'NULL';\n }\n var str = [];\n\n for (var x in obj) {\n if (!opt_showFn && goog.isFunction(obj[x])) {\n continue;\n }\n var s = x + ' = ';\n\n try {\n s += obj[x];\n } catch (e) {\n s += '*** ' + e + ' ***';\n }\n str.push(s);\n }\n return str.join('\\n');\n};\n\n\n/**\n * Creates a string representing a given primitive or object, and for an\n * object, all its properties and nested objects. NOTE: The output will include\n * Uids on all objects that were exposed. Any added Uids will be removed before\n * returning.\n * @param {*} obj Object to expose.\n * @param {boolean=} opt_showFn Also show properties that are functions (by\n * default, functions are omitted).\n * @return {string} A string representation of `obj`.\n */\ngoog.debug.deepExpose = function(obj, opt_showFn) {\n var str = [];\n\n // Track any objects where deepExpose added a Uid, so they can be cleaned up\n // before return. We do this globally, rather than only on ancestors so that\n // if the same object appears in the output, you can see it.\n var uidsToCleanup = [];\n var ancestorUids = {};\n\n var helper = function(obj, space) {\n var nestspace = space + ' ';\n\n var indentMultiline = function(str) {\n return str.replace(/\\n/g, '\\n' + space);\n };\n\n\n try {\n if (obj === undefined) {\n str.push('undefined');\n } else if (obj === null) {\n str.push('NULL');\n } else if (typeof obj === 'string') {\n str.push('\"' + indentMultiline(obj) + '\"');\n } else if (goog.isFunction(obj)) {\n str.push(indentMultiline(String(obj)));\n } else if (goog.isObject(obj)) {\n // Add a Uid if needed. The struct calls implicitly adds them.\n if (!goog.hasUid(obj)) {\n uidsToCleanup.push(obj);\n }\n var uid = goog.getUid(obj);\n if (ancestorUids[uid]) {\n str.push('*** reference loop detected (id=' + uid + ') ***');\n } else {\n ancestorUids[uid] = true;\n str.push('{');\n for (var x in obj) {\n if (!opt_showFn && goog.isFunction(obj[x])) {\n continue;\n }\n str.push('\\n');\n str.push(nestspace);\n str.push(x + ' = ');\n helper(obj[x], nestspace);\n }\n str.push('\\n' + space + '}');\n delete ancestorUids[uid];\n }\n } else {\n str.push(obj);\n }\n } catch (e) {\n str.push('*** ' + e + ' ***');\n }\n };\n\n helper(obj, '');\n\n // Cleanup any Uids that were added by the deepExpose.\n for (var i = 0; i < uidsToCleanup.length; i++) {\n goog.removeUid(uidsToCleanup[i]);\n }\n\n return str.join('');\n};\n\n\n/**\n * Recursively outputs a nested array as a string.\n * @param {Array<?>} arr The array.\n * @return {string} String representing nested array.\n */\ngoog.debug.exposeArray = function(arr) {\n var str = [];\n for (var i = 0; i < arr.length; i++) {\n if (Array.isArray(arr[i])) {\n str.push(goog.debug.exposeArray(arr[i]));\n } else {\n str.push(arr[i]);\n }\n }\n return '[ ' + str.join(', ') + ' ]';\n};\n\n\n/**\n * Normalizes the error/exception object between browsers.\n * @param {*} err Raw error object.\n * @return {{\n * message: (?|undefined),\n * name: (?|undefined),\n * lineNumber: (?|undefined),\n * fileName: (?|undefined),\n * stack: (?|undefined)\n * }} Normalized error object.\n * @suppress {strictMissingProperties} properties not defined on err\n */\ngoog.debug.normalizeErrorObject = function(err) {\n var href = goog.getObjectByName('window.location.href');\n if (err == null) {\n err = 'Unknown Error of type \"null/undefined\"';\n }\n if (typeof err === 'string') {\n return {\n 'message': err,\n 'name': 'Unknown error',\n 'lineNumber': 'Not available',\n 'fileName': href,\n 'stack': 'Not available'\n };\n }\n\n var lineNumber, fileName;\n var threwError = false;\n\n try {\n lineNumber = err.lineNumber || err.line || 'Not available';\n } catch (e) {\n // Firefox 2 sometimes throws an error when accessing 'lineNumber':\n // Message: Permission denied to get property UnnamedClass.lineNumber\n lineNumber = 'Not available';\n threwError = true;\n }\n\n try {\n fileName = err.fileName || err.filename || err.sourceURL ||\n // $googDebugFname may be set before a call to eval to set the filename\n // that the eval is supposed to present.\n goog.global['$googDebugFname'] || href;\n } catch (e) {\n // Firefox 2 may also throw an error when accessing 'filename'.\n fileName = 'Not available';\n threwError = true;\n }\n\n // The IE Error object contains only the name and the message.\n // The Safari Error object uses the line and sourceURL fields.\n if (threwError || !err.lineNumber || !err.fileName || !err.stack ||\n !err.message || !err.name) {\n var message = err.message;\n if (message == null) {\n if (err.constructor && err.constructor instanceof Function) {\n var ctorName = err.constructor.name ?\n err.constructor.name :\n goog.debug.getFunctionName(err.constructor);\n message = 'Unknown Error of type \"' + ctorName + '\"';\n } else {\n message = 'Unknown Error of unknown type';\n }\n }\n return {\n 'message': message,\n 'name': err.name || 'UnknownError',\n 'lineNumber': lineNumber,\n 'fileName': fileName,\n 'stack': err.stack || 'Not available'\n };\n }\n\n // Standards error object\n // Typed !Object. Should be a subtype of the return type, but it's not.\n return /** @type {?} */ (err);\n};\n\n\n/**\n * Converts an object to an Error using the object's toString if it's not\n * already an Error, adds a stacktrace if there isn't one, and optionally adds\n * an extra message.\n * @param {*} err The original thrown error, object, or string.\n * @param {string=} opt_message optional additional message to add to the\n * error.\n * @return {!Error} If err is an Error, it is enhanced and returned. Otherwise,\n * it is converted to an Error which is enhanced and returned.\n */\ngoog.debug.enhanceError = function(err, opt_message) {\n var error;\n if (!(err instanceof Error)) {\n error = Error(err);\n if (Error.captureStackTrace) {\n // Trim this function off the call stack, if we can.\n Error.captureStackTrace(error, goog.debug.enhanceError);\n }\n } else {\n error = err;\n }\n\n if (!error.stack) {\n error.stack = goog.debug.getStacktrace(goog.debug.enhanceError);\n }\n if (opt_message) {\n // find the first unoccupied 'messageX' property\n var x = 0;\n while (error['message' + x]) {\n ++x;\n }\n error['message' + x] = String(opt_message);\n }\n return error;\n};\n\n\n/**\n * Converts an object to an Error using the object's toString if it's not\n * already an Error, adds a stacktrace if there isn't one, and optionally adds\n * context to the Error, which is reported by the closure error reporter.\n * @param {*} err The original thrown error, object, or string.\n * @param {!Object<string, string>=} opt_context Key-value context to add to the\n * Error.\n * @return {!Error} If err is an Error, it is enhanced and returned. Otherwise,\n * it is converted to an Error which is enhanced and returned.\n */\ngoog.debug.enhanceErrorWithContext = function(err, opt_context) {\n var error = goog.debug.enhanceError(err);\n if (opt_context) {\n for (var key in opt_context) {\n goog.debug.errorcontext.addErrorContext(error, key, opt_context[key]);\n }\n }\n return error;\n};\n\n\n/**\n * Gets the current stack trace. Simple and iterative - doesn't worry about\n * catching circular references or getting the args.\n * @param {number=} opt_depth Optional maximum depth to trace back to.\n * @return {string} A string with the function names of all functions in the\n * stack, separated by \\n.\n * @suppress {es5Strict}\n */\ngoog.debug.getStacktraceSimple = function(opt_depth) {\n if (!goog.debug.FORCE_SLOPPY_STACKS) {\n var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple);\n if (stack) {\n return stack;\n }\n // NOTE: browsers that have strict mode support also have native \"stack\"\n // properties. Fall-through for legacy browser support.\n }\n\n var sb = [];\n var fn = arguments.callee.caller;\n var depth = 0;\n\n while (fn && (!opt_depth || depth < opt_depth)) {\n sb.push(goog.debug.getFunctionName(fn));\n sb.push('()\\n');\n\n try {\n fn = fn.caller;\n } catch (e) {\n sb.push('[exception trying to get caller]\\n');\n break;\n }\n depth++;\n if (depth >= goog.debug.MAX_STACK_DEPTH) {\n sb.push('[...long stack...]');\n break;\n }\n }\n if (opt_depth && depth >= opt_depth) {\n sb.push('[...reached max depth limit...]');\n } else {\n sb.push('[end]');\n }\n\n return sb.join('');\n};\n\n\n/**\n * Max length of stack to try and output\n * @type {number}\n */\ngoog.debug.MAX_STACK_DEPTH = 50;\n\n\n/**\n * @param {Function} fn The function to start getting the trace from.\n * @return {?string}\n * @private\n */\ngoog.debug.getNativeStackTrace_ = function(fn) {\n var tempErr = new Error();\n if (Error.captureStackTrace) {\n Error.captureStackTrace(tempErr, fn);\n return String(tempErr.stack);\n } else {\n // IE10, only adds stack traces when an exception is thrown.\n try {\n throw tempErr;\n } catch (e) {\n tempErr = e;\n }\n var stack = tempErr.stack;\n if (stack) {\n return String(stack);\n }\n }\n return null;\n};\n\n\n/**\n * Gets the current stack trace, either starting from the caller or starting\n * from a specified function that's currently on the call stack.\n * @param {?Function=} fn If provided, when collecting the stack trace all\n * frames above the topmost call to this function, including that call,\n * will be left out of the stack trace.\n * @return {string} Stack trace.\n * @suppress {es5Strict}\n */\ngoog.debug.getStacktrace = function(fn) {\n var stack;\n if (!goog.debug.FORCE_SLOPPY_STACKS) {\n // Try to get the stack trace from the environment if it is available.\n var contextFn = fn || goog.debug.getStacktrace;\n stack = goog.debug.getNativeStackTrace_(contextFn);\n }\n if (!stack) {\n // NOTE: browsers that have strict mode support also have native \"stack\"\n // properties. This function will throw in strict mode.\n stack = goog.debug.getStacktraceHelper_(fn || arguments.callee.caller, []);\n }\n return stack;\n};\n\n\n/**\n * Private helper for getStacktrace().\n * @param {?Function} fn If provided, when collecting the stack trace all\n * frames above the topmost call to this function, including that call,\n * will be left out of the stack trace.\n * @param {Array<!Function>} visited List of functions visited so far.\n * @return {string} Stack trace starting from function fn.\n * @suppress {es5Strict}\n * @private\n */\ngoog.debug.getStacktraceHelper_ = function(fn, visited) {\n var sb = [];\n\n // Circular reference, certain functions like bind seem to cause a recursive\n // loop so we need to catch circular references\n if (goog.array.contains(visited, fn)) {\n sb.push('[...circular reference...]');\n\n // Traverse the call stack until function not found or max depth is reached\n } else if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) {\n sb.push(goog.debug.getFunctionName(fn) + '(');\n var args = fn.arguments;\n // Args may be null for some special functions such as host objects or eval.\n for (var i = 0; args && i < args.length; i++) {\n if (i > 0) {\n sb.push(', ');\n }\n var argDesc;\n var arg = args[i];\n switch (typeof arg) {\n case 'object':\n argDesc = arg ? 'object' : 'null';\n break;\n\n case 'string':\n argDesc = arg;\n break;\n\n case 'number':\n argDesc = String(arg);\n break;\n\n case 'boolean':\n argDesc = arg ? 'true' : 'false';\n break;\n\n case 'function':\n argDesc = goog.debug.getFunctionName(arg);\n argDesc = argDesc ? argDesc : '[fn]';\n break;\n\n case 'undefined':\n default:\n argDesc = typeof arg;\n break;\n }\n\n if (argDesc.length > 40) {\n argDesc = argDesc.substr(0, 40) + '...';\n }\n sb.push(argDesc);\n }\n visited.push(fn);\n sb.push(')\\n');\n\n try {\n sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited));\n } catch (e) {\n sb.push('[exception trying to get caller]\\n');\n }\n\n } else if (fn) {\n sb.push('[...long stack...]');\n } else {\n sb.push('[end]');\n }\n return sb.join('');\n};\n\n\n/**\n * Gets a function name\n * @param {Function} fn Function to get name of.\n * @return {string} Function's name.\n */\ngoog.debug.getFunctionName = function(fn) {\n if (goog.debug.fnNameCache_[fn]) {\n return goog.debug.fnNameCache_[fn];\n }\n\n // Heuristically determine function name based on code.\n var functionSource = String(fn);\n if (!goog.debug.fnNameCache_[functionSource]) {\n var matches = /function\\s+([^\\(]+)/m.exec(functionSource);\n if (matches) {\n var method = matches[1];\n goog.debug.fnNameCache_[functionSource] = method;\n } else {\n goog.debug.fnNameCache_[functionSource] = '[Anonymous]';\n }\n }\n\n return goog.debug.fnNameCache_[functionSource];\n};\n\n\n/**\n * Makes whitespace visible by replacing it with printable characters.\n * This is useful in finding diffrences between the expected and the actual\n * output strings of a testcase.\n * @param {string} string whose whitespace needs to be made visible.\n * @return {string} string whose whitespace is made visible.\n */\ngoog.debug.makeWhitespaceVisible = function(string) {\n return string.replace(/ /g, '[_]')\n .replace(/\\f/g, '[f]')\n .replace(/\\n/g, '[n]\\n')\n .replace(/\\r/g, '[r]')\n .replace(/\\t/g, '[t]');\n};\n\n\n/**\n * Returns the type of a value. If a constructor is passed, and a suitable\n * string cannot be found, 'unknown type name' will be returned.\n *\n * <p>Forked rather than moved from {@link goog.asserts.getType_}\n * to avoid adding a dependency to goog.asserts.\n * @param {*} value A constructor, object, or primitive.\n * @return {string} The best display name for the value, or 'unknown type name'.\n */\ngoog.debug.runtimeType = function(value) {\n if (value instanceof Function) {\n return value.displayName || value.name || 'unknown type name';\n } else if (value instanceof Object) {\n return /** @type {string} */ (value.constructor.displayName) ||\n value.constructor.name || Object.prototype.toString.call(value);\n } else {\n return value === null ? 'null' : typeof value;\n }\n};\n\n\n/**\n * Hash map for storing function names that have already been looked up.\n * @type {Object}\n * @private\n */\ngoog.debug.fnNameCache_ = {};\n\n\n/**\n * Private internal function to support goog.debug.freeze.\n * @param {T} arg\n * @return {T}\n * @template T\n * @private\n */\ngoog.debug.freezeInternal_ = goog.DEBUG && Object.freeze || function(arg) {\n return arg;\n};\n\n\n/**\n * Freezes the given object, but only in debug mode (and in browsers that\n * support it). Note that this is a shallow freeze, so for deeply nested\n * objects it must be called at every level to ensure deep immutability.\n * @param {T} arg\n * @return {T}\n * @template T\n */\ngoog.debug.freeze = function(arg) {\n // NOTE: this compiles to nothing, but hides the possible side effect of\n // freezeInternal_ from the compiler so that the entire call can be\n // removed if the result is not used.\n return {\n valueOf: function() {\n return goog.debug.freezeInternal_(arg);\n }\n }.valueOf();\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\n\ngoog.provide('goog.events.BrowserFeature');\n\ngoog.require('goog.userAgent');\ngoog.scope(function() {\n\n\n\n/**\n * Enum of browser capabilities.\n * @enum {boolean}\n */\ngoog.events.BrowserFeature = {\n /**\n * Whether the button attribute of the event is W3C compliant. False in\n * Internet Explorer prior to version 9; document-version dependent.\n */\n HAS_W3C_BUTTON:\n !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),\n\n /**\n * Whether the browser supports full W3C event model.\n */\n HAS_W3C_EVENT_SUPPORT:\n !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),\n\n /**\n * To prevent default in IE7-8 for certain keydown events we need set the\n * keyCode to -1.\n */\n SET_KEY_CODE_TO_PREVENT_DEFAULT:\n goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),\n\n /**\n * Whether the `navigator.onLine` property is supported.\n */\n HAS_NAVIGATOR_ONLINE_PROPERTY:\n !goog.userAgent.WEBKIT || goog.userAgent.isVersionOrHigher('528'),\n\n /**\n * Whether HTML5 network online/offline events are supported.\n */\n HAS_HTML5_NETWORK_EVENT_SUPPORT:\n goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9b') ||\n goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8') ||\n goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('9.5') ||\n goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('528'),\n\n /**\n * Whether HTML5 network events fire on document.body, or otherwise the\n * window.\n */\n HTML5_NETWORK_EVENTS_FIRE_ON_BODY:\n goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('8') ||\n goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),\n\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:\n ('MSPointerEvent' in goog.global &&\n !!(goog.global['navigator'] &&\n goog.global['navigator']['msPointerEnabled'])),\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 goog.global.addEventListener('test', goog.nullFunction, options);\n goog.global.removeEventListener('test', goog.nullFunction, options);\n } catch (e) {\n }\n\n return passive;\n })\n};\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 */\nfunction purify(fn) {\n return ({valueOf: fn}).valueOf();\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 base class for event objects.\n */\n\n\ngoog.provide('goog.events.Event');\ngoog.provide('goog.events.EventLike');\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 typedef for event like objects that are dispatchable via the\n * goog.events.dispatchEvent function. strings are treated as the type for a\n * goog.events.Event. Objects are treated as an extension of a new\n * goog.events.Event with the type property of the object being used as the type\n * of the Event.\n * @typedef {string|Object|goog.events.Event|goog.events.EventId}\n */\ngoog.events.EventLike;\n\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 /**\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 return this.propagationStopped_;\n};\n\n/**\n * Stops event propagation.\n */\ngoog.events.Event.prototype.stopPropagation = function() {\n this.propagationStopped_ = true;\n};\n\n\n/**\n * Prevents the default action, for example a link redirecting to a url.\n */\ngoog.events.Event.prototype.preventDefault = function() {\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 */\ngoog.events.Event.stopPropagation = function(e) {\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 */\ngoog.events.Event.preventDefault = function(e) {\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 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.BrowserFeature');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventType');\ngoog.require('goog.reflect');\ngoog.require('goog.userAgent');\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.USE_LAYER_XY_AS_OFFSET_XY =\n goog.define('goog.events.USE_LAYER_XY_AS_OFFSET_XY', false);\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 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/**\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};\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 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 */\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.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 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 this.pointerId = e.pointerId || 0;\n this.pointerType = goog.events.BrowserEvent.getPointerType_(e);\n this.state = e.state;\n this.event_ = e;\n if (e.defaultPrevented) {\n this.preventDefault();\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 if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) {\n if (this.type == 'click') {\n return button == goog.events.BrowserEvent.MouseButton.LEFT;\n } else {\n return !!(\n this.event_.button & goog.events.BrowserEvent.IE_BUTTON_MAP[button]);\n }\n } else {\n return this.event_.button == button;\n }\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 // Webkit does not ctrl+click to be a right-click, so we\n // normalize it to behave like Gecko and Opera.\n return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&\n !(goog.userAgent.WEBKIT && goog.userAgent.MAC && this.ctrlKey);\n};\n\n\n/**\n * @override\n */\ngoog.events.BrowserEvent.prototype.stopPropagation = function() {\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 goog.events.BrowserEvent.superClass_.preventDefault.call(this);\n var be = this.event_;\n if (!be.preventDefault) {\n be.returnValue = false;\n if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) {\n\n try {\n // Most keys can be prevented using returnValue. Some special keys\n // require setting the keyCode to -1 as well:\n //\n // In IE7:\n // F3, F5, F10, F11, Ctrl+P, Crtl+O, Ctrl+F (these are taken from IE6)\n //\n // In IE8:\n // Ctrl+P, Crtl+O, Ctrl+F (F1-F12 cannot be stopped through the event)\n //\n // We therefore do this for all function keys as well as when Ctrl key\n // is pressed.\n var VK_F1 = 112;\n var VK_F12 = 123;\n if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) {\n be.keyCode = -1;\n }\n } catch (ex) {\n // IE throws an 'access denied' exception when trying to change\n // keyCode in some situations (e.g. srcElement is input[type=file],\n // or srcElement is an anchor tag rewritten by parent's innerHTML).\n // Do nothing in this case.\n }\n }\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 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 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\n/**\n * @fileoverview Event Types.\n */\n\n\ngoog.provide('goog.events.EventType');\ngoog.provide('goog.events.MouseAsMouseEventType');\ngoog.provide('goog.events.MouseEvents');\ngoog.provide('goog.events.PointerAsMouseEventType');\ngoog.provide('goog.events.PointerAsTouchEventType');\ngoog.provide('goog.events.PointerFallbackEventType');\ngoog.provide('goog.events.PointerTouchFallbackEventType');\n\ngoog.require('goog.events.BrowserFeature');\ngoog.require('goog.userAgent');\n\n\n/**\n * Returns a prefixed event name for the current browser.\n * @param {string} eventName The name of the event.\n * @return {string} The prefixed event name.\n * @suppress {missingRequire|missingProvide}\n * @private\n */\ngoog.events.getVendorPrefixedName_ = function(eventName) {\n return goog.userAgent.WEBKIT ?\n 'webkit' + eventName :\n (goog.userAgent.OPERA ? 'o' + eventName.toLowerCase() :\n eventName.toLowerCase());\n};\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 /** @suppress {missingRequire} */\n ANIMATIONSTART: goog.events.getVendorPrefixedName_('AnimationStart'),\n /** @suppress {missingRequire} */\n ANIMATIONEND: goog.events.getVendorPrefixedName_('AnimationEnd'),\n /** @suppress {missingRequire} */\n ANIMATIONITERATION: goog.events.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 /** @suppress {missingRequire} */\n TRANSITIONEND: goog.events.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 // 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 // DOM Level 2 mutation events (deprecated).\n DOMSUBTREEMODIFIED: 'DOMSubtreeModified',\n DOMNODEINSERTED: 'DOMNodeInserted',\n DOMNODEREMOVED: 'DOMNodeRemoved',\n DOMNODEREMOVEDFROMDOCUMENT: 'DOMNodeRemovedFromDocument',\n DOMNODEINSERTEDINTODOCUMENT: 'DOMNodeInsertedIntoDocument',\n DOMATTRMODIFIED: 'DOMAttrModified',\n DOMCHARACTERDATAMODIFIED: 'DOMCharacterDataModified',\n\n // Print events.\n BEFOREPRINT: 'beforeprint',\n AFTERPRINT: 'afterprint',\n\n // Web app manifest events.\n BEFOREINSTALLPROMPT: 'beforeinstallprompt',\n APPINSTALLED: 'appinstalled'\n};\n\n\n/**\n * Returns one of the given pointer fallback event names in order of preference:\n * 1. pointerEventName\n * 2. msPointerEventName\n * 3. fallbackEventName\n * @param {string} pointerEventName\n * @param {string} msPointerEventName\n * @param {string} fallbackEventName\n * @return {string} The supported pointer or fallback (mouse or touch) event\n * name.\n * @private\n */\ngoog.events.getPointerFallbackEventName_ = function(\n pointerEventName, msPointerEventName, fallbackEventName) {\n if (goog.events.BrowserFeature.POINTER_EVENTS) {\n return pointerEventName;\n }\n if (goog.events.BrowserFeature.MSPOINTER_EVENTS) {\n return msPointerEventName;\n }\n return fallbackEventName;\n};\n\n\n/**\n * Constants for pointer event names that fall back to corresponding mouse event\n * names on unsupported platforms. These are intended to be drop-in replacements\n * for corresponding values in `goog.events.EventType`.\n * @enum {string}\n */\ngoog.events.PointerFallbackEventType = {\n POINTERDOWN: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERDOWN, goog.events.EventType.MSPOINTERDOWN,\n goog.events.EventType.MOUSEDOWN),\n POINTERUP: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERUP, goog.events.EventType.MSPOINTERUP,\n goog.events.EventType.MOUSEUP),\n POINTERCANCEL: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERCANCEL,\n goog.events.EventType.MSPOINTERCANCEL,\n // When falling back to mouse events, there is no MOUSECANCEL equivalent\n // of POINTERCANCEL. In this case POINTERUP already falls back to MOUSEUP\n // which represents both UP and CANCEL. POINTERCANCEL does not fall back\n // to MOUSEUP to prevent listening twice on the same event.\n goog.events.EventType.MOUSECANCEL),\n POINTERMOVE: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERMOVE, goog.events.EventType.MSPOINTERMOVE,\n goog.events.EventType.MOUSEMOVE),\n POINTEROVER: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTEROVER, goog.events.EventType.MSPOINTEROVER,\n goog.events.EventType.MOUSEOVER),\n POINTEROUT: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTEROUT, goog.events.EventType.MSPOINTEROUT,\n goog.events.EventType.MOUSEOUT),\n POINTERENTER: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERENTER, goog.events.EventType.MSPOINTERENTER,\n goog.events.EventType.MOUSEENTER),\n POINTERLEAVE: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERLEAVE, goog.events.EventType.MSPOINTERLEAVE,\n goog.events.EventType.MOUSELEAVE)\n};\n\n\n/**\n * Constants for pointer event names that fall back to corresponding touch event\n * names on unsupported platforms. These are intended to be drop-in replacements\n * for corresponding values in `goog.events.EventType`.\n * @enum {string}\n */\ngoog.events.PointerTouchFallbackEventType = {\n POINTERDOWN: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERDOWN, goog.events.EventType.MSPOINTERDOWN,\n goog.events.EventType.TOUCHSTART),\n POINTERUP: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERUP, goog.events.EventType.MSPOINTERUP,\n goog.events.EventType.TOUCHEND),\n POINTERCANCEL: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERCANCEL,\n goog.events.EventType.MSPOINTERCANCEL, goog.events.EventType.TOUCHCANCEL),\n POINTERMOVE: goog.events.getPointerFallbackEventName_(\n goog.events.EventType.POINTERMOVE, goog.events.EventType.MSPOINTERMOVE,\n goog.events.EventType.TOUCHMOVE)\n};\n\n\n/**\n * Mapping of mouse event names to underlying browser event names.\n * @typedef {{\n * MOUSEDOWN: string,\n * MOUSEUP: string,\n * MOUSECANCEL:string,\n * MOUSEMOVE:string,\n * MOUSEOVER:string,\n * MOUSEOUT:string,\n * MOUSEENTER:string,\n * MOUSELEAVE: string,\n * }}\n */\ngoog.events.MouseEvents;\n\n\n/**\n * An alias for `goog.events.EventType.MOUSE*` event types that is overridden by\n * corresponding `POINTER*` event types.\n * @const {!goog.events.MouseEvents}\n */\ngoog.events.PointerAsMouseEventType = {\n MOUSEDOWN: goog.events.PointerFallbackEventType.POINTERDOWN,\n MOUSEUP: goog.events.PointerFallbackEventType.POINTERUP,\n MOUSECANCEL: goog.events.PointerFallbackEventType.POINTERCANCEL,\n MOUSEMOVE: goog.events.PointerFallbackEventType.POINTERMOVE,\n MOUSEOVER: goog.events.PointerFallbackEventType.POINTEROVER,\n MOUSEOUT: goog.events.PointerFallbackEventType.POINTEROUT,\n MOUSEENTER: goog.events.PointerFallbackEventType.POINTERENTER,\n MOUSELEAVE: goog.events.PointerFallbackEventType.POINTERLEAVE\n};\n\n\n/**\n * An alias for `goog.events.EventType.MOUSE*` event types that continue to use\n * mouse events.\n * @const {!goog.events.MouseEvents}\n */\ngoog.events.MouseAsMouseEventType = {\n MOUSEDOWN: goog.events.EventType.MOUSEDOWN,\n MOUSEUP: goog.events.EventType.MOUSEUP,\n MOUSECANCEL: goog.events.EventType.MOUSECANCEL,\n MOUSEMOVE: goog.events.EventType.MOUSEMOVE,\n MOUSEOVER: goog.events.EventType.MOUSEOVER,\n MOUSEOUT: goog.events.EventType.MOUSEOUT,\n MOUSEENTER: goog.events.EventType.MOUSEENTER,\n MOUSELEAVE: goog.events.EventType.MOUSELEAVE\n};\n\n\n/**\n * An alias for `goog.events.EventType.TOUCH*` event types that is overridden by\n * corresponding `POINTER*` event types.\n * @enum {string}\n */\ngoog.events.PointerAsTouchEventType = {\n TOUCHCANCEL: goog.events.PointerTouchFallbackEventType.POINTERCANCEL,\n TOUCHEND: goog.events.PointerTouchFallbackEventType.POINTERUP,\n TOUCHMOVE: goog.events.PointerTouchFallbackEventType.POINTERMOVE,\n TOUCHSTART: goog.events.PointerTouchFallbackEventType.POINTERDOWN\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');\ngoog.provide('goog.events.ListenableKey');\n\ngoog.forwardDeclare('goog.events.EventLike');\ngoog.forwardDeclare('goog.events.EventTarget');\n/** @suppress {extraRequire} */\ngoog.require('goog.events.EventId');\n\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 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 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;\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;\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;\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;\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;\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=} opt_type Type of event to remove, default is to\n * remove all types.\n * @return {number} Number of listeners removed.\n */\ngoog.events.Listenable.prototype.removeAllListeners;\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;\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;\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;\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;\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;\n\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 return ++goog.events.ListenableKey.counter_;\n};\n\n\n/**\n * The source event target.\n * @type {Object|goog.events.Listenable|goog.events.EventTarget}\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');\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 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 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');\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 /** @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 return this.typeCount_;\n};\n\n\n/**\n * @return {number} Total number of registered listeners.\n */\ngoog.events.ListenerMap.prototype.getListenerCount = function() {\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 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 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 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 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 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 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 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 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 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 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.forwardDeclare('goog.debug.ErrorHandler');\ngoog.forwardDeclare('goog.events.EventWrapper');\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');\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 */\ngoog.events.listen = function(src, type, listener, opt_options, opt_handler) {\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 */\ngoog.events.listen_ = function(\n src, type, listener, callOnce, opt_options, opt_handler) {\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 if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {\n if (goog.events.CAPTURE_SIMULATION_MODE ==\n goog.events.CaptureSimulationMode.OFF_AND_FAIL) {\n goog.asserts.fail('Can not register capture listener in IE8-.');\n return null;\n } else if (\n goog.events.CAPTURE_SIMULATION_MODE ==\n goog.events.CaptureSimulationMode.OFF_AND_SILENT) {\n return null;\n }\n }\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 proxy.src = src;\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 var proxyCallbackFunction = goog.events.handleBrowserEvent_;\n // Use a local var f to prevent one allocation.\n var f =\n goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) {\n return proxyCallbackFunction.call(f.src, f.listener, eventObject);\n } : function(eventObject) {\n var v = proxyCallbackFunction.call(f.src, f.listener, eventObject);\n // NOTE(chrishenry): In IE, we hack in a capture phase. However, if\n // there is inline event handler which tries to prevent default (for\n // example <a href=\"...\" onclick=\"return false\">...</a>) in a\n // descendant element, the prevent default will be overridden\n // by this listener if this listener were to return true. Hence, we\n // return undefined.\n if (!v) return v;\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 */\ngoog.events.listenOnce = function(\n src, type, listener, opt_options, opt_handler) {\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 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 */\ngoog.events.unlisten = function(src, type, listener, opt_options, opt_handler) {\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 */\ngoog.events.unlistenByKey = function(key) {\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 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 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 // 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 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 */\ngoog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {\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 */\ngoog.events.hasListener = function(obj, opt_type, opt_capture) {\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 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 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 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 /** @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 */\ngoog.events.fireListener = function(listener, eventObject) {\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 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 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 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 if (listener.removed) {\n return true;\n }\n\n // Synthesize event propagation if the browser does not support W3C\n // event model.\n if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {\n var ieEvent = opt_evt ||\n /** @type {Event} */ (goog.getObjectByName('window.event'));\n var evt = new goog.events.BrowserEvent(ieEvent, this);\n /** @type {*} */\n var retval = true;\n\n if (goog.events.CAPTURE_SIMULATION_MODE ==\n goog.events.CaptureSimulationMode.ON) {\n // If we have not marked this event yet, we should perform capture\n // simulation.\n if (!goog.events.isMarkedIeEvent_(ieEvent)) {\n goog.events.markIeEvent_(ieEvent);\n\n var ancestors = [];\n for (var parent = evt.currentTarget; parent;\n parent = parent.parentNode) {\n ancestors.push(parent);\n }\n\n // Fire capture listeners.\n var type = listener.type;\n for (var i = ancestors.length - 1;\n !evt.hasPropagationStopped() && i >= 0; i--) {\n evt.currentTarget = ancestors[i];\n var result =\n goog.events.fireListeners_(ancestors[i], type, true, evt);\n retval = retval && result;\n }\n\n // Fire bubble listeners.\n //\n // We can technically rely on IE to perform bubble event\n // propagation. However, it turns out that IE fires events in\n // opposite order of attachEvent registration, which broke\n // some code and tests that rely on the order. (While W3C DOM\n // Level 2 Events TR leaves the event ordering unspecified,\n // modern browsers and W3C DOM Level 3 Events Working Draft\n // actually specify the order as the registration order.)\n for (var i = 0; !evt.hasPropagationStopped() && i < ancestors.length;\n i++) {\n evt.currentTarget = ancestors[i];\n var result =\n goog.events.fireListeners_(ancestors[i], type, false, evt);\n retval = retval && result;\n }\n }\n } else {\n retval = goog.events.fireListener(listener, evt);\n }\n return retval;\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 // 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 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 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 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 */\ngoog.events.wrapListener = function(listener) {\n goog.asserts.assert(listener, 'Listener can not be null.');\n\n if (goog.isFunction(listener)) {\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 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 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');\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 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 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 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 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} 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 goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.dispatchEvent = function(e) {\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 goog.events.EventTarget.superClass_.disposeInternal.call(this);\n\n this.removeAllListeners();\n this.parentEventTarget_ = null;\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.listen = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n this.assertInitialized_();\n return this.eventTargetListeners_.add(\n String(type), listener, false /* callOnce */, opt_useCapture,\n opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.listenOnce = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n return this.eventTargetListeners_.add(\n String(type), listener, true /* callOnce */, opt_useCapture,\n opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.unlisten = function(\n type, listener, opt_useCapture, opt_listenerScope) {\n return this.eventTargetListeners_.remove(\n String(type), listener, opt_useCapture, opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.unlistenByKey = function(key) {\n return this.eventTargetListeners_.removeByKey(key);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.removeAllListeners = function(opt_type) {\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/** @override */\ngoog.events.EventTarget.prototype.fireListeners = function(\n type, capture, eventObject) {\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/** @override */\ngoog.events.EventTarget.prototype.getListeners = function(type, capture) {\n return this.eventTargetListeners_.getListeners(String(type), capture);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.getListener = function(\n type, listener, capture, opt_listenerScope) {\n return this.eventTargetListeners_.getListener(\n String(type), listener, capture, opt_listenerScope);\n};\n\n\n/** @override */\ngoog.events.EventTarget.prototype.hasListener = function(\n opt_type, opt_capture) {\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 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 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 /** @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 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');\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 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 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 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 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 this.dispatchEvent(goog.Timer.TICK);\n};\n\n\n/**\n * Starts the timer.\n */\ngoog.Timer.prototype.start = function() {\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 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 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 if (goog.isFunction(listener)) {\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 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 var timerKey = null;\n return new goog\n .Promise(function(resolve, reject) {\n timerKey =\n goog.Timer.callOnce(function() { resolve(opt_result); }, delay);\n if (timerKey == goog.Timer.INVALID_TIMEOUT_ID_) {\n reject(new Error('Failed to schedule timer.'));\n }\n })\n .thenCatch(function(error) {\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 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 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 if (col.getValues && typeof col.getValues == 'function') {\n return col.getValues();\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 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 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 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 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 goog.array.isEmpty(/** @type {!Array<?>} */ (col));\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 */\ngoog.structs.clear = function(col) {\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 * @template T,S\n * @deprecated Use a more specific method, e.g. goog.array.forEach,\n * goog.object.forEach, or for-of.\n */\ngoog.structs.forEach = function(col, f, opt_obj) {\n if (col.forEach && typeof col.forEach == 'function') {\n col.forEach(f, opt_obj);\n } else if (goog.isArrayLike(col) || typeof col === 'string') {\n goog.array.forEach(/** @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 if (typeof col.filter == 'function') {\n return col.filter(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return goog.array.filter(/** @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 goog.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 if (typeof col.map == 'function') {\n return col.map(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return goog.array.map(/** @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 goog.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 if (typeof col.some == 'function') {\n return col.some(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return goog.array.some(/** @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 if (typeof col.every == 'function') {\n return col.every(f, opt_obj);\n }\n if (goog.isArrayLike(col) || typeof col === 'string') {\n return goog.array.every(/** @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 Datastructure: Hash Map.\n *\n *\n * This file contains an implementation of a Map structure. It implements a lot\n * of the methods used in goog.structs so those functions work on hashes. This\n * is best suited for complex key types. For simple keys such as numbers and\n * strings consider using the lighter-weight utilities in goog.object.\n */\n\n\ngoog.provide('goog.structs.Map');\n\ngoog.require('goog.iter.Iterator');\ngoog.require('goog.iter.StopIteration');\n\n\n\n/**\n * Class for Hash Map datastructure.\n * @param {*=} opt_map Map or Object to initialize the map with.\n * @param {...*} var_args If 2 or more arguments are present then they\n * will be used as key-value pairs.\n * @constructor\n * @template K, V\n * @deprecated This type is misleading: use ES6 Map instead.\n */\ngoog.structs.Map = function(opt_map, var_args) {\n\n /**\n * Underlying JS object used to implement the map.\n * @private {!Object}\n */\n this.map_ = {};\n\n /**\n * An array of keys. This is necessary for two reasons:\n * 1. Iterating the keys using for (var key in this.map_) allocates an\n * object for every key in IE which is really bad for IE6 GC perf.\n * 2. Without a side data structure, we would need to escape all the keys\n * as that would be the only way we could tell during iteration if the\n * key was an internal key or a property of the object.\n *\n * This array can contain deleted keys so it's necessary to check the map\n * as well to see if the key is still in the map (this doesn't require a\n * memory allocation in IE).\n * @private {!Array<string>}\n */\n this.keys_ = [];\n\n /**\n * The number of key value pairs in the map.\n * @private {number}\n */\n this.count_ = 0;\n\n /**\n * Version used to detect changes while iterating.\n * @private {number}\n */\n this.version_ = 0;\n\n var argLength = arguments.length;\n\n if (argLength > 1) {\n if (argLength % 2) {\n throw new Error('Uneven number of arguments');\n }\n for (var i = 0; i < argLength; i += 2) {\n this.set(arguments[i], arguments[i + 1]);\n }\n } else if (opt_map) {\n this.addAll(/** @type {!Object} */ (opt_map));\n }\n};\n\n\n/**\n * @return {number} The number of key-value pairs in the map.\n */\ngoog.structs.Map.prototype.getCount = function() {\n return this.count_;\n};\n\n\n/**\n * Returns the values of the map.\n * @return {!Array<V>} The values in the map.\n */\ngoog.structs.Map.prototype.getValues = function() {\n this.cleanupKeysArray_();\n\n var rv = [];\n for (var i = 0; i < this.keys_.length; i++) {\n var key = this.keys_[i];\n rv.push(this.map_[key]);\n }\n return rv;\n};\n\n\n/**\n * Returns the keys of the map.\n * @return {!Array<string>} Array of string values.\n */\ngoog.structs.Map.prototype.getKeys = function() {\n this.cleanupKeysArray_();\n return /** @type {!Array<string>} */ (this.keys_.concat());\n};\n\n\n/**\n * Whether the map contains the given key.\n * @param {*} key The key to check for.\n * @return {boolean} Whether the map contains the key.\n */\ngoog.structs.Map.prototype.containsKey = function(key) {\n return goog.structs.Map.hasKey_(this.map_, key);\n};\n\n\n/**\n * Whether the map contains the given value. This is O(n).\n * @param {V} val The value to check for.\n * @return {boolean} Whether the map contains the value.\n */\ngoog.structs.Map.prototype.containsValue = function(val) {\n for (var i = 0; i < this.keys_.length; i++) {\n var key = this.keys_[i];\n if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) {\n return true;\n }\n }\n return false;\n};\n\n\n/**\n * Whether this map is equal to the argument map.\n * @param {goog.structs.Map} otherMap The map against which to test equality.\n * @param {function(V, V): boolean=} opt_equalityFn Optional equality function\n * to test equality of values. If not specified, this will test whether\n * the values contained in each map are identical objects.\n * @return {boolean} Whether the maps are equal.\n */\ngoog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) {\n if (this === otherMap) {\n return true;\n }\n\n if (this.count_ != otherMap.getCount()) {\n return false;\n }\n\n var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals;\n\n this.cleanupKeysArray_();\n for (var key, i = 0; key = this.keys_[i]; i++) {\n if (!equalityFn(this.get(key), otherMap.get(key))) {\n return false;\n }\n }\n\n return true;\n};\n\n\n/**\n * Default equality test for values.\n * @param {*} a The first value.\n * @param {*} b The second value.\n * @return {boolean} Whether a and b reference the same object.\n */\ngoog.structs.Map.defaultEquals = function(a, b) {\n return a === b;\n};\n\n\n/**\n * @return {boolean} Whether the map is empty.\n */\ngoog.structs.Map.prototype.isEmpty = function() {\n return this.count_ == 0;\n};\n\n\n/**\n * Removes all key-value pairs from the map.\n */\ngoog.structs.Map.prototype.clear = function() {\n this.map_ = {};\n this.keys_.length = 0;\n this.count_ = 0;\n this.version_ = 0;\n};\n\n\n/**\n * Removes a key-value pair based on the key. This is O(logN) amortized due to\n * updating the keys array whenever the count becomes half the size of the keys\n * in the keys array.\n * @param {*} key The key to remove.\n * @return {boolean} Whether object was removed.\n */\ngoog.structs.Map.prototype.remove = function(key) {\n if (goog.structs.Map.hasKey_(this.map_, key)) {\n delete this.map_[key];\n this.count_--;\n this.version_++;\n\n // clean up the keys array if the threshold is hit\n if (this.keys_.length > 2 * this.count_) {\n this.cleanupKeysArray_();\n }\n\n return true;\n }\n return false;\n};\n\n\n/**\n * Cleans up the temp keys array by removing entries that are no longer in the\n * map.\n * @private\n */\ngoog.structs.Map.prototype.cleanupKeysArray_ = function() {\n if (this.count_ != this.keys_.length) {\n // First remove keys that are no longer in the map.\n var srcIndex = 0;\n var destIndex = 0;\n while (srcIndex < this.keys_.length) {\n var key = this.keys_[srcIndex];\n if (goog.structs.Map.hasKey_(this.map_, key)) {\n this.keys_[destIndex++] = key;\n }\n srcIndex++;\n }\n this.keys_.length = destIndex;\n }\n\n if (this.count_ != this.keys_.length) {\n // If the count still isn't correct, that means we have duplicates. This can\n // happen when the same key is added and removed multiple times. Now we have\n // to allocate one extra Object to remove the duplicates. This could have\n // been done in the first pass, but in the common case, we can avoid\n // allocating an extra object by only doing this when necessary.\n var seen = {};\n var srcIndex = 0;\n var destIndex = 0;\n while (srcIndex < this.keys_.length) {\n var key = this.keys_[srcIndex];\n if (!(goog.structs.Map.hasKey_(seen, key))) {\n this.keys_[destIndex++] = key;\n seen[key] = 1;\n }\n srcIndex++;\n }\n this.keys_.length = destIndex;\n }\n};\n\n\n/**\n * Returns the value for the given key. If the key is not found and the default\n * value is not given this will return `undefined`.\n * @param {*} key The key to get the value for.\n * @param {DEFAULT=} opt_val The value to return if no item is found for the\n * given key, defaults to undefined.\n * @return {V|DEFAULT} The value for the given key.\n * @template DEFAULT\n */\ngoog.structs.Map.prototype.get = function(key, opt_val) {\n if (goog.structs.Map.hasKey_(this.map_, key)) {\n return this.map_[key];\n }\n return opt_val;\n};\n\n\n/**\n * Adds a key-value pair to the map.\n * @param {*} key The key.\n * @param {V} value The value to add.\n * @return {*} Some subclasses return a value.\n */\ngoog.structs.Map.prototype.set = function(key, value) {\n if (!(goog.structs.Map.hasKey_(this.map_, key))) {\n this.count_++;\n // TODO(johnlenz): This class lies, it claims to return an array of string\n // keys, but instead returns the original object used.\n this.keys_.push(/** @type {?} */ (key));\n // Only change the version if we add a new key.\n this.version_++;\n }\n this.map_[key] = value;\n};\n\n\n/**\n * Adds multiple key-value pairs from another goog.structs.Map or Object.\n * @param {?Object} map Object containing the data to add.\n */\ngoog.structs.Map.prototype.addAll = function(map) {\n if (map instanceof goog.structs.Map) {\n var keys = map.getKeys();\n for (var i = 0; i < keys.length; i++) {\n this.set(keys[i], map.get(keys[i]));\n }\n } else {\n for (var key in map) {\n this.set(key, map[key]);\n }\n }\n};\n\n\n/**\n * Calls the given function on each entry in the map.\n * @param {function(this:T, V, K, goog.structs.Map<K,V>)} f\n * @param {T=} opt_obj The value of \"this\" inside f.\n * @template T\n */\ngoog.structs.Map.prototype.forEach = function(f, opt_obj) {\n var keys = this.getKeys();\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = this.get(key);\n f.call(opt_obj, value, key, this);\n }\n};\n\n\n/**\n * Clones a map and returns a new map.\n * @return {!goog.structs.Map} A new map with the same key-value pairs.\n */\ngoog.structs.Map.prototype.clone = function() {\n return new goog.structs.Map(this);\n};\n\n\n/**\n * Returns a new map 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 *\n * It acts very similarly to {goog.object.transpose(Object)}.\n *\n * @return {!goog.structs.Map} The transposed map.\n */\ngoog.structs.Map.prototype.transpose = function() {\n var transposed = new goog.structs.Map();\n for (var i = 0; i < this.keys_.length; i++) {\n var key = this.keys_[i];\n var value = this.map_[key];\n transposed.set(value, key);\n }\n\n return transposed;\n};\n\n\n/**\n * @return {!Object} Object representation of the map.\n */\ngoog.structs.Map.prototype.toObject = function() {\n this.cleanupKeysArray_();\n var obj = {};\n for (var i = 0; i < this.keys_.length; i++) {\n var key = this.keys_[i];\n obj[key] = this.map_[key];\n }\n return obj;\n};\n\n\n/**\n * Returns an iterator that iterates over the keys in the map. Removal of keys\n * while iterating might have undesired side effects.\n * @return {!goog.iter.Iterator} An iterator over the keys in the map.\n */\ngoog.structs.Map.prototype.getKeyIterator = function() {\n return this.__iterator__(true);\n};\n\n\n/**\n * Returns an iterator that iterates over the values in the map. Removal of\n * keys while iterating might have undesired side effects.\n * @return {!goog.iter.Iterator} An iterator over the values in the map.\n */\ngoog.structs.Map.prototype.getValueIterator = function() {\n return this.__iterator__(false);\n};\n\n\n/**\n * Returns an iterator that iterates over the values or the keys in the map.\n * This throws an exception if the map was mutated since the iterator was\n * created.\n * @param {boolean=} opt_keys True to iterate over the keys. False to iterate\n * over the values. The default value is false.\n * @return {!goog.iter.Iterator} An iterator over the values or keys in the map.\n */\ngoog.structs.Map.prototype.__iterator__ = function(opt_keys) {\n // Clean up keys to minimize the risk of iterating over dead keys.\n this.cleanupKeysArray_();\n\n var i = 0;\n var version = this.version_;\n var selfObj = this;\n\n var newIter = new goog.iter.Iterator;\n newIter.next = function() {\n if (version != selfObj.version_) {\n throw new Error('The map has changed since the iterator was created');\n }\n if (i >= selfObj.keys_.length) {\n throw goog.iter.StopIteration;\n }\n var key = selfObj.keys_[i++];\n return opt_keys ? key : selfObj.map_[key];\n };\n return newIter;\n};\n\n\n/**\n * Safe way to test for hasOwnProperty. It even allows testing for\n * 'hasOwnProperty'.\n * @param {!Object} obj The object to test for presence of the given key.\n * @param {*} key The key to check for.\n * @return {boolean} Whether the object has the key.\n * @private\n */\ngoog.structs.Map.hasKey_ = function(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\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 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.array');\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 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 * @type {!RegExp}\n * @private\n */\ngoog.uri.utils.splitRe_ = new RegExp(\n '^' +\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\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/**\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 // See @return comment -- never null.\n return /** @type {!Array<string|undefined>} */ (\n uri.match(goog.uri.utils.splitRe_));\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 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 // 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 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 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.substr(0, protocol.length - 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 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 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 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 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 // 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 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 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 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 // The hash mark may not appear in any other part of the URL.\n var hashIndex = uri.indexOf('#');\n return hashIndex < 0 ? null : uri.substr(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 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 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 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 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 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 // The hash mark may not appear in any other part of the URL.\n var hashIndex = uri.indexOf('#');\n return hashIndex < 0 ? uri : uri.substr(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 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 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 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 // 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.substr(0, questionIndex), queryData, uri.substr(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 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 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 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 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 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 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 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 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 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 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 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 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 // Use substr, because it (unlike substring) will return empty string\n // if foundIndex > endPosition.\n return goog.string.urlDecode(\n uri.substr(foundIndex, endPosition - foundIndex));\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 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 // Use substr, because it (unlike substring) will return empty string\n // if foundIndex > position.\n result.push(\n goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex)));\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 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.substr(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 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 var parts = goog.uri.utils.splitQueryData_(uri);\n var queryData = parts[1];\n var buffer = [];\n if (queryData) {\n goog.array.forEach(queryData.split('&'), function(pair) {\n var indexOfEquals = pair.indexOf('=');\n var name = indexOfEquals >= 0 ? pair.substr(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 goog.uri.utils.assertNoFragmentsOrQueries_(baseUri);\n\n // Remove any trailing '/'\n if (goog.string.endsWith(baseUri, '/')) {\n baseUri = baseUri.substr(0, baseUri.length - 1);\n }\n // Remove any leading '/'\n if (goog.string.startsWith(path, '/')) {\n path = path.substr(1);\n }\n return goog.string.buildString(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 // 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 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 Class for parsing and formatting URIs.\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.string');\ngoog.require('goog.structs');\ngoog.require('goog.structs.Map');\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 /**\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, 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 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(\n goog.Uri.encodeSpecialChars_(\n path, 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 '#', 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\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().substr(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 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 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 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 return !!this.scheme_;\n};\n\n\n/**\n * @return {string} The decoded user info.\n */\ngoog.Uri.prototype.getUserInfo = function() {\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 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 return !!this.userInfo_;\n};\n\n\n/**\n * @return {string} The decoded domain.\n */\ngoog.Uri.prototype.getDomain = function() {\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 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 return !!this.domain_;\n};\n\n\n/**\n * @return {?number} The port number.\n */\ngoog.Uri.prototype.getPort = function() {\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 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 return this.port_ != null;\n};\n\n\n/**\n * @return {string} The decoded path.\n */\ngoog.Uri.prototype.getPath = function() {\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 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 return !!this.path_;\n};\n\n\n/**\n * @return {boolean} Whether the query string has been set.\n */\ngoog.Uri.prototype.hasQuery = function() {\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 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, null, 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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\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 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 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 // 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 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 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 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 // 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 {goog.Uri=} opt_uri Optional uri object that should have its\n * cache invalidated when this object updates. Deprecated -- this\n * is no longer required.\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_uri, opt_ignoreCase) {\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 {?goog.structs.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 if (!this.keyMap_) {\n this.keyMap_ = new goog.structs.Map();\n this.count_ = 0;\n if (this.encodedQuery_) {\n var self = this;\n goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\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.structs.Map<string, ?>|!Object} map Map of string parameter\n * 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 {goog.Uri=} opt_uri URI object that should have its cache\n * invalidated when this object updates.\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_uri, opt_ignoreCase) {\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, 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 {goog.Uri=} opt_uri URI object that should have its cache\n * invalidated when this object updates.\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_uri, opt_ignoreCase) {\n if (keys.length != values.length) {\n throw new Error('Mismatched lengths for keys/values');\n }\n var queryData = new goog.Uri.QueryData(null, 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 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 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 this.ensureKeyMapInitialized_();\n\n key = this.getKeyName_(key);\n if (this.keyMap_.containsKey(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_.remove(key);\n }\n return false;\n};\n\n\n/**\n * Clears the parameters.\n */\ngoog.Uri.QueryData.prototype.clear = function() {\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 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 this.ensureKeyMapInitialized_();\n key = this.getKeyName_(key);\n return this.keyMap_.containsKey(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 // 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 this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(values, key) {\n goog.array.forEach(values, function(value) {\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 this.ensureKeyMapInitialized_();\n // We need to get the values to know how many keys to add.\n var vals = this.keyMap_.getValues();\n var keys = this.keyMap_.getKeys();\n var rv = [];\n for (var i = 0; i < keys.length; i++) {\n var val = vals[i];\n for (var 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 this.ensureKeyMapInitialized_();\n var rv = [];\n if (typeof opt_key === 'string') {\n if (this.containsKey(opt_key)) {\n rv = goog.array.concat(rv, this.keyMap_.get(this.getKeyName_(opt_key)));\n }\n } else {\n // Return all values.\n var values = this.keyMap_.getValues();\n for (var i = 0; i < values.length; i++) {\n rv = goog.array.concat(rv, 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 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 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 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 if (this.encodedQuery_) {\n return this.encodedQuery_;\n }\n\n if (!this.keyMap_) {\n return '';\n }\n\n var 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 var keys = this.keyMap_.getKeys();\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var encodedKey = goog.string.urlEncode(key);\n var 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 return goog.Uri.decodeOrEmpty_(this.toString());\n};\n\n\n/**\n * Invalidate the cache.\n * @private\n */\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\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 this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(value, key) {\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 var rv = new goog.Uri.QueryData();\n rv.encodedQuery_ = this.encodedQuery_;\n if (this.keyMap_) {\n rv.keyMap_ = this.keyMap_.clone();\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 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 var resetKeys = ignoreCase && !this.ignoreCase_;\n if (resetKeys) {\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n this.keyMap_.forEach(function(value, key) {\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.structs.Map<?, ?>|?Object)} var_args\n * The object from which key value pairs will be copied. Note: does not\n * 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 for (var i = 0; i < arguments.length; i++) {\n var data = arguments[i];\n goog.structs.forEach(\n data, function(value, key) { this.add(key, value); }, this);\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines fireauth.iframeclient.IfcHandler used to communicate\n * with the serverless widget.\n */\n\ngoog.provide('fireauth.iframeclient.IfcHandler');\ngoog.provide('fireauth.iframeclient.IframeUrlBuilder');\ngoog.provide('fireauth.iframeclient.OAuthUrlBuilder');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.InvalidOriginError');\ngoog.require('fireauth.OAuthSignInHandler');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.iframeclient.IframeWrapper');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n/**\n * The OAuth handler and iframe prototcol.\n * @const {string}\n * @suppress {const|duplicate}\n */\nfireauth.iframeclient.SCHEME = 'https';\n\n\n\n/**\n * The OAuth handler and iframe port number.\n * @const {?number}\n * @suppress {const|duplicate}\n */\nfireauth.iframeclient.PORT_NUMBER = null;\n\n\n\n/**\n * The iframe URL builder used to build the iframe widget URL.\n * @param {string} authDomain The application authDomain.\n * @param {string} apiKey The API key.\n * @param {string} appName The App name.\n * @constructor\n */\nfireauth.iframeclient.IframeUrlBuilder = function(authDomain, apiKey, appName) {\n /** @private {string} The application authDomain. */\n this.authDomain_ = authDomain;\n /** @private {string} The API key. */\n this.apiKey_ = apiKey;\n /** @private {string} The App name. */\n this.appName_ = appName;\n /** @private {?string|undefined} The client version. */\n this.v_ = null;\n /**\n * @private {!goog.Uri} The URI object used to build the iframe URL.\n */\n this.uri_ = goog.Uri.create(\n fireauth.iframeclient.SCHEME,\n null,\n this.authDomain_,\n fireauth.iframeclient.PORT_NUMBER,\n '/__/auth/iframe',\n null,\n null);\n this.uri_.setParameterValue('apiKey', this.apiKey_);\n this.uri_.setParameterValue('appName', this.appName_);\n /** @private {?string|undefined} The endpoint ID. */\n this.endpointId_ = null;\n /** @private {!Array<string>} The list of framework IDs. */\n this.frameworks_ = [];\n};\n\n\n/**\n * Sets the client version.\n * @param {?string|undefined} v The client version.\n * @return {!fireauth.iframeclient.IframeUrlBuilder} The current iframe URL\n * builder instance.\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.setVersion = function(v) {\n this.v_ = v;\n return this;\n};\n\n\n/**\n * Sets the endpoint ID.\n * @param {?string|undefined} eid The endpoint ID (staging, test Gaia, etc).\n * @return {!fireauth.iframeclient.IframeUrlBuilder} The current iframe URL\n * builder instance.\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.setEndpointId = function(eid) {\n this.endpointId_ = eid;\n return this;\n};\n\n\n/**\n * Sets the list of frameworks to pass to the iframe.\n * @param {?Array<string>|undefined} frameworks The list of frameworks to log.\n * @return {!fireauth.iframeclient.IframeUrlBuilder} The current iframe URL\n * builder instance.\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.setFrameworks =\n function(frameworks) {\n this.frameworks_ = goog.array.clone(frameworks || []);\n return this;\n};\n\n\n/**\n * Modifes the URI with the relevant Auth provider parameters.\n * @return {string} The constructed OAuth URL string.\n * @override\n */\nfireauth.iframeclient.IframeUrlBuilder.prototype.toString = function() {\n // Pass the client version if available.\n if (this.v_) {\n this.uri_.setParameterValue('v', this.v_);\n } else {\n this.uri_.removeParameter('v');\n }\n // Pass the endpoint ID if available.\n if (this.endpointId_) {\n this.uri_.setParameterValue('eid', this.endpointId_);\n } else {\n this.uri_.removeParameter('eid');\n }\n // Pass the list of frameworks if available.\n if (this.frameworks_.length) {\n this.uri_.setParameterValue('fw', this.frameworks_.join(','));\n } else {\n this.uri_.removeParameter('fw');\n }\n return this.uri_.toString();\n};\n\n\n\n/**\n * The OAuth URL builder used to build the OAuth handler widget URL.\n * @param {string} authDomain The application authDomain.\n * @param {string} apiKey The API key.\n * @param {string} appName The App name.\n * @param {string} authType The Auth operation type.\n * @param {!fireauth.AuthProvider} provider The Auth provider that the OAuth\n * handler request is built to sign in to.\n * @constructor\n */\nfireauth.iframeclient.OAuthUrlBuilder =\n function(authDomain, apiKey, appName, authType, provider) {\n /** @private {string} The application authDomain. */\n this.authDomain_ = authDomain;\n /** @private {string} The API key. */\n this.apiKey_ = apiKey;\n /** @private {string} The App name. */\n this.appName_ = appName;\n /** @private {string} The Auth operation type. */\n this.authType_ = authType;\n /**\n * @private {?string|undefined} The redirect URL used in redirect operations.\n */\n this.redirectUrl_ = null;\n /** @private {?string|undefined} The event ID. */\n this.eventId_ = null;\n /** @private {?string|undefined} The client version. */\n this.v_ = null;\n /**\n * @private {!fireauth.AuthProvider} The Firebase Auth provider that the OAuth\n * handler request is built to sign in to.\n */\n this.provider_ = provider;\n /** @private {?string|undefined} The endpoint ID. */\n this.endpointId_ = null;\n /** @private {?string|undefined} The tenant ID. */\n this.tenantId_ = null;\n};\n\n\n/**\n * Sets the redirect URL.\n * @param {?string|undefined} redirectUrl The redirect URL used in redirect\n * operations.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n * builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setRedirectUrl =\n function(redirectUrl) {\n this.redirectUrl_ = redirectUrl;\n return this;\n};\n\n\n/**\n * Sets the event ID.\n * @param {?string|undefined} eventId The event ID.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n * builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setEventId = function(eventId) {\n this.eventId_ = eventId;\n return this;\n};\n\n\n/**\n * Sets the tenant ID.\n * @param {?string|undefined} tenantId The event ID.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n * builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setTenantId =\n function(tenantId) {\n this.tenantId_ = tenantId;\n return this;\n};\n\n\n/**\n * Sets the client version.\n * @param {?string|undefined} v The client version.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n * builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setVersion = function(v) {\n this.v_ = v;\n return this;\n};\n\n\n/**\n * Sets the endpoint ID.\n * @param {?string|undefined} eid The endpoint ID (staging, test Gaia, etc).\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n * builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setEndpointId = function(eid) {\n this.endpointId_ = eid;\n return this;\n};\n\n\n/**\n * Sets any additional optional parameters. This will overwrite any previously\n * set additional parameters.\n * @param {?Object<string, string>|undefined} additionalParams The optional\n * additional parameters.\n * @return {!fireauth.iframeclient.OAuthUrlBuilder} The current OAuth URL\n * builder instance.\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.setAdditionalParameters =\n function(additionalParams) {\n this.additionalParams_ = goog.object.clone(additionalParams || null);\n return this;\n};\n\n\n/**\n * Modifies the URI with the relevant Auth provider parameters.\n * @return {string} The constructed OAuth URL string.\n * @override\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.toString = function() {\n var uri = goog.Uri.create(\n fireauth.iframeclient.SCHEME,\n null,\n this.authDomain_,\n fireauth.iframeclient.PORT_NUMBER,\n '/__/auth/handler',\n null,\n null);\n uri.setParameterValue('apiKey', this.apiKey_);\n uri.setParameterValue('appName', this.appName_);\n uri.setParameterValue('authType', this.authType_);\n\n // Add custom parameters for OAuth1/OAuth2 providers.\n if (this.provider_['isOAuthProvider']) {\n // Set default language if available and no language already set.\n /** @type {!fireauth.FederatedProvider} */ (this.provider_)\n .setDefaultLanguage(this.getAuthLanguage_());\n uri.setParameterValue('providerId', this.provider_['providerId']);\n var customParameters = /** @type {!fireauth.FederatedProvider} */ (\n this.provider_).getCustomParameters();\n if (!goog.object.isEmpty(customParameters)) {\n uri.setParameterValue(\n 'customParameters',\n /** @type {string} */ (fireauth.util.stringifyJSON(customParameters))\n );\n }\n }\n\n // Add scopes for OAuth2 providers.\n if (typeof this.provider_.getScopes === 'function') {\n var scopes = this.provider_.getScopes();\n if (scopes.length) {\n uri.setParameterValue('scopes', scopes.join(','));\n }\n }\n\n if (this.redirectUrl_) {\n uri.setParameterValue('redirectUrl', this.redirectUrl_);\n } else {\n uri.removeParameter('redirectUrl');\n }\n if (this.eventId_) {\n uri.setParameterValue('eventId', this.eventId_);\n } else {\n uri.removeParameter('eventId');\n }\n // Pass the client version if available.\n if (this.v_) {\n uri.setParameterValue('v', this.v_);\n } else {\n uri.removeParameter('v');\n }\n if (this.additionalParams_) {\n for (var key in this.additionalParams_) {\n if (this.additionalParams_.hasOwnProperty(key) &&\n // Don't overwrite other existing parameters.\n !uri.getParameterValue(key)) {\n uri.setParameterValue(key, this.additionalParams_[key]);\n }\n }\n }\n // Pass the tenant ID if available.\n if (this.tenantId_) {\n uri.setParameterValue('tid', this.tenantId_);\n } else {\n uri.removeParameter('tid');\n }\n // Pass the endpoint ID if available.\n if (this.endpointId_) {\n uri.setParameterValue('eid', this.endpointId_);\n } else {\n uri.removeParameter('eid');\n }\n // Append any framework IDs to the handler URL to log in handler RPC requests.\n var frameworks = this.getAuthFrameworks_();\n if (frameworks.length) {\n uri.setParameterValue('fw', frameworks.join(','));\n }\n return uri.toString();\n};\n\n\n/**\n * Returns the current Auth instance's language code.\n * @return {?string} The corresponding language code.\n * @private\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.getAuthLanguage_ = function() {\n try {\n // Get the Auth instance for the current App identified by the App name.\n // This could fail if, for example, the App instance was deleted.\n return firebase['app'](this.appName_)['auth']().getLanguageCode();\n } catch (e) {\n return null;\n }\n};\n\n\n/**\n * Returns the list of Firebase frameworks used for logging purposes.\n * @return {!Array<string>} The list of corresponding Firebase frameworks.\n * @private\n */\nfireauth.iframeclient.OAuthUrlBuilder.prototype.getAuthFrameworks_ =\n function() {\n return fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_(\n this.appName_);\n};\n\n\n/**\n * Returns the list of Firebase frameworks used for logging purposes\n * corresponding to the Firebase App name provided.\n * @param {string} appName The Firebase App name.\n * @return {!Array<string>} The list of corresponding Firebase frameworks.\n * @private\n */\nfireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_ =\n function(appName) {\n try {\n // Get the Auth instance's list of Firebase framework IDs for the current\n // App identified by the App name.\n // This could fail if, for example, the App instance was deleted.\n return firebase['app'](appName)['auth']().getFramework();\n } catch (e) {\n return [];\n }\n};\n\n\n\n/**\n * Initializes the ifcHandler which provides the mechanism to listen to Auth\n * events on the hidden iframe.\n * @param {string} authDomain The firebase authDomain used to determine the\n * OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n * request.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @constructor\n * @implements {fireauth.OAuthSignInHandler}\n */\nfireauth.iframeclient.IfcHandler = function(authDomain, apiKey, appName,\n opt_clientVersion, opt_endpointId) {\n /** @private {string} The Auth domain. */\n this.authDomain_ = authDomain;\n /** @private {string} The API key. */\n this.apiKey_ = apiKey;\n /** @private {string} The App name. */\n this.appName_ = appName;\n /** @private {?string} The client version. */\n this.clientVersion_ = opt_clientVersion || null;\n /** @private {?string} The Auth endpoint ID. */\n this.endpointId_ = opt_endpointId || null;\n // Delay RPC handler and iframe URL initialization until needed to ensure\n // logged frameworks are propagated to the iframe.\n /** @private {?string} The full client version string. */\n this.fullClientVersion_ = null;\n /** @private {?string} The iframe URL. */\n this.iframeUrl_ = null;\n /** @private {?fireauth.RpcHandler} The RPC handler for provided API key. */\n this.rpcHandler_ = null;\n /**\n * @private {!Array<!function(?fireauth.AuthEvent)>} The Auth event\n * listeners.\n */\n this.authEventListeners_ = [];\n // Delay origin validator determination until needed, so the error is not\n // thrown in the background. This will also prevent the getProjectConfig RPC\n // until it is required.\n /** @private {?goog.Promise} The origin validator. */\n this.originValidator_ = null;\n /** @private {?goog.Promise} The initialization promise. */\n this.isInitialized_ = null;\n};\n\n\n/**\n * Validates the provided URL.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler used to validate the\n * requested origin.\n * @param {string=} opt_origin The optional page origin. If not provided, the\n * window.location.href value is used.\n * @return {!goog.Promise} The promise that resolves if the provided origin is\n * valid.\n * @private\n */\nfireauth.iframeclient.IfcHandler.getOriginValidator_ =\n function(rpcHandler, opt_origin) {\n var origin = opt_origin || fireauth.util.getCurrentUrl();\n return rpcHandler.getAuthorizedDomains().then(function(authorizedDomains) {\n if (!fireauth.util.isAuthorizedDomain(authorizedDomains, origin)) {\n throw new fireauth.InvalidOriginError(fireauth.util.getCurrentUrl());\n }\n });\n};\n\n\n/**\n * Initializes the iframe client wrapper.\n * @return {!goog.Promise} The promise that resolves on initialization.\n */\nfireauth.iframeclient.IfcHandler.prototype.initialize = function() {\n // Already initialized.\n if (this.isInitialized_) {\n return this.isInitialized_;\n }\n var self = this;\n this.isInitialized_ = fireauth.util.onDomReady().then(function() {\n /**\n * @private {!fireauth.iframeclient.IframeWrapper} The iframe wrapper\n * instance.\n */\n self.iframeWrapper_ = new fireauth.iframeclient.IframeWrapper(\n self.getIframeUrl());\n // Register all event listeners to Auth event messages sent from Auth\n // iframe.\n self.registerEvents_();\n });\n return this.isInitialized_;\n};\n\n\n/**\n * Waits for popup window to close. When closed start timeout listener for popup\n * pending promise. If in the process, it was detected that the iframe does not\n * support web storage, the popup is closed and the web storage unsupported\n * error is thrown.\n * @param {!Window} popupWin The popup window.\n * @param {!function(!fireauth.AuthError)} onError The on error callback.\n * @param {number} timeoutDuration The time to wait in ms after the popup is\n * closed before triggering the popup closed by user error.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.startPopupTimeout =\n function(popupWin, onError, timeoutDuration) {\n // Expire pending timeout promise for popup operation.\n var popupClosedByUserError = new fireauth.AuthError(\n fireauth.authenum.Error.POPUP_CLOSED_BY_USER);\n // If web storage is disabled in the iframe, expire popup timeout quickly with\n // this error.\n var webStorageNotSupportedError = new fireauth.AuthError(\n fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n var self = this;\n var isResolved = false;\n // Wait for the iframe to be ready first.\n return this.initializeAndWait().then(function() {\n // We do not return isWebStorageSupported() to ensure that this is backward\n // compatible.\n // Pushing the following client changes before updating the iframe to\n // respond to these events would continue to work.\n // The downside is that the popup could be closed before this resolves.\n // In that case, they would get an error that the popup was closed and not\n // the error that web storage is not supported, though that is unlikely\n // as isWebStorageSupported should execute faster than the popup timeout.\n // If web storage is not supported in the iframe, fail quickly.\n self.isWebStorageSupported().then(function(isSupported) {\n if (!isSupported) {\n // If not supported, close window.\n if (popupWin) {\n fireauth.util.closeWindow(popupWin);\n }\n onError(webStorageNotSupportedError);\n isResolved = true;\n }\n });\n }).thenCatch(function(error) {\n // Ignore any possible error in iframe embedding.\n // These types of errors will be handled in processPopup which will close\n // the popup too if that happens.\n return;\n }).then(function() {\n // Skip if already resolved.\n if (isResolved) {\n return;\n }\n // After the iframe is ready, wait for popup to close and then start timeout\n // check.\n return fireauth.util.onPopupClose(popupWin);\n }).then(function() {\n // Skip if already resolved.\n if (isResolved) {\n return;\n }\n return goog.Timer.promise(timeoutDuration).then(function() {\n // If this is already resolved or rejected, this will do nothing.\n onError(popupClosedByUserError);\n });\n });\n};\n\n\n/**\n * @return {boolean} Whether the handler should be initialized early.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.shouldBeInitializedEarly =\n function() {\n var ua = fireauth.util.getUserAgentString();\n // Cannot run in the background (can't wait for iframe to be embedded\n // before triggering popup redirect) and is Safari (can only detect\n // localStorage in iframe via change event) => embed iframe ASAP.\n // Do the same for mobile browsers on iOS devices as they use the same\n // Safari implementation underneath.\n return !fireauth.util.runsInBackground(ua) &&\n !fireauth.util.iframeCanSyncWebStorage(ua);\n};\n\n\n/**\n * @return {boolean} Whether the sign-in handler in the current environment\n * has volatile session storage.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.hasVolatileStorage = function() {\n // Web environment with web storage enabled has stable sessionStorage.\n return false;\n};\n\n\n/**\n * Processes the popup request. The popup instance must be provided externally\n * and on error, the requestor must close the window.\n * @param {?Window} popupWin The popup window reference.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function()} onInitialize The function to call on initialization.\n * @param {function(*)} onError The function to call on error.\n * @param {string=} opt_eventId The optional event ID.\n * @param {boolean=} opt_alreadyRedirected Whether popup is already redirected\n * to final destination.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise} The popup window promise.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.processPopup = function(\n popupWin,\n mode,\n provider,\n onInitialize,\n onError,\n opt_eventId,\n opt_alreadyRedirected,\n opt_tenantId) {\n // processPopup is failing since it tries to access popup win when tab can\n // not run in background. For now bypass processPopup which runs\n // additional origin check not accounted above. Besides, iframe will never\n // hand result to parent if origin not whitelisted.\n // Error thrown by browser: Unable to establish a connection with the\n // popup. It may have been blocked by the browser.\n // If popup is null, startPopupTimeout will catch it without having the\n // above error getting triggered due to popup access from opener.\n\n // Reject immediately if the popup is blocked.\n if (!popupWin) {\n return goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.POPUP_BLOCKED));\n }\n // Already redirected and cannot run in the background, resolve quickly while\n // initializing.\n if (opt_alreadyRedirected && !fireauth.util.runsInBackground()) {\n // Initialize first before resolving.\n this.initializeAndWait().thenCatch(function(error) {\n fireauth.util.closeWindow(popupWin);\n onError(error);\n });\n onInitialize();\n // Already redirected.\n return goog.Promise.resolve();\n }\n // If origin validator not determined yet.\n if (!this.originValidator_) {\n this.originValidator_ =\n fireauth.iframeclient.IfcHandler.getOriginValidator_(\n this.getRpcHandler_());\n }\n var self = this;\n return this.originValidator_.then(function() {\n // After origin validation, wait for iframe to be ready before redirecting.\n var onReady = self.initializeAndWait().thenCatch(function(error) {\n fireauth.util.closeWindow(popupWin);\n onError(error);\n throw error;\n });\n onInitialize();\n return onReady;\n }).then(function() {\n // Popup and redirect operations work for OAuth providers only.\n fireauth.AuthProvider.checkIfOAuthSupported(provider);\n // Already redirected to intended destination, no need to redirect again.\n if (opt_alreadyRedirected) {\n return;\n }\n var oauthHelperWidgetUrl =\n fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n self.authDomain_,\n self.apiKey_,\n self.appName_,\n mode,\n provider,\n null,\n opt_eventId,\n self.clientVersion_,\n undefined,\n self.endpointId_,\n opt_tenantId);\n // Redirect popup to OAuth helper widget URL.\n fireauth.util.goTo(oauthHelperWidgetUrl, /** @type {!Window} */ (popupWin));\n }).thenCatch(function(e) {\n // Force another origin validation.\n if (e.code == 'auth/network-request-failed') {\n self.originValidator_ = null;\n }\n throw e;\n });\n};\n\n\n/**\n * @return {!fireauth.RpcHandler} The RPC handler instance with the relevant\n * endpoints, version and frameworks.\n * @private\n */\nfireauth.iframeclient.IfcHandler.prototype.getRpcHandler_ = function() {\n if (!this.rpcHandler_) {\n this.fullClientVersion_ = this.clientVersion_ ?\n fireauth.util.getClientVersion(\n fireauth.util.ClientImplementation.JSCORE,\n this.clientVersion_,\n fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_(\n this.appName_)) :\n null;\n this.rpcHandler_ = new fireauth.RpcHandler(\n this.apiKey_,\n // Get the client Auth endpoint used.\n fireauth.constants.getEndpointConfig(this.endpointId_),\n this.fullClientVersion_);\n }\n return this.rpcHandler_;\n};\n\n\n/**\n * Processes the redirect request.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {?string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.processRedirect =\n function(mode, provider, opt_eventId, opt_tenantId) {\n // If origin validator not determined yet.\n if (!this.originValidator_) {\n this.originValidator_ =\n fireauth.iframeclient.IfcHandler.getOriginValidator_(\n this.getRpcHandler_());\n }\n var self = this;\n // Make sure origin is validated.\n return this.originValidator_.then(function() {\n fireauth.AuthProvider.checkIfOAuthSupported(provider);\n var oauthHelperWidgetUrl =\n fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n self.authDomain_,\n self.apiKey_,\n self.appName_,\n mode,\n provider,\n fireauth.util.getCurrentUrl(),\n opt_eventId,\n self.clientVersion_,\n undefined,\n self.endpointId_,\n opt_tenantId);\n // Redirect to OAuth helper widget URL.\n fireauth.util.goTo(oauthHelperWidgetUrl);\n }).thenCatch(function(e) {\n // Force another origin validation on network errors.\n if (e.code == 'auth/network-request-failed') {\n self.originValidator_ = null;\n }\n throw e;\n });\n};\n\n\n/** @return {string} The iframe URL. */\nfireauth.iframeclient.IfcHandler.prototype.getIframeUrl = function() {\n if (!this.iframeUrl_) {\n this.iframeUrl_ = fireauth.iframeclient.IfcHandler.getAuthIframeUrl(\n this.authDomain_, this.apiKey_, this.appName_, this.clientVersion_,\n this.endpointId_,\n fireauth.iframeclient.OAuthUrlBuilder.getAuthFrameworksForApp_(\n this.appName_));\n }\n return this.iframeUrl_;\n};\n\n\n/**\n * @return {!goog.Promise} The promise that resolves when the iframe is ready.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.initializeAndWait = function() {\n // Initialize if not initialized yet.\n var self = this;\n return this.initialize().then(function() {\n return self.iframeWrapper_.onReady();\n }).thenCatch(function(error) {\n // Reset origin validator.\n self.originValidator_ = null;\n // Reject iframe ready promise with network error.\n throw new fireauth.AuthError(\n fireauth.authenum.Error.NETWORK_REQUEST_FAILED);\n });\n};\n\n\n/**\n * @return {boolean} Whether the handler will unload the current page on\n * redirect operations.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.unloadsOnRedirect = function() {\n return true;\n};\n\n\n/**\n * @param {string} authDomain The Firebase authDomain used to determine the\n * OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n * request.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @param {?Array<string>=} opt_frameworks The optional list of framework IDs.\n * @return {string} The data iframe src URL.\n */\nfireauth.iframeclient.IfcHandler.getAuthIframeUrl = function(authDomain, apiKey,\n appName, opt_clientVersion, opt_endpointId, opt_frameworks) {\n // OAuth helper iframe URL.\n var builder = new fireauth.iframeclient.IframeUrlBuilder(\n authDomain, apiKey, appName);\n return builder\n .setVersion(opt_clientVersion)\n .setEndpointId(opt_endpointId)\n .setFrameworks(opt_frameworks)\n .toString();\n};\n\n\n/**\n * @param {string} authDomain The Firebase authDomain used to determine the\n * OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n * request.\n * @param {string} authType The type of operation that depends on OAuth sign in.\n * @param {!fireauth.AuthProvider} provider The provider to sign in to.\n * @param {?string=} opt_redirectUrl The optional URL to redirect to on OAuth\n * sign in completion.\n * @param {?string=} opt_eventId The optional event ID to identify on receipt.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {?Object<string, string>=} opt_additionalParams The optional\n * additional parameters.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {string} The OAuth helper widget URL.\n */\nfireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl = function(\n authDomain,\n apiKey,\n appName,\n authType,\n provider,\n opt_redirectUrl,\n opt_eventId,\n opt_clientVersion,\n opt_additionalParams,\n opt_endpointId,\n opt_tenantId) {\n // OAuth helper widget URL.\n var builder = new fireauth.iframeclient.OAuthUrlBuilder(\n authDomain, apiKey, appName, authType, provider);\n return builder\n .setRedirectUrl(opt_redirectUrl)\n .setEventId(opt_eventId)\n .setVersion(opt_clientVersion)\n .setAdditionalParameters(opt_additionalParams)\n .setEndpointId(opt_endpointId)\n .setTenantId(opt_tenantId)\n .toString();\n};\n\n\n/**\n * Post message receiver event names.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.ReceiverEvent = {\n AUTH_EVENT: 'authEvent'\n};\n\n\n/**\n * Post message sender event names.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.SenderEvent = {\n WEB_STORAGE_SUPPORT_EVENT: 'webStorageSupport'\n};\n\n\n/**\n * Post message response field names.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.Response = {\n STATUS: 'status',\n AUTH_EVENT: 'authEvent',\n WEB_STORAGE_SUPPORT: 'webStorageSupport'\n};\n\n\n/**\n * Post message status values.\n * @enum {string}\n */\nfireauth.iframeclient.IfcHandler.Status = {\n ACK: 'ACK',\n ERROR: 'ERROR'\n};\n\n\n/**\n * Registers all event listeners.\n * @private\n */\nfireauth.iframeclient.IfcHandler.prototype.registerEvents_ = function() {\n // Should be run in initialization.\n if (!this.iframeWrapper_) {\n throw new Error('IfcHandler must be initialized!');\n }\n var self = this;\n // Listen to Auth change events emitted from iframe.\n this.iframeWrapper_.registerEvent(\n fireauth.iframeclient.IfcHandler.ReceiverEvent.AUTH_EVENT,\n function(response) {\n var resolveResponse = {};\n if (response &&\n response[fireauth.iframeclient.IfcHandler.Response.AUTH_EVENT]) {\n var isHandled = false;\n // Get Auth event (plain object).\n var authEvent = fireauth.AuthEvent.fromPlainObject(\n response[fireauth.iframeclient.IfcHandler.Response.AUTH_EVENT]);\n // Trigger Auth change on all listeners.\n for (var i = 0; i < self.authEventListeners_.length; i++) {\n isHandled = self.authEventListeners_[i](authEvent) || isHandled;\n }\n // Return ack response to notify sender of success.\n resolveResponse = {};\n resolveResponse[fireauth.iframeclient.IfcHandler.Response.STATUS] =\n isHandled ? fireauth.iframeclient.IfcHandler.Status.ACK :\n fireauth.iframeclient.IfcHandler.Status.ERROR;\n return goog.Promise.resolve(resolveResponse);\n }\n // Return error status if the response is invalid.\n resolveResponse[fireauth.iframeclient.IfcHandler.Response.STATUS] =\n fireauth.iframeclient.IfcHandler.Status.ERROR;\n return goog.Promise.resolve(resolveResponse);\n });\n};\n\n\n/**\n * @return {!goog.Promise<boolean>} Whether web storage is supported in the\n * iframe.\n */\nfireauth.iframeclient.IfcHandler.prototype.isWebStorageSupported = function() {\n var webStorageSupportEvent =\n fireauth.iframeclient.IfcHandler.SenderEvent.WEB_STORAGE_SUPPORT_EVENT;\n var message = {\n 'type': webStorageSupportEvent\n };\n var self = this;\n // Initialize if not initialized yet.\n return this.initialize().then(function() {\n return self.iframeWrapper_.sendMessage(message);\n }).then(function(response) {\n // Parse the response and return the passed web storage support status.\n var key = fireauth.iframeclient.IfcHandler.Response.WEB_STORAGE_SUPPORT;\n if (response &&\n response.length &&\n typeof response[0][key] !== 'undefined') {\n return response[0][key];\n }\n // Internal error.\n throw new Error;\n });\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n * listener to add.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.addAuthEventListener =\n function(listener) {\n this.authEventListeners_.push(listener);\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n * listener to remove.\n * @override\n */\nfireauth.iframeclient.IfcHandler.prototype.removeAuthEventListener =\n function(listener) {\n goog.array.removeAllIf(this.authEventListeners_, function(ele) {\n return ele == listener;\n });\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 * @define {boolean} If true, try the native JSON parsing API first. If it\n * fails, log an error and use `eval` instead. This is useful when\n * transitioning to `goog.json.USE_NATIVE_JSON`. The error logger needs to\n * be set by `goog.json.setErrorLogger`. If it is not set then the error\n * is ignored.\n */\ngoog.json.TRY_NATIVE_JSON = goog.define('goog.json.TRY_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 // 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 * if `goog.json.TRY_NATIVE_JSON` is enabled.\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_ = goog.nullFunction;\n\n\n/**\n * Sets an error logger to use if there's a recoverable parsing error and\n * `goog.json.TRY_NATIVE_JSON` is enabled.\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 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 let error;\n if (goog.json.TRY_NATIVE_JSON) {\n try {\n return goog.global['JSON']['parse'](s);\n } catch (ex) {\n error = ex;\n }\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 // 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 /**\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 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 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 // The official JSON implementation does not work with international\n // characters.\n sb.push('\"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {\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).substr(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 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 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 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 2017 Google Inc.\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 * @fileoverview Defines utility and helper functions.\n */\n\ngoog.provide('fireauth.util');\n\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.Uri');\ngoog.require('goog.dom');\ngoog.require('goog.events');\ngoog.require('goog.events.EventType');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.json');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.require('goog.window');\n\n\n/** @suppress {duplicate} Suppress variable 'angular' first declared. */\nvar angular;\n\n/**\n * Checks whether the user agent is IE11.\n * @return {boolean} True if it is IE11.\n */\nfireauth.util.isIe11 = function() {\n return goog.userAgent.IE &&\n !!goog.userAgent.DOCUMENT_MODE &&\n goog.userAgent.DOCUMENT_MODE == 11;\n};\n\n\n/**\n * Checks whether the user agent is IE10.\n * @return {boolean} True if it is IE10.\n */\nfireauth.util.isIe10 = function() {\n return goog.userAgent.IE &&\n !!goog.userAgent.DOCUMENT_MODE &&\n goog.userAgent.DOCUMENT_MODE == 10;\n};\n\n\n/**\n * Checks whether the user agent is Edge.\n * @param {string} userAgent The browser user agent string.\n * @return {boolean} True if it is Edge.\n */\nfireauth.util.isEdge = function(userAgent) {\n return /Edge\\/\\d+/.test(userAgent);\n};\n\n\n/**\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {boolean} Whether local storage is not synchronized between an iframe\n * and a popup of the same domain.\n */\nfireauth.util.isLocalStorageNotSynchronized = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n return fireauth.util.isIe11() || fireauth.util.isEdge(ua);\n};\n\n\n/** @return {string} The current URL. */\nfireauth.util.getCurrentUrl = function() {\n return (goog.global['window'] && goog.global['window']['location']['href']) ||\n // Check for worker environments.\n (self && self['location'] && self['location']['href']) || '';\n};\n\n\n/**\n * @param {string} requestUri The request URI to send in verifyAssertion\n * request.\n * @return {string} The sanitized URI, in this case it undoes the hashbang\n * angularJs routing changes to request URI.\n */\nfireauth.util.sanitizeRequestUri = function(requestUri) {\n // If AngularJS is included.\n if (typeof angular != 'undefined') {\n // Remove hashbang modifications from URL.\n requestUri = requestUri.replace('#/', '#').replace('#!/', '#');\n }\n return requestUri;\n};\n\n\n/**\n * @param {?string} url The target URL. When !url, redirects to a blank page.\n * @param {!Window=} opt_window The optional window to redirect to target URL.\n * @param {boolean=} opt_bypassCheck Whether to bypass check. Used for custom\n * scheme redirects.\n */\nfireauth.util.goTo = function(url, opt_window, opt_bypassCheck) {\n var win = opt_window || goog.global['window'];\n // No URL, redirect to blank page.\n var finalUrl = 'about:blank';\n // Popping up a window and then assigning its URL seems to cause some weird\n // error. Fixed by setting win.location.href for now in IE browsers.\n // Bug was detected in Edge and IE9.\n if (url && !opt_bypassCheck) {\n // We cannot use goog.dom.safe.setLocationHref since it tries to read\n // popup.location from a different origin, which is an error in IE.\n // (In Chrome, popup.location is just an empty Location object)\n finalUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url));\n }\n win.location.href = finalUrl;\n};\n\n\n/**\n * @param {string} url The target URL.\n * @param {!Window=} opt_window The optional window to replace with target URL.\n * @param {boolean=} opt_bypassCheck Whether to bypass check. Used for custom\n * scheme redirects.\n */\nfireauth.util.replaceCurrentUrl = function(url, opt_window, opt_bypassCheck) {\n var win = opt_window || goog.global['window'];\n if (!opt_bypassCheck) {\n win.location.replace(\n goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url)));\n } else {\n win.location.replace(url);\n }\n};\n\n\n/**\n * Deep comparison of two objects.\n * @param {!Object} a The first object.\n * @param {!Object} b The second object.\n * @return {!Array<string>} The list of keys that are different between both\n * objects provided.\n */\nfireauth.util.getKeyDiff = function(a, b) {\n var diff = [];\n for (var k in a) {\n if (!(k in b)) {\n diff.push(k);\n } else if (typeof a[k] != typeof b[k]) {\n diff.push(k);\n } else if (typeof a[k] == 'object' && a[k] != null && b[k] != null) {\n if (fireauth.util.getKeyDiff(\n a[k], b[k]).length > 0) {\n diff.push(k);\n }\n } else if (a[k] !== b[k]) {\n diff.push(k);\n }\n }\n for (var k in b) {\n if (!(k in a)) {\n diff.push(k);\n }\n }\n return diff;\n};\n\n\n/**\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {?number} The Chrome version, null if the user agent is not Chrome.\n */\nfireauth.util.getChromeVersion = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n var browserName = fireauth.util.getBrowserName(ua);\n // Confirm current browser is Chrome.\n if (browserName != fireauth.util.BrowserName.CHROME) {\n return null;\n }\n var matches = ua.match(/\\sChrome\\/(\\d+)/i);\n if (matches && matches.length == 2) {\n return parseInt(matches[1], 10);\n }\n return null;\n};\n\n\n/**\n * Detects CORS support.\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {boolean} True if the browser supports CORS.\n */\nfireauth.util.supportsCors = function(opt_userAgent) {\n // Chrome 7 has CORS issues, pick 30 as upper limit.\n var chromeVersion = fireauth.util.getChromeVersion(opt_userAgent);\n if (chromeVersion && chromeVersion < 30) {\n return false;\n }\n // Among all other supported browsers, only IE8 and IE9 don't support CORS.\n return !goog.userAgent.IE || // Not IE.\n !goog.userAgent.DOCUMENT_MODE || // No document mode == IE Edge.\n goog.userAgent.DOCUMENT_MODE > 9;\n};\n\n\n/**\n * Detects whether browser is running on a mobile device.\n * @param {?string=} opt_userAgent The navigator user agent.\n * @return {boolean} True if the browser is running on a mobile device.\n */\nfireauth.util.isMobileBrowser = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n var uaLower = ua.toLowerCase();\n // TODO: implement getBrowserName equivalent for OS.\n if (uaLower.match(/android/) ||\n uaLower.match(/webos/) ||\n uaLower.match(/iphone|ipad|ipod/) ||\n uaLower.match(/blackberry/) ||\n uaLower.match(/windows phone/) ||\n uaLower.match(/iemobile/)) {\n return true;\n }\n return false;\n};\n\n\n/**\n * Closes the provided window.\n * @param {?Window=} opt_window The optional window to close. The current window\n * is used if none is provided.\n */\nfireauth.util.closeWindow = function(opt_window) {\n var win = opt_window || goog.global['window'];\n // In some browsers, in certain cases after the window closes, as seen in\n // Samsung Galaxy S3 Android 4.4.2 stock browser, the win object here is an\n // empty object {}. Try to catch the failure and ignore it.\n try {\n win.close();\n } catch(e) {}\n};\n\n\n/**\n * Opens a popup window.\n * @param {?string=} opt_url initial URL of the popup window\n * @param {string=} opt_name title of the popup\n * @param {?number=} opt_width width of the popup\n * @param {?number=} opt_height height of the popup\n * @return {?Window} Returns the window object that was opened. This returns\n * null if a popup blocker prevented the window from being\n * opened.\n */\nfireauth.util.popup = function(opt_url, opt_name, opt_width, opt_height) {\n var width = opt_width || 500;\n var height = opt_height || 600;\n var top = (window.screen.availHeight - height) / 2;\n var left = (window.screen.availWidth - width) / 2;\n var options = {\n 'width': width,\n 'height': height,\n 'top': top > 0 ? top : 0,\n 'left': left > 0 ? left : 0,\n 'location': true,\n 'resizable': true,\n 'statusbar': true,\n 'toolbar': false\n };\n // Chrome iOS 7 and 8 is returning an undefined popup win when target is\n // specified, even though the popup is not necessarily blocked.\n var ua = fireauth.util.getUserAgentString().toLowerCase();\n if (opt_name) {\n options['target'] = opt_name;\n // This will force a new window on each call, achieving the same effect as\n // passing a random name on each call.\n if (goog.string.contains(ua, 'crios/')) {\n options['target'] = '_blank';\n }\n }\n var browserName = fireauth.util.getBrowserName(\n fireauth.util.getUserAgentString());\n if (browserName == fireauth.util.BrowserName.FIREFOX) {\n // Firefox complains when invalid URLs are popped out. Hacky way to bypass.\n opt_url = opt_url || 'http://localhost';\n // Firefox disables by default scrolling on popup windows, which can create\n // issues when the user has many Google accounts, for instance.\n options['scrollbars'] = true;\n }\n // about:blank getting sanitized causing browsers like IE/Edge to display\n // brief error message before redirecting to handler.\n var newWin = goog.window.open(opt_url || '', options);\n if (newWin) {\n // Flaky on IE edge, encapsulate with a try and catch.\n try {\n newWin.focus();\n } catch (e) {}\n }\n return newWin;\n};\n\n\n/**\n * The default value for the popup wait cycle in ms.\n * @const {number}\n * @private\n */\nfireauth.util.POPUP_WAIT_CYCLE_MS_ = 2000;\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the popup requires a delay before closing itself.\n */\nfireauth.util.requiresPopupDelay = function(opt_userAgent) {\n // TODO: remove this hack when CriOS behavior is fixed in iOS.\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n // Was observed in iOS 10.2 Chrome version 55.0.2883.79.\n // Apply to Chrome 55+ iOS 10+ to ensure future Chrome versions or iOS 10\n // minor updates do not suddenly resurface this bug. Revisit this check on\n // next CriOS update.\n var matches = ua.match(/OS (\\d+)_.*CriOS\\/(\\d+)\\./i);\n if (matches && matches.length > 2) {\n // iOS 10+ && chrome 55+.\n return parseInt(matches[1], 10) >= 10 && parseInt(matches[2], 10) >= 55;\n }\n return false;\n};\n\n\n/**\n * @param {?Window} win The popup window to check.\n * @param {number=} opt_stepDuration The duration of each wait cycle before\n * checking that window is closed.\n * @return {!goog.Promise<undefined>} The promise to resolve when window is\n * closed.\n */\nfireauth.util.onPopupClose = function(win, opt_stepDuration) {\n var stepDuration = opt_stepDuration || fireauth.util.POPUP_WAIT_CYCLE_MS_;\n return new goog.Promise(function(resolve, reject) {\n // Function to repeat each stepDuration.\n var repeat = function() {\n goog.Timer.promise(stepDuration).then(function() {\n // After wait, check if window is closed.\n if (!win || win.closed) {\n // If so, resolve.\n resolve();\n } else {\n // Call repeat again.\n return repeat();\n }\n });\n };\n return repeat();\n });\n};\n\n\n/**\n * @param {!Array<string>} authorizedDomains List of authorized domains.\n * @param {string} url The URL to check.\n * @return {boolean} Whether the passed domain is an authorized one.\n */\nfireauth.util.isAuthorizedDomain = function(authorizedDomains, url) {\n var uri = goog.Uri.parse(url);\n var scheme = uri.getScheme();\n var domain = uri.getDomain();\n for (var i = 0; i < authorizedDomains.length; i++) {\n // Currently this corresponds to: domain.com = *://*.domain.com:* or\n // exact domain match.\n // In the case of Chrome extensions, the authorizedDomain will be formatted\n // as 'chrome-extension://abcdefghijklmnopqrstuvwxyz123456'.\n // The URL to check must have a chrome extension scheme and the domain\n // must be an exact match domain == 'abcdefghijklmnopqrstuvwxyz123456'.\n if (fireauth.util.matchDomain(authorizedDomains[i], domain, scheme)) {\n return true;\n }\n }\n return false;\n};\n\n\n/**\n * Represents the dimensions of an entity (width and height).\n * @typedef {{\n * width: number,\n * height: number\n * }}\n */\nfireauth.util.Dimensions;\n\n\n/**\n * @param {?Window=} opt_window The optional window whose dimensions are to be\n * returned. The current window is used if not found.\n * @return {?fireauth.util.Dimensions} The requested window dimensions if\n * available.\n */\nfireauth.util.getWindowDimensions = function(opt_window) {\n var win = opt_window || goog.global['window'];\n if (win && win['innerWidth'] && win['innerHeight']) {\n return {\n 'width': parseFloat(win['innerWidth']),\n 'height': parseFloat(win['innerHeight'])\n };\n }\n return null;\n};\n\n\n/**\n * RegExp to detect if the domain given is an IP address. This is only used\n * for validating http and https schemes.\n *\n * It does not strictly validate if the IP is a real IP address, but as the\n * matchDomain method tests against a set of valid domains (extracted from the\n * window's current URL), it is sufficient.\n *\n * @const {!RegExp}\n * @private\n */\nfireauth.util.IP_ADDRESS_REGEXP_ = /^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/;\n\n\n/**\n * @param {string} domainPattern The domain pattern to match.\n * @param {string} domain The domain to check. It is assumed that it is a valid\n * domain, not a user provided one.\n * @param {string} scheme The scheme of the domain to check.\n * @return {boolean} Whether the provided domain matches the domain pattern.\n */\nfireauth.util.matchDomain = function(domainPattern, domain, scheme) {\n // Chrome extension matching.\n if (domainPattern.indexOf('chrome-extension://') == 0) {\n var chromeExtUri = goog.Uri.parse(domainPattern);\n // Domain must match and the current scheme must be a Chrome extension.\n return chromeExtUri.getDomain() == domain && scheme == 'chrome-extension';\n } else if (scheme != 'http' && scheme != 'https') {\n // Any other scheme that is not http or https cannot be whitelisted.\n return false;\n } else {\n // domainPattern must not contain a scheme and the current scheme must be\n // either http or https.\n // Check if authorized domain pattern is an IP address.\n if (fireauth.util.IP_ADDRESS_REGEXP_.test(domainPattern)) {\n // The domain has to be exactly equal to the pattern, as an IP domain will\n // only contain the IP, no extra character.\n return domain == domainPattern;\n }\n // Dots in pattern should be escaped.\n var escapedDomainPattern = domainPattern.split('.').join('\\\\.');\n // Non ip address domains.\n // domain.com = *.domain.com OR domain.com\n var re = new RegExp(\n '^(.+\\\\.' + escapedDomainPattern + '|' +\n escapedDomainPattern + ')$', 'i');\n return re.test(domain);\n }\n};\n\n\n/**\n * RegExp to detect if the email address given is valid.\n * @const {!RegExp}\n * @private\n */\nfireauth.util.EMAIL_ADDRESS_REGEXP_ = /^[^@]+@[^@]+$/;\n\n\n/**\n * Determines if it is a valid email address.\n * @param {*} email The email address.\n * @return {boolean} Whether the email address is valid.\n */\nfireauth.util.isValidEmailAddress = function(email) {\n return typeof email === 'string' &&\n fireauth.util.EMAIL_ADDRESS_REGEXP_.test(email);\n};\n\n\n/**\n * @return {!goog.Promise<void>} A promise that resolves when DOM is ready.\n */\nfireauth.util.onDomReady = function() {\n var resolver = null;\n return new goog.Promise(function(resolve, reject) {\n var doc = goog.global.document;\n // If document already loaded, resolve immediately.\n if (doc.readyState == 'complete') {\n resolve();\n } else {\n // Document not ready, wait for load before resolving.\n // Save resolver, so we can remove listener in case it was externally\n // cancelled.\n resolver = function() {\n resolve();\n };\n goog.events.listenOnce(window, goog.events.EventType.LOAD, resolver);\n }\n }).thenCatch(function(error) {\n // In case this promise was cancelled, make sure it unlistens to load.\n goog.events.unlisten(window, goog.events.EventType.LOAD, resolver);\n throw error;\n });\n};\n\n\n/** @return {boolean} Whether environment supports DOM. */\nfireauth.util.isDOMSupported = function() {\n return !!goog.global.document;\n};\n\n\n/**\n * The default ondeviceready Cordova timeout in ms.\n * @const {number}\n * @private\n */\nfireauth.util.CORDOVA_ONDEVICEREADY_TIMEOUT_MS_ = 1000;\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @param {number=} opt_timeout The optional timeout in ms for deviceready\n * event to resolve.\n * @return {!goog.Promise} A promise that resolves if the current environment is\n * a Cordova environment.\n */\nfireauth.util.checkIfCordova = function(opt_userAgent, opt_timeout) {\n // Errors generated are internal and should be converted if needed to\n // developer facing Firebase errors.\n // Only supported in Android/iOS environment.\n if (fireauth.util.isAndroidOrIosCordovaScheme(opt_userAgent)) {\n return fireauth.util.onDomReady().then(function() {\n return new goog.Promise(function(resolve, reject) {\n var doc = goog.global.document;\n var timeoutId = setTimeout(function() {\n reject(new Error('Cordova framework is not ready.'));\n }, opt_timeout || fireauth.util.CORDOVA_ONDEVICEREADY_TIMEOUT_MS_);\n // This should resolve immediately after DOM ready.\n doc.addEventListener('deviceready', function() {\n clearTimeout(timeoutId);\n resolve();\n }, false);\n });\n });\n }\n return goog.Promise.reject(\n new Error('Cordova must run in an Android or iOS file scheme.'));\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the app is rendered in a mobile iOS or Android\n * Cordova environment.\n */\nfireauth.util.isAndroidOrIosCordovaScheme = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n return !!((fireauth.util.getCurrentScheme() === 'file:' ||\n fireauth.util.getCurrentScheme() === 'ionic:') &&\n ua.toLowerCase().match(/iphone|ipad|ipod|android/));\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the app is rendered in a mobile iOS 7 or 8 browser.\n */\nfireauth.util.isIOS7Or8 = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n return !!(ua.match(/(iPad|iPhone|iPod).*OS 7_\\d/i) ||\n ua.match(/(iPad|iPhone|iPod).*OS 8_\\d/i));\n};\n\n\n/**\n * @return {boolean} Whether browser is Safari or an iOS browser and page is\n * embedded in an iframe. Local Storage does not synchronize with an iframe\n * embedded on a page in a different domain but will still trigger storage\n * event with storage changes.\n */\nfireauth.util.isSafariLocalStorageNotSynced = function() {\n var ua = fireauth.util.getUserAgentString();\n // Safari or iOS browser and embedded in an iframe.\n if (!fireauth.util.iframeCanSyncWebStorage(ua) && fireauth.util.isIframe()) {\n return true;\n }\n return false;\n};\n\n\n/**\n * @param {?Window=} opt_win Optional window to check whether it is an iframe.\n * If not provided, the current window is checked.\n * @return {boolean} Whether web page is running in an iframe.\n */\nfireauth.util.isIframe = function(opt_win) {\n var win = opt_win || goog.global['window'];\n try {\n // Check that the current window is not the top window.\n // If so, return true.\n return !!(win && win != win['top']);\n } catch (e) {\n return false;\n }\n};\n\n\n/**\n * @param {?Window=} opt_win Optional window to check whether it has an opener\n * that is an iframe.\n * @return {boolean} Whether the web page was opened from an iframe.\n */\nfireauth.util.isOpenerAnIframe = function(opt_win) {\n var win = opt_win || goog.global['window'];\n try {\n // Get the opener if available.\n var opener = win && win['opener'];\n // Check if the opener is an iframe. If so, return true.\n // Confirm opener is available, otherwise the current window is checked\n // instead.\n return !!(opener && fireauth.util.isIframe(opener));\n } catch (e) {\n return false;\n }\n};\n\n\n/**\n * @param {?Object=} global The optional global scope.\n * @return {boolean} Whether current environment is a worker.\n */\nfireauth.util.isWorker = function(global) {\n var scope = global || goog.global;\n // WorkerGlobalScope only defined in worker environment.\n return typeof scope['WorkerGlobalScope'] !== 'undefined' &&\n typeof scope['importScripts'] === 'function';\n};\n\n\n/**\n * @param {?Object=} opt_global The optional global scope.\n * @return {boolean} Whether current environment supports fetch API and other\n * APIs it depends on.\n */\nfireauth.util.isFetchSupported = function(opt_global) {\n // Required by fetch API calls.\n var scope = opt_global || goog.global;\n return typeof scope['fetch'] !== 'undefined' &&\n typeof scope['Headers'] !== 'undefined' &&\n typeof scope['Request'] !== 'undefined';\n};\n\n\n/**\n * Enum for the runtime environment.\n * @enum {string}\n */\nfireauth.util.Env = {\n BROWSER: 'Browser',\n NODE: 'Node',\n REACT_NATIVE: 'ReactNative',\n WORKER: 'Worker'\n};\n\n\n/**\n * @return {!fireauth.util.Env} The current runtime environment.\n */\nfireauth.util.getEnvironment = function() {\n if (firebase.INTERNAL.hasOwnProperty('reactNative')) {\n return fireauth.util.Env.REACT_NATIVE;\n } else if (firebase.INTERNAL.hasOwnProperty('node')) {\n // browserify seems to keep the process property in some cases even though\n // the library is browser only. Use this check instead to reliably detect\n // a Node.js environment.\n return fireauth.util.Env.NODE;\n } else if (fireauth.util.isWorker()) {\n // Worker environment.\n return fireauth.util.Env.WORKER;\n }\n // The default is a browser environment.\n return fireauth.util.Env.BROWSER;\n};\n\n\n/**\n * @return {boolean} Whether the environment is a native environment, where\n * CORS checks do not apply.\n */\nfireauth.util.isNativeEnvironment = function() {\n var environment = fireauth.util.getEnvironment();\n return environment === fireauth.util.Env.REACT_NATIVE ||\n environment === fireauth.util.Env.NODE;\n};\n\n\n/**\n * The separator for storage keys to concatenate App name and API key.\n * @const {string}\n * @private\n */\nfireauth.util.STORAGE_KEY_SEPARATOR_ = ':';\n\n\n/**\n * @param {string} apiKey The API Key of the app.\n * @param {string} appName The App name.\n * @return {string} The key used for identifying the app owner of the user.\n */\nfireauth.util.createStorageKey = function(apiKey, appName) {\n return apiKey + fireauth.util.STORAGE_KEY_SEPARATOR_ + appName;\n};\n\n\n/** @return {string} a long random character string. */\nfireauth.util.generateRandomString = function() {\n return Math.floor(Math.random() * 1000000000).toString();\n};\n\n\n/**\n * Generates a random alpha numeric string.\n * @param {number} numOfChars The number of random characters within the string.\n * @return {string} A string with a specific number of random characters.\n */\nfireauth.util.generateRandomAlphaNumericString = function(numOfChars) {\n var chars = [];\n var allowedChars =\n '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n while (numOfChars > 0) {\n chars.push(\n allowedChars.charAt(\n Math.floor(Math.random() * allowedChars.length)));\n numOfChars--;\n }\n return chars.join('');\n};\n\n\n/**\n * Enums for Browser name.\n * @enum {string}\n */\nfireauth.util.BrowserName = {\n ANDROID: 'Android',\n BLACKBERRY: 'Blackberry',\n EDGE: 'Edge',\n FIREFOX: 'Firefox',\n IE: 'IE',\n IEMOBILE: 'IEMobile',\n OPERA: 'Opera',\n OTHER: 'Other',\n CHROME: 'Chrome',\n SAFARI: 'Safari',\n SILK: 'Silk',\n WEBOS: 'Webos'\n};\n\n\n/**\n * @param {string} userAgent The navigator user agent string.\n * @return {string} The browser name, eg Safari, Firefox, etc.\n */\nfireauth.util.getBrowserName = function(userAgent) {\n var ua = userAgent.toLowerCase();\n if (goog.string.contains(ua, 'opera/') ||\n goog.string.contains(ua, 'opr/') ||\n goog.string.contains(ua, 'opios/')) {\n return fireauth.util.BrowserName.OPERA;\n } else if (goog.string.contains(ua, 'iemobile')) {\n // Windows phone IEMobile browser.\n return fireauth.util.BrowserName.IEMOBILE;\n } else if (goog.string.contains(ua, 'msie') ||\n goog.string.contains(ua, 'trident/')) {\n return fireauth.util.BrowserName.IE;\n } else if (goog.string.contains(ua, 'edge/')) {\n return fireauth.util.BrowserName.EDGE;\n } else if (goog.string.contains(ua, 'firefox/')) {\n return fireauth.util.BrowserName.FIREFOX;\n } else if (goog.string.contains(ua, 'silk/')) {\n return fireauth.util.BrowserName.SILK;\n } else if (goog.string.contains(ua, 'blackberry')) {\n // Blackberry browser.\n return fireauth.util.BrowserName.BLACKBERRY;\n } else if (goog.string.contains(ua, 'webos')) {\n // WebOS default browser.\n return fireauth.util.BrowserName.WEBOS;\n } else if (goog.string.contains(ua, 'safari/') &&\n !goog.string.contains(ua, 'chrome/') &&\n !goog.string.contains(ua, 'crios/') &&\n !goog.string.contains(ua, 'android')) {\n return fireauth.util.BrowserName.SAFARI;\n } else if ((goog.string.contains(ua, 'chrome/') ||\n goog.string.contains(ua, 'crios/')) &&\n !goog.string.contains(ua, 'edge/')) {\n return fireauth.util.BrowserName.CHROME;\n } else if (goog.string.contains(ua, 'android')) {\n // Android stock browser.\n return fireauth.util.BrowserName.ANDROID;\n } else {\n // Most modern browsers have name/version at end of user agent string.\n var re = new RegExp('([a-zA-Z\\\\d\\\\.]+)\\/[a-zA-Z\\\\d\\\\.]*$');\n var matches = userAgent.match(re);\n if (matches && matches.length == 2) {\n return matches[1];\n }\n }\n return fireauth.util.BrowserName.OTHER;\n};\n\n\n/**\n * Enums for client implementation name.\n * @enum {string}\n */\nfireauth.util.ClientImplementation = {\n JSCORE: 'JsCore',\n OAUTH_HANDLER: 'Handler',\n OAUTH_IFRAME: 'Iframe'\n};\n\n\n/**\n * Enums for the framework ID to be logged in RPC header.\n * Future frameworks to possibly add: angularfire, polymerfire, reactfire, etc.\n * @enum {string}.\n */\nfireauth.util.Framework = {\n // No other framework used.\n DEFAULT: 'FirebaseCore-web',\n // Firebase Auth used with FirebaseUI-web.\n FIREBASEUI: 'FirebaseUI-web'\n};\n\n\n/**\n * @param {!Array<string>} providedFrameworks List of framework ID strings.\n * @return {!Array<!fireauth.util.Framework>} List of supported framework IDs\n * with no duplicates.\n */\nfireauth.util.getFrameworkIds = function(providedFrameworks) {\n var frameworkVersion = [];\n var frameworkSet = {};\n for (var key in fireauth.util.Framework) {\n frameworkSet[fireauth.util.Framework[key]] = true;\n }\n for (var i = 0; i < providedFrameworks.length; i++) {\n if (typeof frameworkSet[providedFrameworks[i]] !== 'undefined') {\n // Delete it from set to prevent duplications.\n delete frameworkSet[providedFrameworks[i]];\n frameworkVersion.push(providedFrameworks[i]);\n }\n }\n // Sort alphabetically so that \"FirebaseCore-web,FirebaseUI-web\" and\n // \"FirebaseUI-web,FirebaseCore-web\" aren't viewed as different.\n frameworkVersion.sort();\n return frameworkVersion;\n};\n\n\n/**\n * @param {!fireauth.util.ClientImplementation} clientImplementation The client\n * implementation.\n * @param {string} clientVersion The client version.\n * @param {?Array<string>=} opt_frameworkVersion The framework version.\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {string} The full client SDK version.\n */\nfireauth.util.getClientVersion = function(clientImplementation, clientVersion,\n opt_frameworkVersion, opt_userAgent) {\n var frameworkVersion = fireauth.util.getFrameworkIds(\n opt_frameworkVersion || []);\n if (!frameworkVersion.length) {\n frameworkVersion = [fireauth.util.Framework.DEFAULT];\n }\n var environment = fireauth.util.getEnvironment();\n var reportedEnvironment = '';\n if (environment === fireauth.util.Env.BROWSER) {\n // In a browser environment, report the browser name.\n var userAgent = opt_userAgent || fireauth.util.getUserAgentString();\n reportedEnvironment = fireauth.util.getBrowserName(userAgent);\n } else if (environment === fireauth.util.Env.WORKER) {\n // Technically a worker runs from a browser but we need to differentiate a\n // worker from a browser.\n // For example: Chrome-Worker/JsCore/4.9.1/FirebaseCore-web.\n var userAgent = opt_userAgent || fireauth.util.getUserAgentString();\n reportedEnvironment = fireauth.util.getBrowserName(userAgent) + '-' +\n environment;\n } else {\n // Otherwise, just report the environment name.\n reportedEnvironment = environment;\n }\n // The format to be followed:\n // ${browserName}/${clientImplementation}/${clientVersion}/${frameworkVersion}\n // As multiple Firebase frameworks/libraries can be used, join their IDs with\n // a comma.\n return reportedEnvironment + '/' + clientImplementation +\n '/' + clientVersion + '/' + frameworkVersion.join(',');\n};\n\n\n/**\n * @return {string} The user agent string reported by the environment, or the\n * empty string if not available.\n */\nfireauth.util.getUserAgentString = function() {\n return (goog.global['navigator'] && goog.global['navigator']['userAgent']) ||\n '';\n};\n\n\n/**\n * @param {string} varStrName The variable string name.\n * @param {?Object=} opt_scope The optional scope where to look in. The default\n * is window.\n * @return {*} The reference if found.\n */\nfireauth.util.getObjectRef = function(varStrName, opt_scope) {\n var pieces = varStrName.split('.');\n var last = opt_scope || goog.global;\n for (var i = 0;\n i < pieces.length && typeof last == 'object' && last != null;\n i++) {\n last = last[pieces[i]];\n }\n // Last hasn't reached the end yet, return undefined.\n if (i != pieces.length) {\n last = undefined;\n }\n return last;\n};\n\n\n/** @return {boolean} Whether web storage is supported. */\nfireauth.util.isWebStorageSupported = function() {\n try {\n var storage = goog.global['localStorage'];\n var key = fireauth.util.generateEventId();\n if (storage) {\n // setItem will throw an exception if we cannot access WebStorage (e.g.,\n // Safari in private mode).\n storage['setItem'](key, '1');\n storage['removeItem'](key);\n // For browsers where iframe web storage does not synchronize with a popup\n // of the same domain, indexedDB is used for persistent storage. These\n // browsers include IE11 and Edge.\n // Make sure it is supported (IE11 and Edge private mode does not support\n // that).\n if (fireauth.util.isLocalStorageNotSynchronized()) {\n // In such browsers, if indexedDB is not supported, an iframe cannot be\n // notified of the popup sign in result.\n return !!goog.global['indexedDB'];\n }\n return true;\n }\n } catch (e) {\n // localStorage is not available from a worker. Test availability of\n // indexedDB.\n return fireauth.util.isWorker() && !!goog.global['indexedDB'];\n }\n return false;\n};\n\n\n/**\n * This guards against leaking Cordova support before official launch.\n * This field will be removed or updated to return true when the new feature is\n * ready for launch.\n * @return {boolean} Whether Cordova OAuth support is enabled.\n */\nfireauth.util.isCordovaOAuthEnabled = function() {\n return false;\n};\n\n\n/**\n * @return {boolean} Whether popup and redirect operations are supported in the\n * current environment.\n */\nfireauth.util.isPopupRedirectSupported = function() {\n // Popup and redirect are supported in an environment where the container\n // origin can be securely whitelisted.\n return (fireauth.util.isHttpOrHttps() ||\n fireauth.util.isChromeExtension() ||\n fireauth.util.isAndroidOrIosCordovaScheme()) &&\n // React Native with remote debugging reports its location.protocol as\n // http.\n !fireauth.util.isNativeEnvironment() &&\n // Local storage has to be supported for browser popup and redirect\n // operations to work.\n fireauth.util.isWebStorageSupported() &&\n // DOM, popups and redirects are not supported within a worker.\n !fireauth.util.isWorker();\n};\n\n\n/**\n * @return {boolean} Whether the current environment is http or https.\n */\nfireauth.util.isHttpOrHttps = function() {\n return fireauth.util.getCurrentScheme() === 'http:' ||\n fireauth.util.getCurrentScheme() === 'https:';\n};\n\n\n/** @return {?string} The current URL scheme. */\nfireauth.util.getCurrentScheme = function() {\n return (goog.global['location'] && goog.global['location']['protocol']) ||\n null;\n};\n\n\n/**\n * Checks whether the current page is a Chrome extension.\n * @return {boolean} Whether the current page is a Chrome extension.\n */\nfireauth.util.isChromeExtension = function() {\n return fireauth.util.getCurrentScheme() === 'chrome-extension:';\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the current browser is running in an iOS\n * environment.\n */\nfireauth.util.isIOS = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n return !!ua.toLowerCase().match(/iphone|ipad|ipod/);\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the current browser is running in an Android\n * environment.\n */\nfireauth.util.isAndroid = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n return !!ua.toLowerCase().match(/android/);\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether the opener of a popup cannot communicate with the\n * popup while it is in the foreground.\n */\nfireauth.util.runsInBackground = function(opt_userAgent) {\n // TODO: split this check into 2, one check that opener can access\n // popup, another check that storage synchronizes between popup and opener.\n // Popup events fail in iOS version 7 (lowest version we currently support)\n // browsers. When the popup is triggered, the opener is unable to redirect\n // the popup url, close the popup and in some cases will miss the storage\n // event triggered when localStorage is changed.\n // Extend this to all mobile devices. This behavior is more likely to work\n // cross mobile platforms.\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n if (fireauth.util.isMobileBrowser(ua)) {\n return false;\n } else if (fireauth.util.getBrowserName(ua) ==\n fireauth.util.BrowserName.FIREFOX) {\n // Latest version of Firefox 47.0 does not allow you to access properties on\n // the popup window from the opener.\n return false;\n }\n return true;\n};\n\n\n/**\n * Stringifies an object, retuning null if the object is not defined.\n * @param {*} obj The raw object.\n * @return {?string} The JSON-serialized object.\n */\nfireauth.util.stringifyJSON = function(obj) {\n if (typeof obj === 'undefined') {\n return null;\n }\n return goog.json.serialize(obj);\n};\n\n\n/**\n * @param {!Object} obj The original object.\n * @return {!Object} A copy of the original object with all entries that are\n * null or undefined removed.\n */\nfireauth.util.copyWithoutNullsOrUndefined = function(obj) {\n // The processed copy to return.\n var trimmedObj = {};\n // Remove all empty fields from data, allow zero and false booleans.\n for (var key in obj) {\n if (obj.hasOwnProperty(key) &&\n obj[key] !== null &&\n obj[key] !== undefined) {\n trimmedObj[key] = obj[key];\n }\n }\n return trimmedObj;\n};\n\n\n/**\n * Removes all key/pairs with the specified keys from the given object.\n * @param {!Object} obj The object to process.\n * @param {!Array<string>} keys The list of keys to remove.\n * @return {!Object} The object with the keys removed.\n */\nfireauth.util.removeEntriesWithKeys = function(obj, keys) {\n // Clone object.\n var copy = goog.object.clone(obj);\n // Traverse keys.\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n // If key found in object, remove it.\n if (key in copy) {\n delete copy[key];\n }\n }\n // Returned filtered copy.\n return copy;\n};\n\n\n/**\n * Parses a JSON string, returning undefined if null is passed.\n * @param {?string} json The JSON-serialized object.\n * @return {*} The raw object.\n */\nfireauth.util.parseJSON = function(json) {\n if (json === null) {\n return undefined;\n }\n\n // Do not use goog.json.parse since it uses eval underneath to support old\n // browsers that do not provide JSON.parse. The recommended Content Security\n // Policy does not allow unsafe-eval in some environments like Chrome\n // extensions. Usage of eval is not recommend in Chrome in general.\n // Use native parsing instead via JSON.parse. This is provided in our list\n // of supported browsers.\n return JSON.parse(json);\n};\n\n\n/**\n * @param {?string=} opt_prefix An optional prefix string to prepend to ID.\n * @return {string} The generated event ID used to identify a generic event.\n */\nfireauth.util.generateEventId = function(opt_prefix) {\n return opt_prefix ? opt_prefix : '' +\n Math.floor(Math.random() * 1000000000).toString();\n};\n\n\n/**\n * @param {?string=} opt_userAgent The optional user agent.\n * @return {boolean} Whether an embedded iframe can sync to web storage changes.\n * Web storage sync fails in Safari desktop browsers and iOS mobile\n * browsers.\n */\nfireauth.util.iframeCanSyncWebStorage = function(opt_userAgent) {\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n if (fireauth.util.getBrowserName(ua) == fireauth.util.BrowserName.SAFARI ||\n ua.toLowerCase().match(/iphone|ipad|ipod/)) {\n return false;\n }\n return true;\n};\n\n\n/**\n * Reset unlaoded GApi modules. If gapi.load fails due to a network error,\n * it will stop working after a retrial. This is a hack to fix this issue.\n */\nfireauth.util.resetUnloadedGapiModules = function() {\n // Clear last failed gapi.load state to force next gapi.load to first\n // load the failed gapi.iframes module.\n // Get gapix.beacon context.\n var beacon = goog.global['___jsl'];\n // Get current hint.\n if (beacon && beacon['H']) {\n // Get gapi hint.\n for (var hint in beacon['H']) {\n // Requested modules.\n beacon['H'][hint]['r'] = beacon['H'][hint]['r'] || [];\n // Loaded modules.\n beacon['H'][hint]['L'] = beacon['H'][hint]['L'] || [];\n // Set requested modules to a copy of the loaded modules.\n beacon['H'][hint]['r'] = beacon['H'][hint]['L'].concat();\n // Clear pending callbacks.\n if (beacon['CP']) {\n for (var i = 0; i < beacon['CP'].length; i++) {\n // Remove all failed pending callbacks.\n beacon['CP'][i] = null;\n }\n }\n }\n }\n};\n\n\n/**\n * Returns whether the current device is a mobile device. Mobile browsers and\n * React-Native environments are considered mobile devices.\n * @param {?string=} opt_userAgent The optional navigator user agent.\n * @param {?fireauth.util.Env=} opt_env The optional environment.\n * @return {boolean} Whether the current device is a mobile device or not.\n */\nfireauth.util.isMobileDevice = function(opt_userAgent, opt_env) {\n // Get user agent.\n var ua = opt_userAgent || fireauth.util.getUserAgentString();\n // Get environment.\n var environment = opt_env || fireauth.util.getEnvironment();\n return fireauth.util.isMobileBrowser(ua) ||\n environment === fireauth.util.Env.REACT_NATIVE;\n};\n\n\n/**\n * @param {?Object=} opt_navigator The optional navigator object typically used\n * for testing.\n * @return {boolean} Whether the app is currently online. If offline, false is\n * returned. If this cannot be determined, true is returned.\n */\nfireauth.util.isOnline = function(opt_navigator) {\n var navigator = opt_navigator || goog.global['navigator'];\n if (navigator &&\n typeof navigator['onLine'] === 'boolean' &&\n // Apply only for traditional web apps and Chrome extensions.\n // This is especially true for Cordova apps which have unreliable\n // navigator.onLine behavior unless cordova-plugin-network-information is\n // installed which overwrites the native navigator.onLine value and\n // defines navigator.connection.\n (fireauth.util.isHttpOrHttps() ||\n fireauth.util.isChromeExtension() ||\n typeof navigator['connection'] !== 'undefined')) {\n return navigator['onLine'];\n }\n // If we can't determine the state, assume it is online.\n return true;\n};\n\n\n/**\n * @param {?Object=} opt_navigator The object with navigator data, defaulting\n * to window.navigator if unspecified.\n * @return {?string} The user's preferred language. Returns null if\n */\nfireauth.util.getUserLanguage = function(opt_navigator) {\n var navigator = opt_navigator || goog.global['navigator'];\n if (!navigator) {\n return null;\n }\n return (\n // Most reliable, but only supported in Chrome/Firefox.\n navigator['languages'] && navigator['languages'][0] ||\n // Supported in most browsers, but returns the language of the browser\n // UI, not the language set in browser settings.\n navigator['language'] ||\n // IE <= 10.\n navigator['userLanguage'] ||\n // Couldn't determine language.\n null\n );\n};\n\n\n/**\n * A structure to help pick between a range of long and short delay durations\n * depending on the current environment. In general, the long delay is used for\n * mobile environments whereas short delays are used for desktop environments.\n * @param {number} shortDelay The short delay duration.\n * @param {number} longDelay The long delay duration.\n * @param {?string=} opt_userAgent The optional navigator user agent.\n * @param {?fireauth.util.Env=} opt_env The optional environment.\n * @constructor\n */\nfireauth.util.Delay = function(shortDelay, longDelay, opt_userAgent, opt_env) {\n // Internal error when improperly initialized.\n if (shortDelay > longDelay) {\n throw new Error('Short delay should be less than long delay!');\n }\n /**\n * @private @const {number} The short duration delay used for desktop\n * environments.\n */\n this.shortDelay_ = shortDelay;\n /**\n * @private @const {number} The long duration delay used for mobile\n * environments.\n */\n this.longDelay_ = longDelay;\n /** @private @const {boolean} Whether the environment is a mobile one. */\n this.isMobile_ = fireauth.util.isMobileDevice(opt_userAgent, opt_env);\n};\n\n\n/**\n * The default value for the offline delay timeout in ms.\n * @const {number}\n * @private\n */\nfireauth.util.Delay.OFFLINE_DELAY_MS_ = 5000;\n\n\n/**\n * @return {number} The delay that matches with the current environment.\n */\nfireauth.util.Delay.prototype.get = function() {\n // navigator.onLine is unreliable in some cases.\n // Failing hard in those cases may make it impossible to recover for end user.\n // Waiting for the regular full duration when there is no network can result\n // in a bad experience.\n // Instead return a short timeout duration. If there is no network connection,\n // the user would wait 5 seconds to detect that. If there is a connection\n // (false alert case), the user still has the ability to try to send the\n // request. If it fails (timeout too short), they can still retry.\n if (!fireauth.util.isOnline()) {\n // Pick the shorter timeout.\n return Math.min(fireauth.util.Delay.OFFLINE_DELAY_MS_, this.shortDelay_);\n }\n // If running in a mobile environment, return the long delay, otherwise\n // return the short delay.\n // This could be improved in the future to dynamically change based on other\n // variables instead of just reading the current environment.\n return this.isMobile_ ? this.longDelay_ : this.shortDelay_;\n};\n\n\n/**\n * @return {boolean} Whether the app is visible in the foreground. This uses\n * document.visibilityState. For browsers that do not support it, this is\n * always true.\n */\nfireauth.util.isAppVisible = function() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilityState\n var doc = goog.global.document;\n // Check if supported.\n if (doc && typeof doc['visibilityState'] !== 'undefined') {\n // Check if visible.\n return doc['visibilityState'] == 'visible';\n }\n // API not supported in current browser, default to true.\n return true;\n};\n\n\n/**\n * @return {!goog.Promise} A promise that resolves when the app is visible in\n * the foreground.\n */\nfireauth.util.onAppVisible = function() {\n var doc = goog.global.document;\n // Visibility change listener reference.\n var onVisibilityChange = null;\n if (fireauth.util.isAppVisible() || !doc) {\n // Visible or non browser environment.\n return goog.Promise.resolve();\n } else {\n // Invisible and in browser environment.\n return new goog.Promise(function(resolve, reject) {\n // On visibility change listener.\n onVisibilityChange = function(event) {\n // App is visible.\n if (fireauth.util.isAppVisible()) {\n // Unregister event listener.\n doc.removeEventListener(\n 'visibilitychange', onVisibilityChange, false);\n // Resolve promise.\n resolve();\n }\n };\n // Listen to visibility change.\n doc.addEventListener('visibilitychange', onVisibilityChange, false);\n }).thenCatch(function(error) {\n // In case this promise was cancelled, make sure it unlistens to\n // visibilitychange event.\n doc.removeEventListener('visibilitychange', onVisibilityChange, false);\n // Rethrow the same error.\n throw error;\n });\n }\n};\n\n\n/**\n * Logs a warning message to the console, if the console is available.\n * @param {string} message\n */\nfireauth.util.consoleWarn = function(message) {\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(message);\n }\n};\n\n\n/**\n * Parses a UTC time stamp string or number and returns the corresponding UTC\n * date string if valid. Otherwise, returns null.\n * @param {?string|number} utcTimestamp The UTC timestamp number or string.\n * @return {?string} The corresponding UTC date string. Null if invalid.\n */\nfireauth.util.utcTimestampToDateString = function(utcTimestamp) {\n try {\n // Convert to date object.\n var date = new Date(parseInt(utcTimestamp, 10));\n // Test date is valid.\n if (!isNaN(date.getTime()) &&\n // Confirm that utcTimestamp is numeric.\n goog.string.isNumeric(utcTimestamp)) {\n // Convert to UTC date string.\n return date.toUTCString();\n }\n } catch (e) {\n // Do nothing. null will be returned.\n }\n return null;\n};\n\n\n/** @return {boolean} Whether indexedDB is available. */\nfireauth.util.isIndexedDBAvailable = function() {\n return !!goog.global['indexedDB'];\n};\n\n\n/** @return {boolean} Whether current mode is Auth handler or iframe. */\nfireauth.util.isAuthHandlerOrIframe = function() {\n return !!(fireauth.util.getObjectRef('fireauth.oauthhelper', goog.global) ||\n fireauth.util.getObjectRef('fireauth.iframe', goog.global));\n};\n\n\n/** @return {boolean} Whether indexedDB is used to persist storage. */\nfireauth.util.persistsStorageWithIndexedDB = function() {\n // This will cover:\n // IE11, Edge when indexedDB is available (this is unavailable in InPrivate\n // mode). (SDK, OAuth handler and iframe)\n // Any environment where indexedDB is available (SDK only).\n\n // In a browser environment, when an iframe and a popup web storage are not\n // synchronized, use the indexedDB fireauth.storage.Storage implementation.\n return (fireauth.util.isLocalStorageNotSynchronized() ||\n !fireauth.util.isAuthHandlerOrIframe()) &&\n fireauth.util.isIndexedDBAvailable();\n};\n\n\n/** Sets the no-referrer meta tag in the document head if applicable. */\nfireauth.util.setNoReferrer = function() {\n var doc = goog.global.document;\n if (doc) {\n try {\n var meta = goog.dom.createDom(goog.dom.TagName.META, {\n 'name': 'referrer',\n 'content': 'no-referrer'\n });\n var headCollection = goog.dom.getElementsByTagName(goog.dom.TagName.HEAD);\n // Append meta tag to head.\n if (headCollection.length) {\n headCollection[0].appendChild(meta);\n }\n } catch (e) {\n // Best effort approach.\n }\n }\n};\n\n\n/** @return {?ServiceWorker} The servicerWorker controller if available. */\nfireauth.util.getServiceWorkerController = function() {\n var navigator = goog.global['navigator'];\n return (navigator &&\n navigator.serviceWorker &&\n navigator.serviceWorker.controller) || null;\n};\n\n\n/** @return {?WorkerGlobalScope} The worker global scope if available. */\nfireauth.util.getWorkerGlobalScope = function() {\n return fireauth.util.isWorker() ? /** @type {!WorkerGlobalScope} */ (self) :\n null;\n};\n\n/**\n * @return {!goog.Promise<?ServiceWorker>} A promise that resolves with the\n * service worker. This will resolve only when a service worker becomes\n * available. If no service worker is supported, it will resolve with null.\n */\nfireauth.util.getActiveServiceWorker = function() {\n var navigator = goog.global['navigator'];\n if (navigator && navigator.serviceWorker) {\n return goog.Promise.resolve()\n .then(function() {\n return navigator.serviceWorker.ready;\n })\n .then(function(registration) {\n return /** @type {?ServiceWorker} */ (registration.active || null);\n })\n .thenCatch(function(error) {\n return null;\n });\n }\n return goog.Promise.resolve(/** @type {?ServiceWorker} */ (null));\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for window manipulation.\n */\n\n\ngoog.provide('goog.window');\n\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.SafeUrl');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.string');\ngoog.require('goog.string.Const');\ngoog.require('goog.userAgent');\n\n\n/**\n * Default height for popup windows\n * @type {number}\n */\ngoog.window.DEFAULT_POPUP_HEIGHT = 500;\n\n\n/**\n * Default width for popup windows\n * @type {number}\n */\ngoog.window.DEFAULT_POPUP_WIDTH = 690;\n\n\n/**\n * Default target for popup windows\n * @type {string}\n */\ngoog.window.DEFAULT_POPUP_TARGET = 'google_popup';\n\n\n/**\n * @return {!Window}\n * @suppress {checkTypes}\n * @private\n */\ngoog.window.createFakeWindow_ = function() {\n return /** @type {!Window} */ ({});\n};\n\n/**\n * Opens a new window.\n *\n * @param {!goog.html.SafeUrl|string|!Object|null} linkRef If an Object with an\n * 'href' attribute (such as HTMLAnchorElement) is passed then the value of\n * 'href' is used, otherwise its toString method is called. Note that if a\n * string|Object is used, it will be sanitized with SafeUrl.sanitize().\n *\n * @param {?Object=} opt_options supports the following options:\n * 'target': (string) target (window name). If null, linkRef.target will\n * be used.\n * 'width': (number) window width.\n * 'height': (number) window height.\n * 'top': (number) distance from top of screen\n * 'left': (number) distance from left of screen\n * 'toolbar': (boolean) show toolbar\n * 'scrollbars': (boolean) show scrollbars\n * 'location': (boolean) show location\n * 'statusbar': (boolean) show statusbar\n * 'menubar': (boolean) show menubar\n * 'resizable': (boolean) resizable\n * 'noreferrer': (boolean) whether to attempt to remove the referrer header\n * from the request headers. Does this by opening a blank window that\n * then redirects to the target url, so users may see some flickering.\n * 'noopener': (boolean) whether to remove the `opener` property from the\n * window object of the newly created window. The property contains a\n * reference to the original window, and can be used to launch a\n * reverse tabnabbing attack.\n *\n * @param {?Window=} opt_parentWin Parent window that should be used to open the\n * new window.\n *\n * @return {?Window} Returns the window object that was opened. This returns\n * null if a popup blocker prevented the window from being\n * opened. In case when a new window is opened in a different\n * browser sandbox (such as iOS standalone mode), the returned\n * object is a emulated Window object that functions as if\n * a cross-origin window has been opened.\n */\ngoog.window.open = function(linkRef, opt_options, opt_parentWin) {\n if (!opt_options) {\n opt_options = {};\n }\n var parentWin = opt_parentWin || window;\n\n /** @type {!goog.html.SafeUrl} */\n var safeLinkRef;\n\n if (linkRef instanceof goog.html.SafeUrl) {\n safeLinkRef = linkRef;\n } else {\n // HTMLAnchorElement has a toString() method with the same behavior as\n // goog.Uri in all browsers except for Safari, which returns\n // '[object HTMLAnchorElement]'. We check for the href first, then\n // assume that it's a goog.Uri or String otherwise.\n /**\n * @type {string|!goog.string.TypedString}\n * @suppress {missingProperties}\n */\n var url =\n typeof linkRef.href != 'undefined' ? linkRef.href : String(linkRef);\n safeLinkRef = goog.html.SafeUrl.sanitize(url);\n }\n\n /** @suppress {missingProperties} loose references to 'target' */\n /** @suppress {strictMissingProperties} */\n var target = opt_options.target || linkRef.target;\n\n var sb = [];\n for (var option in opt_options) {\n switch (option) {\n case 'width':\n case 'height':\n case 'top':\n case 'left':\n sb.push(option + '=' + opt_options[option]);\n break;\n case 'target':\n case 'noopener':\n case 'noreferrer':\n break;\n default:\n sb.push(option + '=' + (opt_options[option] ? 1 : 0));\n }\n }\n var optionString = sb.join(',');\n\n var newWin;\n if (goog.labs.userAgent.platform.isIos() && parentWin.navigator &&\n parentWin.navigator['standalone'] && target && target != '_self') {\n // iOS in standalone mode disregards \"target\" in window.open and always\n // opens new URL in the same window. The workaround is to create an \"A\"\n // element and send a click event to it.\n // Notice that the \"A\" tag does NOT have to be added to the DOM.\n\n var a = goog.dom.createElement(goog.dom.TagName.A);\n goog.dom.safe.setAnchorHref(a, safeLinkRef);\n\n a.setAttribute('target', target);\n if (opt_options['noreferrer']) {\n a.setAttribute('rel', 'noreferrer');\n }\n\n var click = /** @type {!MouseEvent} */ (document.createEvent('MouseEvent'));\n click.initMouseEvent(\n 'click',\n true, // canBubble\n true, // cancelable\n parentWin,\n 1); // detail = mousebutton\n a.dispatchEvent(click);\n // New window is not available in this case. Instead, a fake Window object\n // is returned. In particular, it will have window.document undefined. In\n // general, it will appear to most of clients as a Window for a different\n // origin. Since iOS standalone web apps are run in their own sandbox, this\n // is the most appropriate return value.\n newWin = goog.window.createFakeWindow_();\n } else if (opt_options['noreferrer']) {\n // This code used to use meta-refresh to stop the referrer from being\n // included in the request headers. This was the only cross-browser way\n // to remove the referrer circa 2009. However, this never worked in Chrome,\n // and, instead newWin.opener had to be set to null on this browser. This\n // behavior is slated to be removed in Chrome and should not be relied\n // upon. Referrer Policy is the only spec'd and supported way of stripping\n // referrers and works across all current browsers. This is used in\n // addition to the aforementioned tricks.\n //\n // We also set the opener to be set to null in the new window, thus\n // disallowing the opened window from navigating its opener.\n //\n // Detecting user agent and then using a different strategy per browser\n // would allow the referrer to leak in case of an incorrect/missing user\n // agent.\n //\n // Also note that we can't use goog.dom.safe.openInWindow here, as it\n // requires a goog.string.Const 'name' parameter, while we're using plain\n // strings here for target.\n newWin = parentWin.open('', target, optionString);\n\n var sanitizedLinkRef = goog.html.SafeUrl.unwrap(safeLinkRef);\n if (newWin) {\n if (goog.userAgent.EDGE_OR_IE) {\n // IE/EDGE can't parse the content attribute if the url contains\n // a semicolon. We can fix this by adding quotes around the url, but\n // then we can't parse quotes in the URL correctly. We take a\n // best-effort approach.\n //\n // If the URL has semicolons, wrap it in single quotes to protect\n // the semicolons.\n // If the URL has semicolons and single quotes, url-encode the single\n // quotes as well.\n //\n // This is imperfect. Notice that both ' and ; are reserved characters\n // in URIs, so this could do the wrong thing, but at least it will\n // do the wrong thing in only rare cases.\n // ugh.\n if (goog.string.contains(sanitizedLinkRef, ';')) {\n sanitizedLinkRef = \"'\" + sanitizedLinkRef.replace(/'/g, '%27') + \"'\";\n }\n }\n newWin.opener = null;\n\n // TODO(rjamet): Building proper SafeHtml with SafeHtml.createMetaRefresh\n // pulls in a lot of compiled code, which is composed of various unneeded\n // goog.html parts such as SafeStyle.create among others. So, for now,\n // keep the unchecked conversion until we figure out how to make the\n // dependencies of createSafeHtmlTagSecurityPrivateDoNotAccessOrElse less\n // heavy.\n var safeHtml =\n goog.html.uncheckedconversions\n .safeHtmlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from(\n 'b/12014412, meta tag with sanitized URL'),\n '<meta name=\"referrer\" content=\"no-referrer\">' +\n '<meta http-equiv=\"refresh\" content=\"0; url=' +\n goog.string.htmlEscape(sanitizedLinkRef) + '\">');\n\n // During window loading `newWin.document` may be unset in some browsers.\n // Storing and checking a reference to the document prevents NPEs.\n var newDoc = newWin.document;\n if (newDoc) {\n goog.dom.safe.documentWrite(newDoc, safeHtml);\n newDoc.close();\n }\n }\n } else {\n newWin = parentWin.open(\n goog.html.SafeUrl.unwrap(safeLinkRef), target, optionString);\n // Passing in 'noopener' into the 'windowFeatures' param of window.open(...)\n // will yield a feature-deprived browser. This is an known issue, tracked\n // here: https://github.com/whatwg/html/issues/1902\n if (newWin && opt_options['noopener']) {\n newWin.opener = null;\n }\n }\n // newWin is null if a popup blocker prevented the window open.\n return newWin;\n};\n\n\n/**\n * Opens a new window without any real content in it.\n *\n * This can be used to get around popup blockers if you need to open a window\n * in response to a user event, but need to do asynchronous work to determine\n * the URL to open, and then set the URL later.\n *\n * Example usage:\n *\n * var newWin = goog.window.openBlank('Loading...');\n * setTimeout(\n * function() {\n * newWin.location.href = 'http://www.google.com';\n * }, 100);\n *\n * @param {string=} opt_message String to show in the new window. This string\n * will be HTML-escaped to avoid XSS issues.\n * @param {?Object=} opt_options Options to open window with.\n * {@see goog.window.open for exact option semantics}.\n * @param {?Window=} opt_parentWin Parent window that should be used to open the\n * new window.\n * @return {?Window} Returns the window object that was opened. This returns\n * null if a popup blocker prevented the window from being\n * opened.\n */\ngoog.window.openBlank = function(opt_message, opt_options, opt_parentWin) {\n // Open up a window with the loading message and nothing else.\n // This will be interpreted as HTML content type with a missing doctype\n // and html/body tags, but is otherwise acceptable.\n //\n // IMPORTANT: The order of escaping is crucial here in order to avoid XSS.\n // First, HTML-escaping is needed because the result of the JS expression\n // is evaluated as HTML. Second, JS-string escaping is needed; this avoids\n // \\u escaping from inserting HTML tags and \\ from escaping the final \".\n // Finally, URL percent-encoding is done with encodeURI(); this\n // avoids percent-encoding from bypassing HTML and JS escaping.\n //\n // Note: There are other ways the same result could be achieved but the\n // current behavior was preserved when this code was refactored to use\n // SafeUrl, in order to avoid breakage.\n var loadingMessage;\n if (!opt_message) {\n loadingMessage = '';\n } else {\n loadingMessage =\n goog.string.escapeString(goog.string.htmlEscape(opt_message));\n }\n var url = goog.html.uncheckedconversions\n .safeUrlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from(\n 'b/12014412, encoded string in javascript: URL'),\n 'javascript:\"' + encodeURI(loadingMessage) + '\"');\n return /** @type {?Window} */ (\n goog.window.open(url, opt_options, opt_parentWin));\n};\n\n\n/**\n * Raise a help popup window, defaulting to \"Google standard\" size and name.\n *\n * (If your project is using GXPs, consider using {@link PopUpLink.gxp}.)\n *\n* @param {?goog.html.SafeUrl|string|?Object} linkRef If an Object with an 'href'\n * attribute (such as HTMLAnchorElement) is passed then the value of 'href'\n * is used, otherwise otherwise its toString method is called. Note that\n * if a string|Object is used, it will be sanitized with SafeUrl.sanitize().\n *\n * @param {?Object=} opt_options Options to open window with.\n * {@see goog.window.open for exact option semantics}\n * Additional wrinkles to the options:\n * - if 'target' field is null, linkRef.target will be used. If *that's*\n * null, the default is \"google_popup\".\n * - if 'width' field is not specified, the default is 690.\n * - if 'height' field is not specified, the default is 500.\n *\n * @return {boolean} true if the window was not popped up, false if it was.\n */\ngoog.window.popup = function(linkRef, opt_options) {\n if (!opt_options) {\n opt_options = {};\n }\n\n // set default properties\n opt_options['target'] = opt_options['target'] || linkRef['target'] ||\n goog.window.DEFAULT_POPUP_TARGET;\n opt_options['width'] =\n opt_options['width'] || goog.window.DEFAULT_POPUP_WIDTH;\n opt_options['height'] =\n opt_options['height'] || goog.window.DEFAULT_POPUP_HEIGHT;\n\n var newWin = goog.window.open(linkRef, opt_options);\n if (!newWin) {\n return true;\n }\n newWin.focus();\n\n return false;\n};\n","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\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 * @fileoverview Closure user agent platform detection.\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>\n * For more information on browser brand, rendering engine, or device see the\n * other sub-namespaces in goog.labs.userAgent (browser, engine, and device\n * respectively).\n */\n\ngoog.provide('goog.labs.userAgent.platform');\n\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.string');\n\n\n/**\n * @return {boolean} Whether the platform is Android.\n */\ngoog.labs.userAgent.platform.isAndroid = function() {\n return goog.labs.userAgent.util.matchUserAgent('Android');\n};\n\n\n/**\n * @return {boolean} Whether the platform is iPod.\n */\ngoog.labs.userAgent.platform.isIpod = function() {\n return goog.labs.userAgent.util.matchUserAgent('iPod');\n};\n\n\n/**\n * @return {boolean} Whether the platform is iPhone.\n */\ngoog.labs.userAgent.platform.isIphone = function() {\n return goog.labs.userAgent.util.matchUserAgent('iPhone') &&\n !goog.labs.userAgent.util.matchUserAgent('iPod') &&\n !goog.labs.userAgent.util.matchUserAgent('iPad');\n};\n\n\n/**\n * @return {boolean} Whether the platform is iPad.\n */\ngoog.labs.userAgent.platform.isIpad = function() {\n return goog.labs.userAgent.util.matchUserAgent('iPad');\n};\n\n\n/**\n * @return {boolean} Whether the platform is iOS.\n */\ngoog.labs.userAgent.platform.isIos = function() {\n return goog.labs.userAgent.platform.isIphone() ||\n goog.labs.userAgent.platform.isIpad() ||\n goog.labs.userAgent.platform.isIpod();\n};\n\n\n/**\n * @return {boolean} Whether the platform is Mac.\n */\ngoog.labs.userAgent.platform.isMacintosh = function() {\n return goog.labs.userAgent.util.matchUserAgent('Macintosh');\n};\n\n\n/**\n * Note: ChromeOS is not considered to be Linux as it does not report itself\n * as Linux in the user agent string.\n * @return {boolean} Whether the platform is Linux.\n */\ngoog.labs.userAgent.platform.isLinux = function() {\n return goog.labs.userAgent.util.matchUserAgent('Linux');\n};\n\n\n/**\n * @return {boolean} Whether the platform is Windows.\n */\ngoog.labs.userAgent.platform.isWindows = function() {\n return goog.labs.userAgent.util.matchUserAgent('Windows');\n};\n\n\n/**\n * @return {boolean} Whether the platform is ChromeOS.\n */\ngoog.labs.userAgent.platform.isChromeOS = function() {\n return goog.labs.userAgent.util.matchUserAgent('CrOS');\n};\n\n/**\n * @return {boolean} Whether the platform is Chromecast.\n */\ngoog.labs.userAgent.platform.isChromecast = function() {\n return goog.labs.userAgent.util.matchUserAgent('CrKey');\n};\n\n/**\n * @return {boolean} Whether the platform is KaiOS.\n */\ngoog.labs.userAgent.platform.isKaiOS = function() {\n return goog.labs.userAgent.util.matchUserAgentIgnoreCase('KaiOS');\n};\n\n/**\n * The version of the platform. We only determine the version for Windows,\n * Mac, and Chrome OS. It doesn't make much sense on Linux. For Windows, we only\n * look at the NT version. Non-NT-based versions (e.g. 95, 98, etc.) are given\n * version 0.0.\n *\n * @return {string} The platform version or empty string if version cannot be\n * determined.\n */\ngoog.labs.userAgent.platform.getVersion = function() {\n var userAgentString = goog.labs.userAgent.util.getUserAgent();\n var version = '', re;\n if (goog.labs.userAgent.platform.isWindows()) {\n re = /Windows (?:NT|Phone) ([0-9.]+)/;\n var match = re.exec(userAgentString);\n if (match) {\n version = match[1];\n } else {\n version = '0.0';\n }\n } else if (goog.labs.userAgent.platform.isIos()) {\n re = /(?:iPhone|iPod|iPad|CPU)\\s+OS\\s+(\\S+)/;\n var match = re.exec(userAgentString);\n // Report the version as x.y.z and not x_y_z\n version = match && match[1].replace(/_/g, '.');\n } else if (goog.labs.userAgent.platform.isMacintosh()) {\n re = /Mac OS X ([0-9_.]+)/;\n var match = re.exec(userAgentString);\n // Note: some old versions of Camino do not report an OSX version.\n // Default to 10.\n version = match ? match[1].replace(/_/g, '.') : '10';\n } else if (goog.labs.userAgent.platform.isKaiOS()) {\n re = /(?:KaiOS)\\/(\\S+)/i;\n var match = re.exec(userAgentString);\n version = match && match[1];\n } else if (goog.labs.userAgent.platform.isAndroid()) {\n re = /Android\\s+([^\\);]+)(\\)|;)/;\n var match = re.exec(userAgentString);\n version = match && match[1];\n } else if (goog.labs.userAgent.platform.isChromeOS()) {\n re = /(?:CrOS\\s+(?:i686|x86_64)\\s+([0-9.]+))/;\n var match = re.exec(userAgentString);\n version = match && match[1];\n }\n return version || '';\n};\n\n\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 */\ngoog.labs.userAgent.platform.isVersionOrHigher = function(version) {\n return goog.string.compareVersions(\n goog.labs.userAgent.platform.getVersion(), version) >= 0;\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the mock grecaptcha utilities used for development\n * testing.\n */\ngoog.provide('fireauth.GRecaptchaMockFactory');\ngoog.provide('fireauth.RecaptchaMock');\n\ngoog.require('fireauth.grecaptcha');\ngoog.require('fireauth.util');\ngoog.require('goog.dom');\ngoog.require('goog.events');\ngoog.require('goog.events.EventType');\n\n\n/**\n * The mock grecaptcha factory.\n * @constructor\n * @implements {fireauth.grecaptcha}\n */\nfireauth.GRecaptchaMockFactory = function() {\n /**\n * @const @private {!Object<string, !fireauth.RecaptchaMock>} The hash map\n * that stores the widget ID to mock reCAPTCHA instances.\n */\n this.map_ = {};\n /**\n * @private {number} The current widget ID counter, incremented each time\n * a new mock reCAPTCHA is created.\n */\n this.counter_ = fireauth.GRecaptchaMockFactory.START_INSTANCE_ID;\n};\n\n\n/**\n * @const {number} The start ID of the first created mock reCAPTCHA.\n */\nfireauth.GRecaptchaMockFactory.START_INSTANCE_ID = 1000000000000;\n\n\n/** @const {number} The reCAPTCHA expiration time in milliseconds. */\nfireauth.GRecaptchaMockFactory.EXPIRATION_TIME_MS = 60000;\n\n\n/** @const {number} The reCAPTCHA auto solving time in milliseconds. */\nfireauth.GRecaptchaMockFactory.SOLVE_TIME_MS = 500;\n\n\n/**\n * @private {?fireauth.GRecaptchaMockFactory} The singleton instance\n * for grecaptcha mock object.\n */\nfireauth.GRecaptchaMockFactory.instance_ = null;\n\n\n/**\n * @return {!fireauth.GRecaptchaMockFactory} The singleton grecaptcha mock\n * instance.\n */\nfireauth.GRecaptchaMockFactory.getInstance = function() {\n // Check if there is an existing instance. Otherwise, create one and cache it.\n if (!fireauth.GRecaptchaMockFactory.instance_) {\n fireauth.GRecaptchaMockFactory.instance_ =\n new fireauth.GRecaptchaMockFactory();\n }\n return fireauth.GRecaptchaMockFactory.instance_;\n};\n\n\n/**\n * Creates a new instance of the mock reCAPTCHA widget.\n *\n * @param {(!Element|string)} elementOrId Element or element ID for the\n * placeholder to render the reCAPTCHA client.\n * @param {!Object} params Parameters for the reCAPTCHA client.\n * @return {number} The client ID.\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.render =\n function(elementOrId, params) {\n this.map_[this.counter_.toString()] =\n new fireauth.RecaptchaMock(elementOrId, params);\n return this.counter_++;\n};\n\n\n/**\n * Resets a reCAPTCHA with the given ID. If an ID is not provided, resets the\n * first instance.\n *\n * @param {number=} opt_id The id of the reCAPTCHA client. Defaults to the first\n * widget created if unspecified.\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.reset = function(opt_id) {\n var mock = this.getMock_(opt_id);\n var id = this.getId_(opt_id);\n if (mock && id) {\n mock.delete();\n delete this.map_[/** @type {string} */ (id)];\n }\n};\n\n\n/**\n * Gets the response for the client with the given ID. If an ID is not\n * provided, gets the response for the default client.\n *\n * @param {number=} opt_id The ID of the reCAPTCHA widget. Defaults to the first\n * widget created if unspecified.\n * @return {?string}\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.getResponse = function(opt_id) {\n var mock = this.getMock_(opt_id);\n return mock ? mock.getResponse() : null;\n};\n\n\n/**\n * Programmatically triggers the invisible reCAPTCHA.\n *\n * @param {number=} opt_id The ID of the recaptcha client. Defaults to the first\n * widget created if unspecified.\n * @override\n */\nfireauth.GRecaptchaMockFactory.prototype.execute = function(opt_id) {\n var mock = this.getMock_(opt_id);\n if (mock) {\n mock.execute();\n }\n};\n\n\n/**\n * @param {number=} opt_id The optional ID to lookup.\n * @return {?fireauth.RecaptchaMock} The corresponding reCAPTCHA mock if found.\n * @private\n */\nfireauth.GRecaptchaMockFactory.prototype.getMock_ = function(opt_id) {\n var id = this.getId_(opt_id);\n return id ? this.map_[id] || null : null;\n};\n\n\n/**\n * @param {number=} opt_id The optional ID to lookup.\n * @return {?string} The corresponding reCAPTCHA mock ID if found.\n * @private\n */\nfireauth.GRecaptchaMockFactory.prototype.getId_ = function(opt_id) {\n var id = typeof opt_id === 'undefined' ?\n fireauth.GRecaptchaMockFactory.START_INSTANCE_ID : opt_id;\n return id ? id.toString() : null;\n};\n\n\n/**\n * Mock single reCAPTCHA instance.\n * @param {(!Element|string)} elementOrId Element or element ID for the\n * placeholder to render the reCAPTCHA client.\n * @param {!Object} params Parameters for the reCAPTCHA client.\n * @constructor\n */\nfireauth.RecaptchaMock = function(elementOrId, params) {\n /** @private {boolean} Whether the instance was deleted. */\n this.deleted_ = false;\n /** @const @private {!Object} The reCAPTCHA parameters. */\n this.params_ = params;\n /** @private {?string} The simulated response token if available. */\n this.responseToken_ = null;\n /**\n * @private {?number} The timer ID for response callback/expiration callback\n * to trigger.\n */\n this.timerId_ = null;\n /** @const @private {boolean} Whether the reCAPTCHA is visible or not. */\n this.isVisible_ = this.params_['size'] !== 'invisible';\n /**\n * @const @private {?Element} The container or button trigger of the\n * reCAPTCHA.\n */\n this.element_ = goog.dom.getElement(elementOrId);\n var self = this;\n /** @private {function(?)} The on click handler for invisible reCAPTCHAs. */\n this.onClickHandler_ = function(event) {\n self.execute();\n };\n if (this.isVisible_) {\n // For a visible reCAPTCHA, simulate reCAPTCHA continuously solved\n // and then expired.\n this.execute();\n } else {\n // Trigger on button click on when execute is directly called.\n goog.events.listen(\n this.element_,\n goog.events.EventType.CLICK,\n this.onClickHandler_);\n }\n};\n\n\n/** @return {?string} The current reCAPTCHA response. */\nfireauth.RecaptchaMock.prototype.getResponse = function() {\n this.checkIfDeleted_();\n return this.responseToken_;\n};\n\n\n/** Starts the reCAPTCHA mock solving/expiration cycle. */\nfireauth.RecaptchaMock.prototype.execute = function() {\n this.checkIfDeleted_();\n var self = this;\n if (this.timerId_) {\n return;\n }\n // Wait for expected delay before auto-solving.\n this.timerId_ = setTimeout(function() {\n // Generate random string as reCAPTCHA response token.\n self.responseToken_ = fireauth.util.generateRandomAlphaNumericString(50);\n // Trigger developer's callbacks.\n var callback = self.params_['callback'];\n var expirationCallback = self.params_['expired-callback'];\n if (callback) {\n try {\n callback(self.responseToken_);\n } catch (e) {}\n }\n // Wait for token to expire before triggering expiration callback and\n // resetting token response.\n self.timerId_ = setTimeout(function() {\n self.timerId_ = null;\n self.responseToken_ = null;\n if (expirationCallback) {\n try {\n expirationCallback();\n } catch (e) {}\n }\n if (self.isVisible_) {\n self.execute();\n }\n }, fireauth.GRecaptchaMockFactory.EXPIRATION_TIME_MS);\n }, fireauth.GRecaptchaMockFactory.SOLVE_TIME_MS);\n};\n\n\n/** Deletes the current mock instance. */\nfireauth.RecaptchaMock.prototype.delete = function() {\n this.checkIfDeleted_();\n this.deleted_ = true;\n clearTimeout(this.timerId_);\n this.timerId_ = null;\n goog.events.unlisten(\n this.element_,\n goog.events.EventType.CLICK,\n this.onClickHandler_);\n};\n\n\n/**\n * Checks whether the instance was deleted.\n * @private\n */\nfireauth.RecaptchaMock.prototype.checkIfDeleted_ = function() {\n // This error should never be thrown externally.\n // GRecaptchaMockFactory will ensure that a deleted instance is removed.\n if (this.deleted_) {\n throw new Error('reCAPTCHA mock was already deleted!');\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Provides utilities for displaying deprecation notices.\n */\ngoog.provide('fireauth.deprecation');\ngoog.provide('fireauth.deprecation.Deprecations');\ngoog.require('fireauth.util');\n\n\n/**\n * An enum of valid notices to display. All deprecation notices must be in this\n * enum. Deprecation messages should be unique and provide the full context\n * of what is deprecated (e.g. the fully qualified path to a method).\n * @enum {string}\n */\nfireauth.deprecation.Deprecations = {\n LINK_WITH_CREDENTIAL: 'firebase.User.prototype.linkAndRetrieveDataWithCrede' +\n 'ntial is deprecated. Please use firebase.User.prototype.linkWithCreden' +\n 'tial instead.',\n REAUTH_WITH_CREDENTIAL: 'firebase.User.prototype.reauthenticateAndRetrieveD' +\n 'ataWithCredential is deprecated. Please use firebase.User.prototype.re' +\n 'authenticateWithCredential instead.',\n SIGN_IN_WITH_CREDENTIAL: 'firebase.auth.Auth.prototype.signInAndRetrieveDat' +\n 'aWithCredential is deprecated. Please use firebase.auth.Auth.prototype' +\n '.signInWithCredential instead.'\n};\n\n\n/**\n * Keeps track of notices that were already displayed.\n * @type {!Object<fireauth.deprecation.Deprecations, boolean>}\n * @private\n */\nfireauth.deprecation.shownMessages_ = {};\n\n\n/**\n * Logs a deprecation notice to the developer.\n * @param {!fireauth.deprecation.Deprecations} message\n */\nfireauth.deprecation.log = function(message) {\n if (fireauth.deprecation.shownMessages_[message]) {\n return;\n }\n fireauth.deprecation.shownMessages_[message] = true;\n fireauth.util.consoleWarn(message);\n};\n\n\n/**\n * Resets the displayed deprecation notices.\n */\nfireauth.deprecation.resetForTesting = function() {\n fireauth.deprecation.shownMessages_ =\n /** @type {!Object<fireauth.deprecation.Deprecations, boolean>} */ ({});\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Provides methods for manipulating objects.\n */\n\ngoog.provide('fireauth.object');\n\ngoog.require('fireauth.deprecation');\ngoog.require('fireauth.deprecation.Deprecations');\n\n\n/**\n * Checks whether the defineProperty method allows to change the value of\n * the property.\n * @return {boolean} Whether the defineProperty method allows to change the\n * value of the property.\n * @private\n */\nfireauth.object.isReadonlyConfigurable_ = function() {\n // Android 2.3 stock browser doesn't allow to change the value of\n // a read-only property once defined.\n try {\n var obj = {};\n Object.defineProperty(obj, 'abcd', {\n configurable: true,\n enumerable: true,\n value: 1\n });\n Object.defineProperty(obj, 'abcd', {\n configurable: true,\n enumerable: true,\n value: 2\n });\n return obj['abcd'] == 2;\n } catch (e) {\n return false;\n }\n};\n\n\n/**\n * @private {boolean} Whether the defineProperty method allows to change the\n * value of the property.\n */\nfireauth.object.readonlyConfigurable_ =\n fireauth.object.isReadonlyConfigurable_();\n\n\n/**\n * Defines a property on an object that is not writable by clients. However, the\n * property can be overwritten within the Firebase library through subsequent\n * calls to setReadonlyProperty.\n *\n * In browsers that do not support read-only properties (notably IE8 and below),\n * fall back to writable properties.\n *\n * @param {!Object} obj The object to which we add the property.\n * @param {string} key The name of the property.\n * @param {*} value The desired value.\n */\nfireauth.object.setReadonlyProperty = function(obj, key, value) {\n if (fireauth.object.readonlyConfigurable_) {\n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: true,\n value: value\n });\n } else {\n obj[key] = value;\n }\n};\n\n\n/**\n * Defines a deprecated property, which emits a warning if the developer tries\n * to use it.\n *\n * In browsers that do not support getters, we fall back to a normal property\n * with no message.\n *\n * @param {!Object} obj The object to which we add the property.\n * @param {string} key The name of the deprecated property.\n * @param {*} value The desired value.\n * @param {!fireauth.deprecation.Deprecations} deprecationMessage The\n * deprecation warning to display.\n */\nfireauth.object.setDeprecatedReadonlyProperty = function(obj, key, value,\n deprecationMessage) {\n if (fireauth.object.readonlyConfigurable_) {\n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: true,\n get: function() {\n fireauth.deprecation.log(deprecationMessage);\n return value;\n }\n });\n } else {\n obj[key] = value;\n }\n};\n\n\n/**\n * Defines properties on an object that are not writable by clients, equivalent\n * to many calls to setReadonlyProperty.\n * @param {!Object} obj The object to which we add the properties.\n * @param {?Object<string, *>} props An object that maps the keys and values\n * that we wish to add.\n */\nfireauth.object.setReadonlyProperties = function(obj, props) {\n if (!props) {\n return;\n }\n\n for (var key in props) {\n if (props.hasOwnProperty(key)) {\n fireauth.object.setReadonlyProperty(obj, key, props[key]);\n }\n }\n};\n\n\n/**\n * Makes a shallow read-only copy of an object. The writability of any child\n * objects will not be affected.\n * @param {?Object} obj The object that we wish to copy.\n * @return {!Object}\n */\nfireauth.object.makeReadonlyCopy = function(obj) {\n var output = {};\n fireauth.object.setReadonlyProperties(output, obj);\n return output;\n};\n\n\n/**\n * Makes a shallow writable copy of a read-only object. The writability of any\n * child objects will not be affected.\n * @param {?Object} obj The object that we wish to copy.\n * @return {!Object}\n */\nfireauth.object.makeWritableCopy = function(obj) {\n var output = {};\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n output[key] = obj[key];\n }\n }\n return output;\n};\n\n\n/**\n * Returns true if the all the specified fields are present in obj and are not\n * null, undefined, or the empty string. If the field list is empty, returns\n * true regardless of the value of obj.\n * @param {?Object=} opt_obj The object.\n * @param {?Array<string>=} opt_fields The desired fields of the object.\n * @return {boolean} True if obj has all the specified fields.\n */\nfireauth.object.hasNonEmptyFields = function(opt_obj, opt_fields) {\n if (!opt_fields || !opt_fields.length) {\n return true;\n }\n if (!opt_obj) {\n return false;\n }\n for (var i = 0; i < opt_fields.length; i++) {\n var field = opt_obj[opt_fields[i]];\n if (field === undefined || field === null || field === '') {\n return false;\n }\n }\n return true;\n};\n\n\n/**\n * Traverses the specified object and creates a read-only deep copy of it.\n * This will fail when circular references are contained within the object.\n * @param {*} obj The object to make a read-only copy from.\n * @return {*} A Read-only copy of the obj specified.\n */\nfireauth.object.unsafeCreateReadOnlyCopy = function(obj) {\n var copy = obj;\n if (typeof obj == 'object' && obj != null) {\n // Make the right type of copy.\n copy = 'length' in obj ? [] : {};\n // Make a deep copy.\n for (var key in obj) {\n fireauth.object.setReadonlyProperty(\n copy, key, fireauth.object.unsafeCreateReadOnlyCopy(obj[key]));\n }\n }\n // Return the copy.\n return copy;\n};\n\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the multi-factor enrollment information.\n */\n\ngoog.provide('fireauth.MultiFactorInfo');\ngoog.provide('fireauth.PhoneMultiFactorInfo');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.object');\n\n\n/**\n * Abstract class representing a `firebase.auth.MultiFactorInfo` interface.\n * This is typically parsed from a server response.\n * @param {?Object} resp The server response.\n * @abstract\n * @constructor\n */\nfireauth.MultiFactorInfo = function(resp) {\n var factorId = resp && this.getFactorId(resp);\n if (factorId && resp &&\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID]) {\n fireauth.object.setReadonlyProperty(\n this,\n 'uid',\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID]);\n fireauth.object.setReadonlyProperty(\n this,\n 'displayName',\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.DISPLAY_NAME] || null);\n var enrollmentTime = null;\n // Encoded using [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format.\n // For example, \"2017-01-15T01:30:15.01Z\".\n // This can be parsed directly in modern browsers via Date constructor.\n // This can be computed using Data.prototype.toISOString.\n if (resp[fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT]) {\n enrollmentTime = new Date(\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT])\n .toUTCString();\n }\n fireauth.object.setReadonlyProperty(\n this,\n 'enrollmentTime',\n enrollmentTime);\n fireauth.object.setReadonlyProperty(\n this,\n 'factorId',\n factorId);\n } else {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'Internal assert: invalid MultiFactorInfo object');\n }\n};\n\n\n/** @return {!Object} The plain object representation. */\nfireauth.MultiFactorInfo.prototype.toPlainObject = function() {\n return {\n 'uid': this['uid'],\n 'displayName': this['displayName'],\n 'factorId': this['factorId'],\n 'enrollmentTime': this['enrollmentTime']\n };\n};\n\n\n/**\n * Returns the factor ID based on the server response. This function needs to be\n * implemented by the subclass.\n * @param {!Object} resp The server response.\n * @return {?fireauth.constants.SecondFactorType} The factor ID based on the\n * response type.\n * @protected\n */\nfireauth.MultiFactorInfo.prototype.getFactorId = goog.abstractMethod;\n\n\n/**\n * Returns the corresponding `firebase.auth.MultiFactor` instance if the\n * server response maps to one. Otherwise, null is returned.\n * @param {?Object} resp The server response.\n * @return {?fireauth.MultiFactorInfo} The corresponding\n * `firebase.auth.MultiFactorInfo` instance, null otherwise.\n */\nfireauth.MultiFactorInfo.fromServerResponse = function(resp) {\n var multiFactorInfo;\n // Only PhoneMultiFactorInfo currently available.\n try {\n multiFactorInfo = new fireauth.PhoneMultiFactorInfo(resp);\n } catch (e) {\n multiFactorInfo = null;\n }\n return multiFactorInfo;\n};\n\n\n/**\n * Returns the corresponding `firebase.auth.MultiFactor` instance if the\n * plain object maps to one. Otherwise, null is returned.\n * @param {?Object} obj The plain object representation.\n * @return {?fireauth.MultiFactorInfo} The corresponding\n * `firebase.auth.MultiFactorInfo` instance, null otherwise.\n */\nfireauth.MultiFactorInfo.fromPlainObject = function(obj) {\n var multiFactorInfo = null;\n var resp = {};\n if (!obj) {\n return null;\n }\n if (obj['uid']) {\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.MFA_ENROLLMENT_ID] =\n obj['uid'];\n }\n if (obj['displayName']) {\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.DISPLAY_NAME] =\n obj['displayName'];\n }\n if (obj['enrollmentTime']) {\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.ENROLLED_AT] =\n new Date(obj['enrollmentTime']).toISOString();\n }\n if (obj['phoneNumber']) {\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO] =\n obj['phoneNumber'];\n }\n\n // Only PhoneMultiFactorInfo currently available.\n try {\n multiFactorInfo = new fireauth.PhoneMultiFactorInfo(resp);\n } catch (e) {\n // Ignore error.\n }\n return multiFactorInfo;\n};\n\n\n/**\n * MfaEnrollment server side response fields.\n * @enum {string}\n */\nfireauth.MultiFactorInfo.MfaEnrollmentField = {\n DISPLAY_NAME: 'displayName',\n ENROLLED_AT: 'enrolledAt',\n MFA_ENROLLMENT_ID: 'mfaEnrollmentId',\n PHONE_INFO: 'phoneInfo'\n};\n\n\n/**\n * Initializes a `firebase.auth.PhoneMultiFactorInfo` instance from the provided\n * server response.\n * @param {?Object} resp The server response.\n * @constructor\n * @extends {fireauth.MultiFactorInfo}\n */\nfireauth.PhoneMultiFactorInfo = function(resp) {\n fireauth.PhoneMultiFactorInfo.base(this, 'constructor', resp);\n fireauth.object.setReadonlyProperty(\n this,\n 'phoneNumber',\n // PhoneInfo may be masked for security reasons for sign-in flows after\n // the user signs in with the first factor but hasn't yet proven ownership\n // of the second factor yet.\n // For enrollment flows or for a user already signed in with a second\n // factor, this field should not be masked.\n resp[fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO]);\n};\ngoog.inherits(\n fireauth.PhoneMultiFactorInfo, fireauth.MultiFactorInfo);\n\n\n/**\n * Implements the factor ID getter based on the response. If the response is an\n * invalid PhoneMultiFactorInfo, null is returned.\n * @param {!Object} resp The server response.\n * @return {?fireauth.constants.SecondFactorType} The phone factor ID.\n * @protected\n * @override\n */\nfireauth.PhoneMultiFactorInfo.prototype.getFactorId = function(resp) {\n return !!resp[fireauth.MultiFactorInfo.MfaEnrollmentField.PHONE_INFO] ?\n fireauth.constants.SecondFactorType.PHONE : null;\n};\n\n\n/**\n * @return {!Object} The plain object representation.\n * @override\n */\nfireauth.PhoneMultiFactorInfo.prototype.toPlainObject = function() {\n var obj = fireauth.PhoneMultiFactorInfo.base(this, 'toPlainObject');\n obj['phoneNumber'] = this['phoneNumber'];\n return obj;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the firebase.auth.ActionCodeInfo class that is returned\n * when calling checkActionCode API and is populated from the server response\n * directly.\n */\n\ngoog.provide('fireauth.ActionCodeInfo');\n\ngoog.require('fireauth.MultiFactorInfo');\ngoog.require('fireauth.object');\n\n\n/**\n * Constructs the action code info object which provides metadata corresponding\n * to action codes. This includes the type of operation (RESET_PASSWORD,\n * VERIFY_EMAIL and RECOVER_EMAIL), the email corresponding to the operation\n * and in case of the recover email flow, the old and new email.\n * @param {!Object} response The server response for checkActionCode.\n * @constructor\n */\nfireauth.ActionCodeInfo = function(response) {\n var data = {};\n // Original email for email change revocation.\n var email = response[fireauth.ActionCodeInfo.ServerFieldName.EMAIL];\n // The new email.\n var newEmail = response[fireauth.ActionCodeInfo.ServerFieldName.NEW_EMAIL];\n var operation =\n response[fireauth.ActionCodeInfo.ServerFieldName.REQUEST_TYPE];\n // The multi-factor info for revert second factor addition.\n var mfaInfo =\n fireauth.MultiFactorInfo.fromServerResponse(\n response[fireauth.ActionCodeInfo.ServerFieldName.MFA_INFO]);\n // Email could be empty only if the request type is EMAIL_SIGNIN or\n // VERIFY_AND_CHANGE_EMAIL.\n // New email should not be empty if the request type is\n // VERIFY_AND_CHANGE_EMAIL.\n // Multi-factor info could not be empty if the request type is\n // REVERT_SECOND_FACTOR_ADDITION.\n if (!operation ||\n (operation != fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN &&\n operation != fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL &&\n !email) ||\n (operation == fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL &&\n !newEmail) ||\n (operation ==\n fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION &&\n !mfaInfo)) {\n // This is internal only.\n throw new Error('Invalid checkActionCode response!');\n }\n if (operation == fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL) {\n data[fireauth.ActionCodeInfo.DataField.FROM_EMAIL] = email || null;\n data[fireauth.ActionCodeInfo.DataField.PREVIOUS_EMAIL] = email || null;\n data[fireauth.ActionCodeInfo.DataField.EMAIL] = newEmail;\n } else {\n data[fireauth.ActionCodeInfo.DataField.FROM_EMAIL] = newEmail || null;\n data[fireauth.ActionCodeInfo.DataField.PREVIOUS_EMAIL] = newEmail || null;\n data[fireauth.ActionCodeInfo.DataField.EMAIL] = email || null;\n }\n data[fireauth.ActionCodeInfo.DataField.MULTI_FACTOR_INFO] = mfaInfo || null;\n fireauth.object.setReadonlyProperty(\n this,\n fireauth.ActionCodeInfo.PropertyName.OPERATION,\n operation);\n fireauth.object.setReadonlyProperty(\n this,\n fireauth.ActionCodeInfo.PropertyName.DATA,\n fireauth.object.unsafeCreateReadOnlyCopy(data));\n};\n\n\n/**\n * Firebase Auth Action Code Info operation possible values.\n * @enum {string}\n */\nfireauth.ActionCodeInfo.Operation = {\n PASSWORD_RESET: 'PASSWORD_RESET',\n RECOVER_EMAIL: 'RECOVER_EMAIL',\n REVERT_SECOND_FACTOR_ADDITION: 'REVERT_SECOND_FACTOR_ADDITION',\n EMAIL_SIGNIN: 'EMAIL_SIGNIN',\n VERIFY_AND_CHANGE_EMAIL: 'VERIFY_AND_CHANGE_EMAIL',\n VERIFY_EMAIL: 'VERIFY_EMAIL'\n};\n\n\n/**\n * The checkActionCode endpoint server response field names.\n * @enum {string}\n */\nfireauth.ActionCodeInfo.ServerFieldName = {\n // This is the current email of the account and in email recovery, the email\n // to revert to.\n EMAIL: 'email',\n // The multi-factor info to unenroll for revert second factor addition action.\n MFA_INFO: 'mfaInfo',\n // For email recovery, this is the new email.\n NEW_EMAIL: 'newEmail',\n // The action code request type.\n REQUEST_TYPE: 'requestType'\n};\n\n\n/**\n * The ActionCodeInfo data object field names.\n * @enum {string}\n */\nfireauth.ActionCodeInfo.DataField = {\n EMAIL: 'email',\n // This field will be deprecated in favor of PREVIOUS_EMAIL.\n FROM_EMAIL: 'fromEmail',\n MULTI_FACTOR_INFO: 'multiFactorInfo',\n PREVIOUS_EMAIL: 'previousEmail'\n};\n\n\n/**\n * The ActionCodeInfo main property names\n * @enum {string}\n */\nfireauth.ActionCodeInfo.PropertyName = {\n DATA: 'data',\n OPERATION: 'operation'\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines firebase.auth.ActionCodeURL class which is the utility\n * to parse action code URLs.\n */\n\ngoog.provide('fireauth.ActionCodeURL');\n\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('goog.Uri');\n\n\n/**\n * The utility class to help parse action code URLs used for out of band email\n * flows such as password reset, email verification, email link sign in, etc.\n * @param {string} actionLink The action link string.\n * @constructor\n */\nfireauth.ActionCodeURL = function(actionLink) {\n var uri = goog.Uri.parse(actionLink);\n var apiKey = uri.getParameterValue(\n fireauth.ActionCodeURL.QueryField.API_KEY) || null;\n var code = uri.getParameterValue(\n fireauth.ActionCodeURL.QueryField.CODE) || null;\n var mode = uri.getParameterValue(\n fireauth.ActionCodeURL.QueryField.MODE) || null;\n var operation = fireauth.ActionCodeURL.getOperation(mode);\n // Validate API key, code and mode.\n if (!apiKey || !code || !operation) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeURL.QueryField.API_KEY + ', ' +\n fireauth.ActionCodeURL.QueryField.CODE + 'and ' +\n fireauth.ActionCodeURL.QueryField.MODE +\n ' are required in a valid action code URL.');\n }\n fireauth.object.setReadonlyProperties(this, {\n 'apiKey': apiKey,\n 'operation': operation,\n 'code': code,\n 'continueUrl': uri.getParameterValue(\n fireauth.ActionCodeURL.QueryField.CONTINUE_URL) || null,\n 'languageCode': uri.getParameterValue(\n fireauth.ActionCodeURL.QueryField.LANGUAGE_CODE) || null,\n 'tenantId': uri.getParameterValue(\n fireauth.ActionCodeURL.QueryField.TENANT_ID) || null\n });\n};\n\n/**\n * Enums for fields in URL query string.\n * @enum {string}\n */\nfireauth.ActionCodeURL.QueryField = {\n API_KEY: 'apiKey',\n CODE: 'oobCode',\n CONTINUE_URL: 'continueUrl',\n LANGUAGE_CODE: 'languageCode',\n MODE: 'mode',\n TENANT_ID: 'tenantId'\n};\n\n\n/**\n * Map of mode string to Action Code Info operation.\n * @const @private {!Object<string, !fireauth.ActionCodeInfo.Operation>}\n */\nfireauth.ActionCodeURL.ModeToOperationMap_ = {\n 'recoverEmail': fireauth.ActionCodeInfo.Operation.RECOVER_EMAIL,\n 'resetPassword': fireauth.ActionCodeInfo.Operation.PASSWORD_RESET,\n 'revertSecondFactorAddition':\n fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION,\n 'signIn': fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN,\n 'verifyAndChangeEmail':\n fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL,\n 'verifyEmail': fireauth.ActionCodeInfo.Operation.VERIFY_EMAIL\n};\n\n\n/**\n * Maps the mode string in action code URL to Action Code Info operation.\n * @param {?string} mode The mode string in the URL.\n * @return {?fireauth.ActionCodeInfo.Operation}\n */\nfireauth.ActionCodeURL.getOperation = function(mode) {\n if (!mode) {\n return null;\n }\n return fireauth.ActionCodeURL.ModeToOperationMap_[mode] || null;\n\n};\n\n\n/**\n * Returns an ActionCodeURL instance if the link is valid, otherwise null.\n * @param {string} actionLink The action code link string.\n * @return {?fireauth.ActionCodeURL}\n */\nfireauth.ActionCodeURL.parseLink = function(actionLink) {\n try {\n return new fireauth.ActionCodeURL(actionLink);\n } catch(e) {\n return null;\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Utility for firebase.auth.ActionCodeSettings and its helper\n * functions.\n */\n\ngoog.provide('fireauth.ActionCodeSettings');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\n\n\n/**\n * Defines the action code settings structure used to specify how email action\n * links are handled.\n * @param {!Object} settingsObj The action code settings object used to\n * construct the action code link.\n * @constructor @struct @final\n */\nfireauth.ActionCodeSettings = function(settingsObj) {\n // Validate the settings object passed.\n this.initialize_(settingsObj);\n};\n\n\n/**\n * Validate the action code settings object.\n * @param {!Object} settingsObj The action code settings object to validate.\n * @private\n */\nfireauth.ActionCodeSettings.prototype.initialize_ = function(settingsObj) {\n // URL should be required.\n var continueUrl = settingsObj[fireauth.ActionCodeSettings.RawField.URL];\n if (typeof continueUrl === 'undefined') {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CONTINUE_URI);\n } else if (typeof continueUrl !== 'string' ||\n (typeof continueUrl === 'string' && !continueUrl.length)) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_CONTINUE_URI);\n }\n /** @const @private {string} The continue URL. */\n this.continueUrl_ = /** @type {string} */ (continueUrl);\n\n // Validate Android parameters.\n /** @private {?string} The Android package name. */\n this.apn_ = null;\n /** @private {?string} The Android minimum version. */\n this.amv_ = null;\n /** @private {boolean} Whether to install the Android app. */\n this.installApp_ = false;\n var androidSettings =\n settingsObj[fireauth.ActionCodeSettings.RawField.ANDROID];\n if (androidSettings && typeof androidSettings === 'object') {\n var apn = androidSettings[\n fireauth.ActionCodeSettings.AndroidRawField.PACKAGE_NAME];\n var installApp = androidSettings[\n fireauth.ActionCodeSettings.AndroidRawField.INSTALL_APP];\n var amv = androidSettings[\n fireauth.ActionCodeSettings.AndroidRawField.MINIMUM_VERSION];\n if (typeof apn === 'string' && apn.length) {\n this.apn_ = /** @type {string} */ (apn);\n if (typeof installApp !== 'undefined' &&\n typeof installApp !== 'boolean') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.AndroidRawField.INSTALL_APP +\n ' property must be a boolean when specified.');\n }\n this.installApp_ = !!installApp;\n if (typeof amv !== 'undefined' &&\n (typeof amv !== 'string' ||\n (typeof amv === 'string' && !amv.length))) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.AndroidRawField.MINIMUM_VERSION +\n ' property must be a non empty string when specified.');\n }\n this.amv_ = /** @type {?string}*/ (amv || null);\n } else if (typeof apn !== 'undefined') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.AndroidRawField.PACKAGE_NAME +\n ' property must be a non empty string when specified.');\n } else if (typeof installApp !== 'undefined' ||\n typeof amv !== 'undefined') {\n // If installApp or amv specified with no valid APN, fail quickly.\n throw new fireauth.AuthError(\n fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME);\n }\n } else if (typeof androidSettings !== 'undefined') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.RawField.ANDROID +\n ' property must be a non null object when specified.');\n }\n\n // Validate iOS parameters.\n /** @private {?string} The iOS bundle ID. */\n this.ibi_ = null;\n var iosSettings = settingsObj[fireauth.ActionCodeSettings.RawField.IOS];\n if (iosSettings && typeof iosSettings === 'object') {\n var ibi = iosSettings[\n fireauth.ActionCodeSettings.IosRawField.BUNDLE_ID];\n if (typeof ibi === 'string' && ibi.length) {\n this.ibi_ = /** @type {string}*/ (ibi);\n } else if (typeof ibi !== 'undefined') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.IosRawField.BUNDLE_ID +\n ' property must be a non empty string when specified.');\n }\n } else if (typeof iosSettings !== 'undefined') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.RawField.IOS +\n ' property must be a non null object when specified.');\n }\n\n // Validate canHandleCodeInApp.\n var canHandleCodeInApp =\n settingsObj[fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP];\n if (typeof canHandleCodeInApp !== 'undefined' &&\n typeof canHandleCodeInApp !== 'boolean') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP +\n ' property must be a boolean when specified.');\n }\n /** @const @private {boolean} Whether the code can be handled in app. */\n this.canHandleCodeInApp_ = !!canHandleCodeInApp;\n\n // Validate dynamicLinkDomain.\n var dynamicLinkDomain = settingsObj[\n fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN];\n if (typeof dynamicLinkDomain !== 'undefined' &&\n (typeof dynamicLinkDomain !== 'string' ||\n (typeof dynamicLinkDomain === 'string' &&\n !dynamicLinkDomain.length))) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.RawField.DYNAMIC_LINK_DOMAIN +\n ' property must be a non empty string when specified.');\n }\n /** @const @private {?string} The FDL domain. */\n this.dynamicLinkDomain_ = dynamicLinkDomain || null;\n};\n\n\n/**\n * Action code settings backend request field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.RequestField = {\n ANDROID_INSTALL_APP: 'androidInstallApp',\n ANDROID_MINIMUM_VERSION: 'androidMinimumVersion',\n ANDROID_PACKAGE_NAME: 'androidPackageName',\n CAN_HANDLE_CODE_IN_APP: 'canHandleCodeInApp',\n CONTINUE_URL: 'continueUrl',\n DYNAMIC_LINK_DOMAIN: 'dynamicLinkDomain',\n IOS_BUNDLE_ID: 'iOSBundleId'\n};\n\n\n/**\n * Action code settings raw field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.RawField = {\n ANDROID: 'android',\n DYNAMIC_LINK_DOMAIN: 'dynamicLinkDomain',\n HANDLE_CODE_IN_APP: 'handleCodeInApp',\n IOS: 'iOS',\n URL: 'url'\n};\n\n\n/**\n * Action code settings raw Android raw field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.AndroidRawField = {\n INSTALL_APP: 'installApp',\n MINIMUM_VERSION: 'minimumVersion',\n PACKAGE_NAME: 'packageName'\n};\n\n\n/**\n * Action code settings raw iOS raw field names.\n * @enum {string}\n */\nfireauth.ActionCodeSettings.IosRawField = {\n BUNDLE_ID: 'bundleId'\n};\n\n\n/**\n * Builds and returns the backend request for the passed action code settings.\n * @return {!Object} The constructed backend request populated with the action\n * code settings parameters.\n */\nfireauth.ActionCodeSettings.prototype.buildRequest = function() {\n // Construct backend request.\n var request = {};\n request[fireauth.ActionCodeSettings.RequestField.CONTINUE_URL] =\n this.continueUrl_;\n request[fireauth.ActionCodeSettings.RequestField.CAN_HANDLE_CODE_IN_APP] =\n this.canHandleCodeInApp_;\n request[fireauth.ActionCodeSettings.RequestField.ANDROID_PACKAGE_NAME] =\n this.apn_;\n if (this.apn_) {\n request[fireauth.ActionCodeSettings.RequestField.ANDROID_MINIMUM_VERSION] =\n this.amv_;\n request[fireauth.ActionCodeSettings.RequestField.ANDROID_INSTALL_APP] =\n this.installApp_;\n }\n request[fireauth.ActionCodeSettings.RequestField.IOS_BUNDLE_ID] = this.ibi_;\n request[fireauth.ActionCodeSettings.RequestField.DYNAMIC_LINK_DOMAIN] =\n this.dynamicLinkDomain_;\n // Remove null fields.\n for (var key in request) {\n if (request[key] === null) {\n delete request[key];\n }\n }\n return request;\n};\n\n\n/**\n * Returns the canHandleCodeInApp setting of ActionCodeSettings.\n * @return {boolean} Whether the code can be handled in app.\n */\nfireauth.ActionCodeSettings.prototype.canHandleCodeInApp = function() {\n return this.canHandleCodeInApp_;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Namespace with crypto related helper functions.\n */\n\ngoog.provide('goog.crypt');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\n\n\n/**\n * Turns a string into an array of bytes; a \"byte\" being a JS number in the\n * range 0-255. Multi-byte characters are written as little-endian.\n * @param {string} str String value to arrify.\n * @return {!Array<number>} Array of numbers corresponding to the\n * UCS character codes of each character in str.\n */\ngoog.crypt.stringToByteArray = function(str) {\n var output = [], p = 0;\n for (var i = 0; i < str.length; i++) {\n var c = str.charCodeAt(i);\n // NOTE: c <= 0xffff since JavaScript strings are UTF-16.\n if (c > 0xff) {\n output[p++] = c & 0xff;\n c >>= 8;\n }\n output[p++] = c;\n }\n return output;\n};\n\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param {!Uint8Array|!Array<number>} bytes Array of numbers representing\n * characters.\n * @return {string} Stringification of the array.\n */\ngoog.crypt.byteArrayToString = function(bytes) {\n var CHUNK_SIZE = 8192;\n\n // Special-case the simple case for speed's sake.\n if (bytes.length <= CHUNK_SIZE) {\n return String.fromCharCode.apply(null, bytes);\n }\n\n // The remaining logic splits conversion by chunks since\n // Function#apply() has a maximum parameter count.\n // See discussion: http://goo.gl/LrWmZ9\n\n var str = '';\n for (var i = 0; i < bytes.length; i += CHUNK_SIZE) {\n var chunk = goog.array.slice(bytes, i, i + CHUNK_SIZE);\n str += String.fromCharCode.apply(null, chunk);\n }\n return str;\n};\n\n\n/**\n * Turns an array of numbers into the hex string given by the concatenation of\n * the hex values to which the numbers correspond.\n * @param {Uint8Array|Array<number>} array Array of numbers representing\n * characters.\n * @param {string=} opt_separator Optional separator between values\n * @return {string} Hex string.\n */\ngoog.crypt.byteArrayToHex = function(array, opt_separator) {\n return goog.array\n .map(\n array,\n function(numByte) {\n var hexByte = numByte.toString(16);\n return hexByte.length > 1 ? hexByte : '0' + hexByte;\n })\n .join(opt_separator || '');\n};\n\n\n/**\n * Converts a hex string into an integer array.\n * @param {string} hexString Hex string of 16-bit integers (two characters\n * per integer).\n * @return {!Array<number>} Array of {0,255} integers for the given string.\n */\ngoog.crypt.hexToByteArray = function(hexString) {\n goog.asserts.assert(\n hexString.length % 2 == 0, 'Key string length must be multiple of 2');\n var arr = [];\n for (var i = 0; i < hexString.length; i += 2) {\n arr.push(parseInt(hexString.substring(i, i + 2), 16));\n }\n return arr;\n};\n\n\n/**\n * Converts a JS string to a UTF-8 \"byte\" array.\n * @param {string} str 16-bit unicode string.\n * @return {!Array<number>} UTF-8 byte array.\n */\ngoog.crypt.stringToUtf8ByteArray = function(str) {\n // TODO(user): Use native implementations if/when available\n var out = [], p = 0;\n for (var i = 0; i < str.length; i++) {\n var c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n ((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&\n ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n\n/**\n * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.\n * @param {Uint8Array|Array<number>} bytes UTF-8 byte array.\n * @return {string} 16-bit Unicode string.\n */\ngoog.crypt.utf8ByteArrayToString = function(bytes) {\n // TODO(user): Use native implementations if/when available\n var out = [], pos = 0, c = 0;\n while (pos < bytes.length) {\n var c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n var c2 = bytes[pos++];\n out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n var c2 = bytes[pos++];\n var c3 = bytes[pos++];\n var c4 = bytes[pos++];\n var u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) -\n 0x10000;\n out[c++] = String.fromCharCode(0xD800 + (u >> 10));\n out[c++] = String.fromCharCode(0xDC00 + (u & 1023));\n } else {\n var c2 = bytes[pos++];\n var c3 = bytes[pos++];\n out[c++] =\n String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);\n }\n }\n return out.join('');\n};\n\n\n/**\n * XOR two byte arrays.\n * @param {!Uint8Array|!Int8Array|!Array<number>} bytes1 Byte array 1.\n * @param {!Uint8Array|!Int8Array|!Array<number>} bytes2 Byte array 2.\n * @return {!Array<number>} Resulting XOR of the two byte arrays.\n */\ngoog.crypt.xorByteArray = function(bytes1, bytes2) {\n goog.asserts.assert(\n bytes1.length == bytes2.length, 'XOR array lengths must match');\n\n var result = [];\n for (var i = 0; i < bytes1.length; i++) {\n result.push(bytes1[i] ^ bytes2[i]);\n }\n return result;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Base64 en/decoding. Not much to say here except that we\n * work with decoded values in arrays of bytes. By \"byte\" I mean a number\n * in [0, 255].\n */\n\ngoog.provide('goog.crypt.base64');\n\ngoog.require('goog.asserts');\ngoog.require('goog.crypt');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.require('goog.userAgent.product');\n\n/**\n * Default alphabet, shared between alphabets. Only 62 characters.\n * @private {string}\n */\ngoog.crypt.base64.DEFAULT_ALPHABET_COMMON_ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n 'abcdefghijklmnopqrstuvwxyz' +\n '0123456789';\n\n\n/**\n * Alphabet characters for Alphabet.DEFAULT encoding.\n * For characters without padding, please consider using\n * `goog.crypt.baseN.BASE_64` instead.\n *\n * @type {string}\n */\ngoog.crypt.base64.ENCODED_VALS =\n goog.crypt.base64.DEFAULT_ALPHABET_COMMON_ + '+/=';\n\n\n/**\n * Alphabet characters for Alphabet.WEBSAFE_DOT_PADDING encoding.\n * The dot padding is no Internet Standard, according to RFC 4686.\n * https://tools.ietf.org/html/rfc4648\n * For characters without padding, please consider using\n * `goog.crypt.baseN.BASE_64_URL_SAFE` instead.\n *\n * @type {string}\n */\ngoog.crypt.base64.ENCODED_VALS_WEBSAFE =\n goog.crypt.base64.DEFAULT_ALPHABET_COMMON_ + '-_.';\n\n\n/**\n * Alphabets for Base64 encoding\n * Alphabets with no padding character are for encoding without padding.\n * About the alphabets, please refer to RFC 4686.\n * https://tools.ietf.org/html/rfc4648\n * @enum {number}\n */\ngoog.crypt.base64.Alphabet = {\n DEFAULT: 0,\n NO_PADDING: 1,\n WEBSAFE: 2,\n WEBSAFE_DOT_PADDING: 3,\n WEBSAFE_NO_PADDING: 4,\n};\n\n\n/**\n * Padding chars for Base64 encoding\n * @const {string}\n * @private\n */\ngoog.crypt.base64.paddingChars_ = '=.';\n\n\n/**\n * Check if a character is a padding character\n *\n * @param {string} char\n * @return {boolean}\n * @private\n */\ngoog.crypt.base64.isPadding_ = function(char) {\n return goog.string.contains(goog.crypt.base64.paddingChars_, char);\n};\n\n\n// Static lookup maps, lazily populated by init_()\n\n/**\n * For each `Alphabet`, maps from bytes to characters.\n *\n * @see https://jsperf.com/char-lookups\n * @type {!Object<!goog.crypt.base64.Alphabet, !Array<string>>}\n * @private\n */\ngoog.crypt.base64.byteToCharMaps_ = {};\n\n/**\n * Maps characters to bytes.\n *\n * This map is used for all alphabets since, across alphabets, common chars\n * always map to the same byte.\n *\n * `null` indicates `init` has not yet been called.\n *\n * @type {?Object<string, number>}\n * @private\n */\ngoog.crypt.base64.charToByteMap_ = null;\n\n\n/**\n * White list of implementations with known-good native atob and btoa functions.\n * Listing these explicitly (via the ASSUME_* wrappers) benefits dead-code\n * removal in per-browser compilations.\n * @private {boolean}\n */\ngoog.crypt.base64.ASSUME_NATIVE_SUPPORT_ = goog.userAgent.GECKO ||\n (goog.userAgent.WEBKIT && !goog.userAgent.product.SAFARI) ||\n goog.userAgent.OPERA;\n\n\n/**\n * Does this browser have a working btoa function?\n * @private {boolean}\n */\ngoog.crypt.base64.HAS_NATIVE_ENCODE_ =\n goog.crypt.base64.ASSUME_NATIVE_SUPPORT_ ||\n typeof(goog.global.btoa) == 'function';\n\n\n/**\n * Does this browser have a working atob function?\n * We blacklist known-bad implementations:\n * - IE (10+) added atob() but it does not tolerate whitespace on the input.\n * @private {boolean}\n */\ngoog.crypt.base64.HAS_NATIVE_DECODE_ =\n goog.crypt.base64.ASSUME_NATIVE_SUPPORT_ ||\n (!goog.userAgent.product.SAFARI && !goog.userAgent.IE &&\n typeof(goog.global.atob) == 'function');\n\n\n/**\n * Base64-encode an array of bytes.\n *\n * @param {Array<number>|Uint8Array} input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param {!goog.crypt.base64.Alphabet=} alphabet Base 64 alphabet to\n * use in encoding. Alphabet.DEFAULT is used by default.\n * @return {string} The base64 encoded string.\n */\ngoog.crypt.base64.encodeByteArray = function(input, alphabet) {\n // Assert avoids runtime dependency on goog.isArrayLike, which helps reduce\n // size of jscompiler output, and which yields slight performance increase.\n goog.asserts.assert(\n goog.isArrayLike(input), 'encodeByteArray takes an array as a parameter');\n\n if (alphabet === undefined) {\n alphabet = goog.crypt.base64.Alphabet.DEFAULT;\n }\n\n goog.crypt.base64.init_();\n\n var byteToCharMap = goog.crypt.base64.byteToCharMaps_[alphabet];\n\n var output = [];\n\n for (var i = 0; i < input.length; i += 3) {\n var byte1 = input[i];\n var haveByte2 = i + 1 < input.length;\n var byte2 = haveByte2 ? input[i + 1] : 0;\n var haveByte3 = i + 2 < input.length;\n var byte3 = haveByte3 ? input[i + 2] : 0;\n\n var outByte1 = byte1 >> 2;\n var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);\n var outByte4 = byte3 & 0x3F;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1], byteToCharMap[outByte2],\n byteToCharMap[outByte3] || '', byteToCharMap[outByte4] || '');\n }\n\n return output.join('');\n};\n\n\n/**\n * Base64-encode a string.\n *\n * @param {string} input A string to encode.\n * @param {!goog.crypt.base64.Alphabet=} alphabet Base 64 alphabet to\n * use in encoding. Alphabet.DEFAULT is used by default.\n * @return {string} The base64 encoded string.\n */\ngoog.crypt.base64.encodeString = function(input, alphabet) {\n // Shortcut for browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (goog.crypt.base64.HAS_NATIVE_ENCODE_ && !alphabet) {\n return goog.global.btoa(input);\n }\n return goog.crypt.base64.encodeByteArray(\n goog.crypt.stringToByteArray(input), alphabet);\n};\n\n\n/**\n * Base64-decode a string.\n *\n * @param {string} input Input to decode. Any whitespace is ignored, and the\n * input maybe encoded with either supported alphabet (or a mix thereof).\n * @param {boolean=} useCustomDecoder True indicates the custom decoder is used,\n * which supports alternative alphabets. Note that passing false may still\n * use the custom decoder on browsers without native support.\n * @return {string} string representing the decoded value.\n */\ngoog.crypt.base64.decodeString = function(input, useCustomDecoder) {\n // Shortcut for browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (goog.crypt.base64.HAS_NATIVE_DECODE_ && !useCustomDecoder) {\n return goog.global.atob(input);\n }\n var output = '';\n function pushByte(b) {\n output += String.fromCharCode(b);\n }\n\n goog.crypt.base64.decodeStringInternal_(input, pushByte);\n\n return output;\n};\n\n\n/**\n * Base64-decode a string to an Array of numbers.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param {string} input Input to decode. Any whitespace is ignored, and the\n * input maybe encoded with either supported alphabet (or a mix thereof).\n * @param {boolean=} opt_ignored Unused parameter, retained for compatibility.\n * @return {!Array<number>} bytes representing the decoded value.\n */\ngoog.crypt.base64.decodeStringToByteArray = function(input, opt_ignored) {\n var output = [];\n function pushByte(b) { output.push(b); }\n\n goog.crypt.base64.decodeStringInternal_(input, pushByte);\n\n return output;\n};\n\n\n/**\n * Base64-decode a string to a Uint8Array.\n *\n * Note that Uint8Array is not supported on older browsers, e.g. IE < 10.\n * @see http://caniuse.com/uint8array\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param {string} input Input to decode. Any whitespace is ignored, and the\n * input maybe encoded with either supported alphabet (or a mix thereof).\n * @return {!Uint8Array} bytes representing the decoded value.\n */\ngoog.crypt.base64.decodeStringToUint8Array = function(input) {\n goog.asserts.assert(\n !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'),\n 'Browser does not support typed arrays');\n var len = input.length;\n // Approximate the length of the array needed for output.\n // Our method varies according to the format of the input, which we can\n // consider in three categories:\n // A) well-formed with proper padding\n // B) well-formed without any padding\n // C) not-well-formed, either with extra whitespace in the middle or with\n // extra padding characters.\n //\n // In the case of (A), (length * 3 / 4) will result in an integer number of\n // bytes evenly divisible by 3, and we need only subtract bytes according to\n // the padding observed.\n //\n // In the case of (B), (length * 3 / 4) will result in a non-integer number\n // of bytes, or not evenly divisible by 3. (If the result is evenly divisible\n // by 3, it's well-formed with the proper amount of padding [0 padding]).\n // This approximation can become exact by rounding down.\n //\n // In the case of (C), the only way to get the length is to walk the full\n // length of the string to consider each character. This is handled by\n // tracking the number of bytes added to the array and using subarray to\n // trim the array back down to size.\n var approxByteLength = len * 3 / 4;\n if (approxByteLength % 3) {\n // The string isn't complete, either because it didn't include padding, or\n // because it has extra white space.\n // In either case, we won't generate more bytes than are completely encoded,\n // so rounding down is appropriate to have a buffer at least as large as\n // output.\n approxByteLength = Math.floor(approxByteLength);\n } else if (goog.crypt.base64.isPadding_(input[len - 1])) {\n // The string has a round length, and has some padding.\n // Reduce the byte length according to the quantity of padding.\n if (goog.crypt.base64.isPadding_(input[len - 2])) {\n approxByteLength -= 2;\n } else {\n approxByteLength -= 1;\n }\n }\n var output = new Uint8Array(approxByteLength);\n var outLen = 0;\n function pushByte(b) {\n output[outLen++] = b;\n }\n\n goog.crypt.base64.decodeStringInternal_(input, pushByte);\n\n // Return a subarray to handle the case that input included extra whitespace\n // or extra padding and approxByteLength was incorrect.\n return output.subarray(0, outLen);\n};\n\n\n/**\n * @param {string} input Input to decode.\n * @param {function(number):void} pushByte result accumulator.\n * @private\n */\ngoog.crypt.base64.decodeStringInternal_ = function(input, pushByte) {\n goog.crypt.base64.init_();\n\n var nextCharIndex = 0;\n /**\n * @param {number} default_val Used for end-of-input.\n * @return {number} The next 6-bit value, or the default for end-of-input.\n */\n function getByte(default_val) {\n while (nextCharIndex < input.length) {\n var ch = input.charAt(nextCharIndex++);\n var b = goog.crypt.base64.charToByteMap_[ch];\n if (b != null) {\n return b; // Common case: decoded the char.\n }\n if (!goog.string.isEmptyOrWhitespace(ch)) {\n throw new Error('Unknown base64 encoding at char: ' + ch);\n }\n // We encountered whitespace: loop around to the next input char.\n }\n return default_val; // No more input remaining.\n }\n\n while (true) {\n var byte1 = getByte(-1);\n var byte2 = getByte(0);\n var byte3 = getByte(64);\n var byte4 = getByte(64);\n\n // The common case is that all four bytes are present, so if we have byte4\n // we can skip over the truncated input special case handling.\n if (byte4 === 64) {\n if (byte1 === -1) {\n return; // Terminal case: no input left to decode.\n }\n // Here we know an intermediate number of bytes are missing.\n // The defaults for byte2, byte3 and byte4 apply the inferred padding\n // rules per the public API documentation. i.e: 1 byte\n // missing should yield 2 bytes of output, but 2 or 3 missing bytes yield\n // a single byte of output. (Recall that 64 corresponds the padding char).\n }\n\n var outByte1 = (byte1 << 2) | (byte2 >> 4);\n pushByte(outByte1);\n\n if (byte3 != 64) {\n var outByte2 = ((byte2 << 4) & 0xF0) | (byte3 >> 2);\n pushByte(outByte2);\n\n if (byte4 != 64) {\n var outByte3 = ((byte3 << 6) & 0xC0) | byte4;\n pushByte(outByte3);\n }\n }\n }\n};\n\n\n/**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\ngoog.crypt.base64.init_ = function() {\n if (goog.crypt.base64.charToByteMap_) {\n return;\n }\n goog.crypt.base64.charToByteMap_ = {};\n\n // We want quick mappings back and forth, so we precompute encoding maps.\n\n /** @type {!Array<string>} */\n var commonChars = goog.crypt.base64.DEFAULT_ALPHABET_COMMON_.split('');\n var specialChars = [\n '+/=', // DEFAULT\n '+/', // NO_PADDING\n '-_=', // WEBSAFE\n '-_.', // WEBSAFE_DOT_PADDING\n '-_', // WEBSAFE_NO_PADDING\n ];\n\n for (var i = 0; i < 5; i++) {\n // `i` is each value of the `goog.crypt.base64.Alphabet` enum\n var chars = commonChars.concat(specialChars[i].split(''));\n\n // Sets byte-to-char map\n goog.crypt.base64\n .byteToCharMaps_[/** @type {!goog.crypt.base64.Alphabet} */ (i)] =\n chars;\n\n // Sets char-to-byte map\n for (var j = 0; j < chars.length; j++) {\n var char = chars[j];\n\n var existingByte = goog.crypt.base64.charToByteMap_[char];\n if (existingByte === undefined) {\n goog.crypt.base64.charToByteMap_[char] = j;\n } else {\n goog.asserts.assert(existingByte === j);\n }\n }\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Utility functions to handle Firebase Auth ID tokens.\n */\n\ngoog.provide('fireauth.IdToken');\n\ngoog.require('goog.crypt.base64');\n\n\n/**\n * Parses the token string into a {@code Token} object.\n * @param {?string} tokenString The JWT token string.\n * @constructor\n */\nfireauth.IdToken = function(tokenString) {\n var token = fireauth.IdToken.parseIdTokenClaims(tokenString);\n if (!(token && token['sub'] && token['iss'] &&\n token['aud'] && token['exp'])) {\n throw new Error('Invalid JWT');\n }\n /** @const @private {string} The plain JWT string. */\n this.jwt_ = /** @type {string} */ (tokenString);\n /** @const @private {string} The issuer of the token. */\n this.iss_ = token['iss'];\n /** @const @private {string} The audience of the token. */\n this.aud_ = token['aud'];\n /** @const @private {number} The expire time in seconds of the token. */\n this.exp_ = token['exp'];\n /** @const @private {string} The local user ID of the token. */\n this.localId_ = token['sub'];\n var now = goog.now() / 1000;\n /** @const @private {number} The issue time in seconds of the token. */\n this.iat_ = token['iat'] || (now > this.exp_ ? this.exp_ : now);\n /** @const @private {?string} The email address of the token. */\n this.email_ = token['email'] || null;\n /** @const @private {boolean} Whether the user is verified. */\n this.verified_ = !!token['verified'];\n /** @const @private {?string} The provider ID of the token. */\n this.providerId_ = token['provider_id'] ||\n (token['firebase'] && token['firebase']['sign_in_provider']) ||\n null;\n /** @const @private {?string} The tenant ID of the token. */\n this.tenantId_ = (token['firebase'] && token['firebase']['tenant']) || null;\n /** @const @private {boolean} Whether the user is anonymous. */\n this.anonymous_ = !!token['is_anonymous'] || this.providerId_ == 'anonymous';\n /** @const @private {?string} The federated ID of the token. */\n this.federatedId_ = token['federated_id'] || null;\n /** @const @private {?string} The display name of the token. */\n this.displayName_ = token['display_name'] || null;\n /** @const @private {?string} The photo URL of the token. */\n this.photoURL_ = token['photo_url'] || null;\n /**\n * @const @private {?string} The phone number of the user identified by the\n * token.\n */\n this.phoneNumber_ = token['phone_number'] || null;\n};\n\n\n/**\n * @typedef {{\n * identities: (?Object|undefined),\n * sign_in_provider: (?string|undefined),\n * tenant: (string|undefined)\n * }}\n */\nfireauth.IdToken.Firebase;\n\n\n/**\n * @typedef {{\n * iss: string,\n * aud: string,\n * exp: number,\n * sub: string,\n * iat: (?number|undefined),\n * email: (?string|undefined),\n * verified: (?boolean|undefined),\n * provider_id: (?string|undefined),\n * is_anonymous: (?boolean|undefined),\n * federated_id: (?string|undefined),\n * display_name: (?string|undefined),\n * photo_url: (?string|undefined),\n * phone_number: (?string|undefined),\n * firebase: (?fireauth.IdToken.Firebase|undefined)\n * }}\n */\nfireauth.IdToken.JsonToken;\n\n\n/** @return {?string} The email address of the account. */\nfireauth.IdToken.prototype.getEmail = function() {\n return this.email_;\n};\n\n\n/** @return {number} The expire time in seconds. */\nfireauth.IdToken.prototype.getExp = function() {\n return this.exp_;\n};\n\n\n/** @return {?string} The ID of the identity provider. */\nfireauth.IdToken.prototype.getProviderId = function() {\n return this.providerId_;\n};\n\n\n/** @return {?string} The tenant ID. */\nfireauth.IdToken.prototype.getTenantId = function() {\n return this.tenantId_;\n};\n\n\n/** @return {?string} The display name of the account. */\nfireauth.IdToken.prototype.getDisplayName = function() {\n return this.displayName_;\n};\n\n\n/** @return {?string} The photo URL of the account. */\nfireauth.IdToken.prototype.getPhotoUrl = function() {\n return this.photoURL_;\n};\n\n\n/** @return {string} The user ID of the account. */\nfireauth.IdToken.prototype.getLocalId = function() {\n return this.localId_;\n};\n\n\n/** @return {?string} The federated ID of the account. */\nfireauth.IdToken.prototype.getFederatedId = function() {\n return this.federatedId_;\n};\n\n\n/** @return {boolean} Whether the user is anonymous. */\nfireauth.IdToken.prototype.isAnonymous = function() {\n return this.anonymous_;\n};\n\n\n/** @return {boolean} Whether the user email is verified. */\nfireauth.IdToken.prototype.isVerified = function() {\n return this.verified_;\n};\n\n\n/** @return {boolean} Whether token is expired. */\nfireauth.IdToken.prototype.isExpired = function() {\n var now = Math.floor(goog.now() / 1000);\n // It is expired if token expiration time is less than current time.\n return this.getExp() <= now;\n};\n\n\n/** @return {string} The issuer of the token. */\nfireauth.IdToken.prototype.getIssuer = function() {\n return this.iss_;\n};\n\n\n/** @return {?string} The phone number of the account. */\nfireauth.IdToken.prototype.getPhoneNumber = function() {\n return this.phoneNumber_;\n};\n\n\n/**\n * @return {string} The JWT string.\n * @override\n */\nfireauth.IdToken.prototype.toString = function() {\n return this.jwt_;\n};\n\n\n/**\n * Parses the JWT token and extracts the information part without verifying the\n * token signature.\n * @param {string} tokenString The JWT token.\n * @return {?fireauth.IdToken} The decoded token.\n */\nfireauth.IdToken.parse = function(tokenString) {\n try {\n return new fireauth.IdToken(tokenString);\n } catch (e) {\n return null;\n }\n};\n\n/**\n * Converts the information part of JWT token to plain object format.\n * @param {?string} tokenString The JWT token.\n * @return {?Object}\n */\nfireauth.IdToken.parseIdTokenClaims = function(tokenString) {\n if (!tokenString) {\n return null;\n }\n // Token format is <algorithm>.<info>.<sig>\n var fields = tokenString.split('.');\n if (fields.length != 3) {\n return null;\n }\n var jsonInfo = fields[1];\n // Google base64 library does not handle padding.\n var padLen = (4 - jsonInfo.length % 4) % 4;\n for (var i = 0; i < padLen; i++) {\n jsonInfo += '.';\n }\n try {\n var token = JSON.parse(goog.crypt.base64.decodeString(jsonInfo, true));\n return /** @type {?Object} */ (token);\n } catch (e) {}\n return null;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the IdP provider IDs and related settings.\n */\n\ngoog.provide('fireauth.idp');\ngoog.provide('fireauth.idp.IdpSettings');\ngoog.provide('fireauth.idp.ProviderId');\ngoog.provide('fireauth.idp.Settings');\ngoog.provide('fireauth.idp.SignInMethod');\n\ngoog.require('fireauth.constants');\n\n\n/**\n * Enums for supported provider IDs. These provider IDs correspond to the\n * sign_in_provider in the Firebase ID token and do not correspond to the\n * supported client exposed firebase.auth.AuthProviders.\n * @enum {string}\n */\nfireauth.idp.ProviderId = {\n ANONYMOUS: 'anonymous',\n CUSTOM: 'custom',\n FACEBOOK: 'facebook.com',\n FIREBASE: 'firebase',\n GITHUB: 'github.com',\n GOOGLE: 'google.com',\n PASSWORD: 'password',\n PHONE: 'phone',\n TWITTER: 'twitter.com'\n};\n\n\n/**\n * Enums for supported sign in methods.\n * @enum {string}\n */\nfireauth.idp.SignInMethod = {\n EMAIL_LINK: 'emailLink',\n EMAIL_PASSWORD: 'password',\n FACEBOOK: 'facebook.com',\n GITHUB: 'github.com',\n GOOGLE: 'google.com',\n PHONE: 'phone',\n TWITTER: 'twitter.com'\n};\n\n\n/**\n * The settings of an identity provider. The fields are:\n * <ul>\n * <li>languageParam: defines the custom OAuth language parameter.\n * <li>popupWidth: defines the popup recommended width.\n * <li>popupHeight: defines the popup recommended height.\n * <li>providerId: defines the provider ID.\n * <li>reservedOAuthParameters: defines the list of reserved OAuth parameters.\n * </ul>\n * @typedef {{\n * languageParam: (?string|undefined),\n * popupWidth: (?number|undefined),\n * popupHeight: (?number|undefined),\n * providerId: !fireauth.idp.ProviderId,\n * reservedOAuthParameters: !Array<string>\n * }}\n */\nfireauth.idp.IdpSettings;\n\n\n/**\n * The list of reserved OAuth 1.0 parameters.\n * @const {!Array<string>}\n */\nfireauth.idp.RESERVED_OAUTH1_PARAMS =\n ['oauth_consumer_key', 'oauth_nonce', 'oauth_signature',\n 'oauth_signature_method', 'oauth_timestamp', 'oauth_token',\n 'oauth_version'];\n\n\n/**\n * The list of reserved OAuth 2.0 parameters.\n * @const {!Array<string>}\n */\nfireauth.idp.RESERVED_OAUTH2_PARAMS =\n ['client_id', 'response_type', 'scope', 'redirect_uri', 'state'];\n\n\n/**\n * The recommendations for the different IdP display settings.\n * @enum {!fireauth.idp.IdpSettings}\n */\nfireauth.idp.Settings = {\n FACEBOOK: {\n languageParam: 'locale',\n popupWidth: 700,\n popupHeight: 600,\n providerId: fireauth.idp.ProviderId.FACEBOOK,\n reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH2_PARAMS,\n },\n GITHUB: {\n languageParam: null,\n popupWidth: 500,\n popupHeight: 750,\n providerId: fireauth.idp.ProviderId.GITHUB,\n reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH2_PARAMS,\n },\n GOOGLE: {\n languageParam: 'hl',\n popupWidth: 515,\n popupHeight: 680,\n providerId: fireauth.idp.ProviderId.GOOGLE,\n reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH2_PARAMS,\n },\n TWITTER: {\n languageParam: 'lang',\n popupWidth: 485,\n popupHeight: 705,\n providerId: fireauth.idp.ProviderId.TWITTER,\n reservedOAuthParameters: fireauth.idp.RESERVED_OAUTH1_PARAMS,\n },\n APPLE: {\n languageParam: 'locale',\n popupWidth: 640,\n popupHeight: 600,\n providerId: 'apple.com',\n reservedOAuthParameters: [],\n },\n};\n\n\n/**\n * @param {!fireauth.idp.ProviderId} providerId The requested provider ID.\n * @return {?fireauth.idp.Settings} The settings for the requested provider ID.\n */\nfireauth.idp.getIdpSettings = function(providerId) {\n for (var key in fireauth.idp.Settings) {\n if (fireauth.idp.Settings[key].providerId == providerId) {\n return fireauth.idp.Settings[key];\n }\n }\n return null;\n};\n\n\n/**\n * @param {!fireauth.idp.ProviderId} providerId The requested provider ID.\n * @return {!Array<string>} The list of reserved OAuth parameters.\n */\nfireauth.idp.getReservedOAuthParams = function(providerId) {\n var settings = fireauth.idp.getIdpSettings(providerId);\n return (settings && settings.reservedOAuthParameters) || [];\n};\n\n\n/**\n * @param {?string|undefined} identifier The provider identifier.\n * @return {boolean} Whether the identifier provided is a SAML provider ID.\n */\nfireauth.idp.isSaml = function(identifier) {\n return typeof identifier === 'string' &&\n identifier.indexOf(fireauth.constants.SAML_PREFIX) == 0;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines all the fireauth additional user info interfaces,\n * implementations and subclasses.\n */\n\ngoog.provide('fireauth.AdditionalUserInfo');\ngoog.provide('fireauth.FacebookAdditionalUserInfo');\ngoog.provide('fireauth.FederatedAdditionalUserInfo');\ngoog.provide('fireauth.GenericAdditionalUserInfo');\ngoog.provide('fireauth.GithubAdditionalUserInfo');\ngoog.provide('fireauth.GoogleAdditionalUserInfo');\ngoog.provide('fireauth.TwitterAdditionalUserInfo');\n\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\n\n\n/**\n * The interface that represents additional user info.\n * @interface\n */\nfireauth.AdditionalUserInfo = function() {};\n\n\n/**\n * Constructs the corresponding additional user info for the backend\n * verifyAssertion response.\n * @param {?Object|undefined} resp The backend verifyAssertion,\n * verifyPhoneNumber or verifyPassword/setAccountInfo response.\n * @return {?fireauth.AdditionalUserInfo} The fireauth.AdditionalUserInfo\n * instance.\n */\nfireauth.AdditionalUserInfo.fromPlainObject = function(resp) {\n var factory = {};\n factory[fireauth.idp.ProviderId.FACEBOOK] =\n fireauth.FacebookAdditionalUserInfo;\n factory[fireauth.idp.ProviderId.GOOGLE] =\n fireauth.GoogleAdditionalUserInfo;\n factory[fireauth.idp.ProviderId.GITHUB] =\n fireauth.GithubAdditionalUserInfo;\n factory[fireauth.idp.ProviderId.TWITTER] =\n fireauth.TwitterAdditionalUserInfo;\n // Provider ID and UID are required.\n var providerId =\n resp &&\n resp[fireauth.AdditionalUserInfo.VerifyAssertionField.PROVIDER_ID];\n try {\n // Provider ID already present.\n if (providerId) {\n if (factory[providerId]) {\n // 1st class supported federated providers.\n return new factory[providerId](resp);\n } else {\n // Generic federated providers.\n return new fireauth.FederatedAdditionalUserInfo(\n /** @type {!Object} */ (resp));\n }\n } else if (typeof resp[fireauth.AdditionalUserInfo.VerifyAssertionField\n .ID_TOKEN] !== 'undefined') {\n // For all other ID token responses with no providerId, get the required\n // providerId from the ID token itself.\n return new fireauth.GenericAdditionalUserInfo(\n /** @type {!Object} */ (resp));\n }\n } catch (e) {\n // Do nothing, null will be returned.\n }\n return null;\n};\n\n\n\n/**\n * verifyAssertion response additional user info fields.\n * @enum {string}\n */\nfireauth.AdditionalUserInfo.VerifyAssertionField = {\n ID_TOKEN: 'idToken',\n IS_NEW_USER: 'isNewUser',\n KIND: 'kind',\n PROVIDER_ID: 'providerId',\n RAW_USER_INFO: 'rawUserInfo',\n SCREEN_NAME: 'screenName'\n};\n\n\n/**\n * Constructs a generic additional user info object from the backend\n * verifyPhoneNumber and verifyPassword provider response.\n * @param {!Object} info The verifyPhoneNumber/verifyPassword/setAccountInfo\n * response data object.\n * @constructor\n * @implements {fireauth.AdditionalUserInfo}\n */\nfireauth.GenericAdditionalUserInfo = function(info) {\n // Federated provider profile data.\n var providerId =\n info[fireauth.AdditionalUserInfo.VerifyAssertionField.PROVIDER_ID];\n // Try to get providerId from the ID token if available.\n if (!providerId &&\n info[fireauth.AdditionalUserInfo.VerifyAssertionField.ID_TOKEN]) {\n // verifyPassword/setAccountInfo and verifyPhoneNumber return an ID token\n // but no providerId. Get providerId from the token itself.\n // isNewUser will be returned for verifyPhoneNumber.\n var idToken = fireauth.IdToken.parse(\n info[fireauth.AdditionalUserInfo.VerifyAssertionField.ID_TOKEN]);\n if (idToken && idToken.getProviderId()) {\n providerId = idToken.getProviderId();\n }\n }\n if (!providerId) {\n // This is internal only.\n throw new Error('Invalid additional user info!');\n }\n // For custom token and anonymous token, set provider ID to null.\n if (providerId == fireauth.idp.ProviderId.ANONYMOUS ||\n providerId == fireauth.idp.ProviderId.CUSTOM) {\n providerId = null;\n }\n // Check whether user is new. Temporary Solution since backend does not return\n // isNewUser field for SignupNewUserResponse.\n var isNewUser = false;\n if (typeof info[fireauth.AdditionalUserInfo.VerifyAssertionField.IS_NEW_USER]\n !== 'undefined') {\n isNewUser =\n !!info[fireauth.AdditionalUserInfo.VerifyAssertionField.IS_NEW_USER];\n } else if (info[fireauth.AdditionalUserInfo.VerifyAssertionField.KIND]\n === 'identitytoolkit#SignupNewUserResponse') {\n //For SignupNewUserResponse, always set isNewUser to true.\n isNewUser = true;\n }\n // Set required providerId.\n fireauth.object.setReadonlyProperty(this, 'providerId', providerId);\n // Set read-only isNewUser property.\n fireauth.object.setReadonlyProperty(this, 'isNewUser', isNewUser);\n};\n\n\n/**\n * Constructs a federated additional user info object from the backend\n * verifyAssertion federated provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.GenericAdditionalUserInfo}\n */\nfireauth.FederatedAdditionalUserInfo = function(info) {\n fireauth.FederatedAdditionalUserInfo.base(this, 'constructor', info);\n // Federated provider profile data.\n // This structure will also be used for generic IdPs.\n var profile = fireauth.util.parseJSON(\n info[fireauth.AdditionalUserInfo.VerifyAssertionField.RAW_USER_INFO] ||\n '{}');\n // Set read-only profile property.\n fireauth.object.setReadonlyProperty(\n this,\n 'profile',\n fireauth.object.unsafeCreateReadOnlyCopy(profile || {}));\n};\ngoog.inherits(\n fireauth.FederatedAdditionalUserInfo, fireauth.GenericAdditionalUserInfo);\n\n\n/**\n * Constructs a Facebook additional user info object from the backend\n * verifyAssertion Facebook provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.FacebookAdditionalUserInfo = function(info) {\n fireauth.FacebookAdditionalUserInfo.base(this, 'constructor', info);\n // This should not happen as this object is initialized via fromPlainObject.\n if (this['providerId'] != fireauth.idp.ProviderId.FACEBOOK) {\n throw new Error('Invalid provider ID!');\n }\n};\ngoog.inherits(\n fireauth.FacebookAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n\n\n\n/**\n * Constructs a GitHub additional user info object from the backend\n * verifyAssertion GitHub provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.GithubAdditionalUserInfo = function(info) {\n fireauth.GithubAdditionalUserInfo.base(this, 'constructor', info);\n // This should not happen as this object is initialized via fromPlainObject.\n if (this['providerId'] != fireauth.idp.ProviderId.GITHUB) {\n throw new Error('Invalid provider ID!');\n }\n // GitHub username.\n fireauth.object.setReadonlyProperty(\n this,\n 'username',\n (this['profile'] && this['profile']['login']) || null);\n};\ngoog.inherits(\n fireauth.GithubAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n\n\n\n/**\n * Constructs a Google additional user info object from the backend\n * verifyAssertion Google provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.GoogleAdditionalUserInfo = function(info) {\n fireauth.GoogleAdditionalUserInfo.base(this, 'constructor', info);\n // This should not happen as this object is initialized via fromPlainObject.\n if (this['providerId'] != fireauth.idp.ProviderId.GOOGLE) {\n throw new Error('Invalid provider ID!');\n }\n};\ngoog.inherits(\n fireauth.GoogleAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n\n\n\n/**\n * Constructs a Twitter additional user info object from the backend\n * verifyAssertion Twitter provider response.\n * @param {!Object} info The verifyAssertion response data object.\n * @constructor\n * @extends {fireauth.FederatedAdditionalUserInfo}\n */\nfireauth.TwitterAdditionalUserInfo = function(info) {\n fireauth.TwitterAdditionalUserInfo.base(this, 'constructor', info);\n // This should not happen as this object is initialized via fromPlainObject.\n if (this['providerId'] != fireauth.idp.ProviderId.TWITTER) {\n throw new Error('Invalid provider ID!');\n }\n // Twitter user name.\n fireauth.object.setReadonlyProperty(\n this,\n 'username',\n info[fireauth.AdditionalUserInfo.VerifyAssertionField.SCREEN_NAME] ||\n null);\n};\ngoog.inherits(\n fireauth.TwitterAdditionalUserInfo, fireauth.FederatedAdditionalUserInfo);\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the Firebase dynamic link constructor.\n */\n\ngoog.provide('fireauth.DynamicLink');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Uri');\n\n\n/**\n * Dynamic link builder used to help build the FDL link to redirect to an app\n * while passing some payload or error.\n * @param {?string} fdlDomain The FDL domain. If none is available, custom\n * scheme redirects are used.\n * @param {!fireauth.DynamicLink.Platform} platform The FDL supported\n * platform (Android or iOS).\n * @param {string} appIdentifier The app identifier (iOS bundle ID or Android\n * package name).\n * @param {string} authDomain The Firebase application authDomain.\n * @param {string} payload The FDL deep link content.\n * @param {?string=} opt_clientId The optional OAuth client ID.\n * @constructor\n */\nfireauth.DynamicLink = function(fdlDomain, platform, appIdentifier, authDomain,\n payload, opt_clientId) {\n // The fallback error when the app is not installed on the device.\n var defaultError =\n new fireauth.AuthError(fireauth.authenum.Error.APP_NOT_INSTALLED);\n /** @private {string} The fallback URL when the app is not installed. */\n this.fallbackUrl_ = 'https://' + authDomain + '/__/auth/handler?' +\n 'firebaseError=' + encodeURIComponent(/** @type {string} */ (\n fireauth.util.stringifyJSON(defaultError.toPlainObject())));\n fireauth.object.setReadonlyProperty(this, 'fallbackUrl', this.fallbackUrl_);\n /** @private {?string} The FDL domain if available. */\n this.fdlDomain_ = fdlDomain;\n fireauth.object.setReadonlyProperty(this, 'fdlDomain', fdlDomain);\n /** @private {!fireauth.DynamicLink.Platform} The FDL link platform. */\n this.platform_ = platform;\n fireauth.object.setReadonlyProperty(this, 'platform', platform);\n /** @private {string} The app identifier. */\n this.appIdentifier_ = appIdentifier;\n fireauth.object.setReadonlyProperty(this, 'appIdentifier', appIdentifier);\n /** @private {string} The Firebase application authDomain. */\n this.authDomain_ = authDomain;\n fireauth.object.setReadonlyProperty(this, 'authDomain', authDomain);\n /** @private {string} The FDL deep link content. */\n this.link_ = payload;\n fireauth.object.setReadonlyProperty(this, 'payload', payload);\n /** @private {?string} The application display name. */\n this.appName_ = null;\n fireauth.object.setReadonlyProperty(this, 'appName', null);\n /** @private {?string} The client ID if available. */\n this.clientId_ = opt_clientId || null;\n fireauth.object.setReadonlyProperty(this, 'clientId', this.clientId_);\n};\n\n\n/**\n * Sets the app name for the current dynamic link.\n * @param {?string|undefined} appName The app name typically displayed in an FDL\n * button.\n */\nfireauth.DynamicLink.prototype.setAppName = function(appName) {\n this.appName_ = appName || null;\n fireauth.object.setReadonlyProperty(this, 'appName', appName);\n};\n\n\n/**\n * Sets the dynamic link fallback URL overriding the default one.\n * @param {string} fallbackUrl The dynamic link fallback URL.\n */\nfireauth.DynamicLink.prototype.setFallbackUrl = function(fallbackUrl) {\n this.fallbackUrl_ = fallbackUrl;\n fireauth.object.setReadonlyProperty(this, 'fallbackUrl', fallbackUrl);\n};\n\n\n/**\n * Parses a dynamic link object from an automatic FDL redirect link.\n * @param {string} url The URL string to parse and convert to a dynamic link.\n * @return {?fireauth.DynamicLink} The corresponding dynamic link if applicable.\n */\nfireauth.DynamicLink.fromURL = function(url) {\n // This constructs the Dynamic link from the URL provided.\n var uri = goog.Uri.parse(url);\n var fdlDomain = uri.getParameterValue('fdlDomain');\n var platform = uri.getParameterValue('platform');\n var appIdentifier = uri.getParameterValue('appIdentifier');\n var authDomain = uri.getParameterValue('authDomain');\n var payload = uri.getParameterValue('link');\n var appName = uri.getParameterValue('appName');\n if (fdlDomain && platform && appIdentifier && authDomain && payload &&\n appName) {\n var dl = new fireauth.DynamicLink(\n /** @type {string} */ (fdlDomain),\n /** @type {!fireauth.DynamicLink.Platform} */ (platform),\n /** @type {string} */ (appIdentifier),\n /** @type {string} */ (authDomain),\n /** @type {string} */ (payload));\n dl.setAppName(appName);\n return dl;\n }\n return null;\n};\n\n\n/**\n * @param {string} url The dynamic link URL.\n * @return {string} The deep link embedded within the dynamic link.\n */\nfireauth.DynamicLink.parseDeepLink = function(url) {\n var uri = goog.Uri.parse(url);\n var link = uri.getParameterValue('link');\n // Double link case (automatic redirect).\n var doubleDeepLink = goog.Uri.parse(link).getParameterValue('link');\n // iOS custom scheme links.\n var iOSdeepLink = uri.getParameterValue('deep_link_id');\n var iOSDoubledeepLink = goog.Uri.parse(iOSdeepLink).getParameterValue('link');\n var callbackUrl =\n iOSDoubledeepLink || iOSdeepLink || doubleDeepLink || link || url;\n return callbackUrl;\n};\n\n\n/**\n * The supported FDL platforms.\n * @enum {string}\n */\nfireauth.DynamicLink.Platform = {\n ANDROID: 'android',\n IOS: 'ios'\n};\n\n\n/**\n * Constructs the common FDL link base used for building the button link or the\n * automatic redirect link.\n * @param {string} fallbackUrl The fallback URL to use.\n * @return {!goog.Uri} The partial URI of the FDL link used to build the final\n * button link or the automatic redirect link.\n * @private\n */\nfireauth.DynamicLink.prototype.constructFdlBase_ = function(fallbackUrl) {\n var uri = goog.Uri.create(\n 'https',\n null,\n this.fdlDomain_,\n null,\n '/');\n if (this.platform_ == fireauth.DynamicLink.Platform.ANDROID) {\n uri.setParameterValue('apn', this.appIdentifier_);\n uri.setParameterValue('afl', fallbackUrl);\n } else if (this.platform_ == fireauth.DynamicLink.Platform.IOS) {\n uri.setParameterValue('ibi', this.appIdentifier_);\n uri.setParameterValue('ifl', fallbackUrl);\n }\n return uri;\n};\n\n\n/**\n * Constructs the custom scheme URL. This is used when no FDL domain is\n * available.\n * @return {!goog.Uri} The uri of the dynamic link used to build the final\n * button link or the automatic redirect link.\n * @private\n */\nfireauth.DynamicLink.prototype.constructCustomSchemeUrl_ = function() {\n // This mimics the FDL custom scheme URL format.\n var uri = goog.Uri.create(\n this.clientId_ ? this.clientId_.split('.').reverse().join('.') :\n this.appIdentifier_,\n null,\n // 'firebaseauth' is used in the app verification flow.\n // 'google' is used for the Cordova iOS flow.\n this.clientId_ ? 'firebaseauth' : 'google',\n null,\n '/link');\n uri.setParameterValue('deep_link_id', this.link_);\n return uri;\n};\n\n\n/**\n * @param {boolean=} opt_isAutoRedirect Whether the link is an auto redirect\n * link.\n * @return {string} The generated dynamic link string.\n * @override\n */\nfireauth.DynamicLink.prototype.toString = function(opt_isAutoRedirect) {\n // When FDL domain is not available, always returns the custom scheme URL.\n if (!this.fdlDomain_) {\n return this.constructCustomSchemeUrl_().toString();\n }\n if (!!opt_isAutoRedirect) {\n return this.generateAutomaticRedirectLink_();\n }\n return this.generateButtonLink_();\n};\n\n\n/**\n * @return {string} The final FDL button link.\n * @private\n */\nfireauth.DynamicLink.prototype.generateButtonLink_ = function() {\n var fdlLink = this.constructFdlBase_(this.fallbackUrl_);\n fdlLink.setParameterValue('link', this.link_);\n return fdlLink.toString();\n};\n\n\n/**\n * @return {string} The final FDL automatic redirect link.\n * @private\n */\nfireauth.DynamicLink.prototype.generateAutomaticRedirectLink_ =\n function() {\n var doubleDeeplink = goog.Uri.create(\n 'https',\n null,\n this.authDomain_,\n null,\n '/__/auth/callback');\n doubleDeeplink.setParameterValue('fdlDomain', this.fdlDomain_);\n doubleDeeplink.setParameterValue('platform', this.platform_);\n doubleDeeplink.setParameterValue('appIdentifier', this.appIdentifier_);\n doubleDeeplink.setParameterValue('authDomain', this.authDomain_);\n doubleDeeplink.setParameterValue('link', this.link_);\n doubleDeeplink.setParameterValue('appName', this.appName_ || '');\n // The fallback URL is the deep link itself.\n // This is in case the link fails to be intercepted by the app, FDL will\n // redirect to the fallback URL.\n var fdlLink = this.constructFdlBase_(doubleDeeplink.toString());\n fdlLink.setParameterValue('link', doubleDeeplink.toString());\n return fdlLink.toString();\n};\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the multi-factor session object used for enrolling a\n * second factor on a user or helping sign in an enrolled user with a second\n * factor.\n */\n\ngoog.provide('fireauth.MultiFactorSession');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('goog.Promise');\n\n\n/**\n * Initializes an instance of a multi-factor session object used for enrolling\n * a second factor on a user or helping sign in an enrolled user with a second\n * factor.\n * This will be constructed either after calling `user.getIdToken()` or from the\n * error containing the pending MFA credential after sign-in.\n * @param {?string} idToken The ID token for an enroll flow. This has to be\n * retrieved after recent authentication.\n * @param {?string=} mfaPendingCredential The pending credential after an\n * enrolled second factor user signs in successfully with the first factor.\n * @constructor\n */\nfireauth.MultiFactorSession = function(idToken, mfaPendingCredential) {\n if (!idToken && !mfaPendingCredential) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'Internal assert: no raw session string available');\n }\n // Both fields should never be passed at the same time.\n if (idToken && mfaPendingCredential) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'Internal assert: unable to determine the session type');\n }\n /** @const @private {?string} The ID token for an enroll flow. */\n this.idToken_ = idToken || null;\n /** @const @private {?string} The pending credential for a sign-in flow. */\n this.mfaPendingCredential_ = mfaPendingCredential || null;\n /** @const @public {!fireauth.MultiFactorSession.Type} The session type.*/\n this.type = this.idToken_ ?\n fireauth.MultiFactorSession.Type.ENROLL :\n fireauth.MultiFactorSession.Type.SIGN_IN;\n};\n\n\n/**\n * Enum representing the type of multi-factor session.\n * @enum {string}\n */\nfireauth.MultiFactorSession.Type = {\n ENROLL: 'enroll',\n SIGN_IN: 'signin'\n};\n\n\n/**\n * Returns a promise that resolves with the raw session string.\n * @return {!goog.Promise<string>} A promise that resolves with the raw session\n * string.\n */\nfireauth.MultiFactorSession.prototype.getRawSession = function() {\n return this.idToken_ ?\n goog.Promise.resolve(this.idToken_) :\n goog.Promise.resolve(this.mfaPendingCredential_);\n};\n\n\n/**\n * Returns the plain object representation of the session object.\n * @return {!Object} The plain object representation of the session object.\n */\nfireauth.MultiFactorSession.prototype.toPlainObject = function() {\n if (this.type == fireauth.MultiFactorSession.Type.ENROLL) {\n return {\n 'multiFactorSession': {\n 'idToken': this.idToken_\n }\n };\n } else {\n return {\n 'multiFactorSession': {\n 'pendingCredential': this.mfaPendingCredential_\n }\n };\n }\n};\n\n\n/**\n * Converts a plain object to a `fireauth.MultiFactorSession` if applicable.\n * @param {?Object} obj The plain object to convert to a\n * `fireauth.MultiFactorSession`.\n * @return {?fireauth.MultiFactorSession} The corresponding\n * `fireauth.MultiFactorSession` representation, null otherwise.\n */\nfireauth.MultiFactorSession.fromPlainObject = function(obj) {\n if (obj && obj['multiFactorSession']) {\n if (obj['multiFactorSession']['pendingCredential']) {\n return new fireauth.MultiFactorSession(\n null, obj['multiFactorSession']['pendingCredential']);\n } else if (obj['multiFactorSession']['idToken']) {\n return new fireauth.MultiFactorSession(\n obj['multiFactorSession']['idToken'], null);\n }\n }\n return null;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines Auth credentials used for signInWithCredential.\n */\n\ngoog.provide('fireauth.AuthCredential');\ngoog.provide('fireauth.AuthProvider');\ngoog.provide('fireauth.EmailAuthCredential');\ngoog.provide('fireauth.EmailAuthProvider');\ngoog.provide('fireauth.FacebookAuthProvider');\ngoog.provide('fireauth.FederatedProvider');\ngoog.provide('fireauth.GithubAuthProvider');\ngoog.provide('fireauth.GoogleAuthProvider');\ngoog.provide('fireauth.OAuthCredential');\ngoog.provide('fireauth.OAuthProvider');\ngoog.provide('fireauth.OAuthResponse');\ngoog.provide('fireauth.PhoneAuthCredential');\ngoog.provide('fireauth.PhoneAuthProvider');\ngoog.provide('fireauth.SAMLAuthCredential');\ngoog.provide('fireauth.SAMLAuthProvider');\ngoog.provide('fireauth.TwitterAuthProvider');\n\ngoog.requireType('fireauth.RpcHandler');\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.ActionCodeURL');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.DynamicLink');\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.MultiFactorAuthCredential');\ngoog.require('fireauth.MultiFactorEnrollmentRequestIdentifier');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.MultiFactorSignInRequestIdentifier');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n\n/**\n * The interface that represents Auth credential. It provides the underlying\n * implementation for retrieving the ID token depending on the type of\n * credential.\n * @interface\n */\nfireauth.AuthCredential = function() {};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n * idTokenPromise The RPC handler method that returns a promise which\n * resolves with an ID token.\n */\nfireauth.AuthCredential.prototype.getIdTokenProvider = function(rpcHandler) {};\n\n\n/**\n * Links the credential to an existing account, identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n * are linked.\n */\nfireauth.AuthCredential.prototype.linkToIdToken =\n function(rpcHandler, idToken) {};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n * idToken UID match succeeds and returns the server response.\n */\nfireauth.AuthCredential.prototype.matchIdTokenWithUid =\n function(rpcHandler, uid) {};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential. This\n * will be exposed as toJSON() externally.\n */\nfireauth.AuthCredential.prototype.toPlainObject = function() {};\n\n\n/**\n * @param {!goog.Promise<!Object>} idTokenResolver A promise that resolves with\n * the ID token response.\n * @param {string} uid The UID to match in the token response.\n * @return {!goog.Promise<!Object>} A promise that resolves with the same\n * response if the UID matches.\n */\nfireauth.AuthCredential.verifyTokenResponseUid =\n function(idTokenResolver, uid) {\n return idTokenResolver.then(function(response) {\n // This should not happen as rpcHandler verifyAssertion and verifyPassword\n // always guarantee an ID token is available.\n if (response[fireauth.RpcHandler.AuthServerField.ID_TOKEN]) {\n // Parse the token object.\n var parsedIdToken = fireauth.IdToken.parse(\n response[fireauth.RpcHandler.AuthServerField.ID_TOKEN]);\n // Confirm token localId matches the provided UID. If not, throw the user\n // mismatch error.\n if (!parsedIdToken || uid != parsedIdToken.getLocalId()) {\n throw new fireauth.AuthError(fireauth.authenum.Error.USER_MISMATCH);\n }\n return response;\n }\n throw new fireauth.AuthError(fireauth.authenum.Error.USER_MISMATCH);\n })\n .thenCatch(function(error) {\n // Translate auth/user-not-found error directly to auth/user-mismatch.\n throw fireauth.AuthError.translateError(\n error,\n fireauth.authenum.Error.USER_DELETED,\n fireauth.authenum.Error.USER_MISMATCH);\n });\n};\n\n\n\n/**\n * The interface that represents the Auth provider.\n * @interface\n */\nfireauth.AuthProvider = function() {};\n\n\n/**\n * @param {...*} var_args The credential data.\n * @return {!fireauth.AuthCredential} The Auth provider credential.\n */\nfireauth.AuthProvider.credential;\n\n\n/**\n * @typedef {{\n * accessToken: (?string|undefined),\n * idToken: (?string|undefined),\n * nonce: (?string|undefined),\n * oauthToken: (?string|undefined),\n * oauthTokenSecret: (?string|undefined),\n * pendingToken: (?string|undefined)\n * }}\n */\nfireauth.OAuthResponse;\n\n\n/**\n * The SAML Auth credential class. The Constructor is not publicly visible.\n * This is constructed by the SDK on successful or failure after SAML sign-in\n * and returned to developer.\n * @param {!fireauth.idp.ProviderId} providerId The provider ID.\n * @param {string} pendingToken The SAML response pending token.\n * @constructor\n * @implements {fireauth.AuthCredential}\n */\nfireauth.SAMLAuthCredential = function(providerId, pendingToken) {\n if (pendingToken) {\n /** @private {string} The pending token where SAML response is encrypted. */\n this.pendingToken_ = pendingToken;\n } else {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'failed to construct a credential');\n }\n\n fireauth.object.setReadonlyProperty(this, 'providerId', providerId);\n fireauth.object.setReadonlyProperty(this, 'signInMethod', providerId);\n};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n * idTokenPromise The RPC handler method that returns a promise which\n * resolves with an ID token.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.getIdTokenProvider =\n function(rpcHandler) {\n return rpcHandler.verifyAssertion(\n /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (\n this.makeVerifyAssertionRequest_()));\n};\n\n\n/**\n * Links the credential to an existing account, identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The rpc handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n * are linked, returning the backend response.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.linkToIdToken =\n function(rpcHandler, idToken) {\n var request = this.makeVerifyAssertionRequest_();\n request['idToken'] = idToken;\n return rpcHandler.verifyAssertionForLinking(\n /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request));\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n * idToken UID match succeeds and returns the server response.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.matchIdTokenWithUid =\n function(rpcHandler, uid) {\n var request = this.makeVerifyAssertionRequest_();\n // Do not create a new account if the user doesn't exist.\n return fireauth.AuthCredential.verifyTokenResponseUid(\n rpcHandler.verifyAssertionForExisting(\n /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request)),\n uid);\n};\n\n\n/**\n * @return {!Object} A request to the VerifyAssertion endpoint, populated with\n * the assertion data from this credential.\n * @private\n */\nfireauth.SAMLAuthCredential.prototype.makeVerifyAssertionRequest_ =\n function() {\n return {\n 'pendingToken': this.pendingToken_,\n // Always use http://localhost.\n 'requestUri': 'http://localhost'\n };\n};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential.\n * @override\n */\nfireauth.SAMLAuthCredential.prototype.toPlainObject = function() {\n return {\n 'providerId': this['providerId'],\n 'signInMethod': this['signInMethod'],\n 'pendingToken': this.pendingToken_\n };\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of a\n * SAMLAuthCredential.\n * @return {?fireauth.SAMLAuthCredential} The SAML credential if the object\n * is a JSON representation of a SAMLAuthCredential, null otherwise.\n */\nfireauth.SAMLAuthCredential.fromJSON = function(json) {\n if (json &&\n json['providerId'] &&\n json['signInMethod'] &&\n json['providerId'].indexOf(fireauth.constants.SAML_PREFIX) == 0 &&\n json['pendingToken']) {\n try {\n return new fireauth.SAMLAuthCredential(\n json['providerId'], json['pendingToken']);\n } catch (e) {\n return null;\n }\n }\n return null;\n};\n\n\n/**\n * The OAuth credential class.\n * @param {!fireauth.idp.ProviderId} providerId The provider ID.\n * @param {!fireauth.OAuthResponse} oauthResponse The OAuth\n * response object containing token information.\n * @param {!fireauth.idp.SignInMethod} signInMethod The sign in method.\n * @constructor\n * @implements {fireauth.AuthCredential}\n */\nfireauth.OAuthCredential = function(providerId, oauthResponse, signInMethod) {\n /**\n * @private {?string} The pending token where the IdP response is encrypted.\n */\n this.pendingToken_ = null;\n if (oauthResponse['idToken'] || oauthResponse['accessToken']) {\n // OAuth 2 and either ID token or access token.\n if (oauthResponse['idToken']) {\n fireauth.object.setReadonlyProperty(\n this, 'idToken', oauthResponse['idToken']);\n }\n if (oauthResponse['accessToken']) {\n fireauth.object.setReadonlyProperty(\n this, 'accessToken', oauthResponse['accessToken']);\n }\n // Add nonce if available and no pendingToken is present.\n if (oauthResponse['nonce'] && !oauthResponse['pendingToken']) {\n fireauth.object.setReadonlyProperty(\n this, 'nonce', oauthResponse['nonce']);\n }\n if (oauthResponse['pendingToken']) {\n this.pendingToken_ = oauthResponse['pendingToken'];\n }\n } else if (oauthResponse['oauthToken'] &&\n oauthResponse['oauthTokenSecret']) {\n // OAuth 1 and OAuth token with OAuth token secret.\n fireauth.object.setReadonlyProperty(\n this, 'accessToken', oauthResponse['oauthToken']);\n fireauth.object.setReadonlyProperty(\n this, 'secret', oauthResponse['oauthTokenSecret']);\n } else {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'failed to construct a credential');\n }\n\n fireauth.object.setReadonlyProperty(this, 'providerId', providerId);\n fireauth.object.setReadonlyProperty(this, 'signInMethod', signInMethod);\n};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n * idTokenPromise The RPC handler method that returns a promise which\n * resolves with an ID token.\n * @override\n */\nfireauth.OAuthCredential.prototype.getIdTokenProvider = function(rpcHandler) {\n return rpcHandler.verifyAssertion(\n /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (\n this.makeVerifyAssertionRequest_()));\n};\n\n\n/**\n * Links the credential to an existing account, identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The rpc handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n * are linked, returning the backend response.\n * @override\n */\nfireauth.OAuthCredential.prototype.linkToIdToken =\n function(rpcHandler, idToken) {\n var request = this.makeVerifyAssertionRequest_();\n request['idToken'] = idToken;\n return rpcHandler.verifyAssertionForLinking(\n /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request));\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n * idToken UID match succeeds and returns the server response.\n * @override\n */\nfireauth.OAuthCredential.prototype.matchIdTokenWithUid =\n function(rpcHandler, uid) {\n var request = this.makeVerifyAssertionRequest_();\n // Do not create a new account if the user doesn't exist.\n return fireauth.AuthCredential.verifyTokenResponseUid(\n rpcHandler.verifyAssertionForExisting(\n /** @type {!fireauth.RpcHandler.VerifyAssertionData} */ (request)),\n uid);\n};\n\n\n/**\n * @return {!Object} A request to the VerifyAssertion endpoint, populated with\n * the OAuth data from this credential.\n * @private\n */\nfireauth.OAuthCredential.prototype.makeVerifyAssertionRequest_ = function() {\n var postBody = {};\n if (this['idToken']) {\n postBody['id_token'] = this['idToken'];\n }\n if (this['accessToken']) {\n postBody['access_token'] = this['accessToken'];\n }\n if (this['secret']) {\n postBody['oauth_token_secret'] = this['secret'];\n }\n postBody['providerId'] = this['providerId'];\n // Pass nonce in postBody if available.\n if (this['nonce'] && !this.pendingToken_) {\n postBody['nonce'] = this['nonce'];\n }\n var request = {\n 'postBody': goog.Uri.QueryData.createFromMap(postBody).toString(),\n // Always use http://localhost.\n 'requestUri': 'http://localhost'\n };\n if (this.pendingToken_) {\n // For pendingToken, just pass it through and drop postBody.\n delete request['postBody'];\n request['pendingToken'] = this.pendingToken_;\n }\n return request;\n};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential.\n * @override\n */\nfireauth.OAuthCredential.prototype.toPlainObject = function() {\n var obj = {\n 'providerId': this['providerId'],\n 'signInMethod': this['signInMethod']\n };\n if (this['idToken']) {\n obj['oauthIdToken'] = this['idToken'];\n }\n if (this['accessToken']) {\n obj['oauthAccessToken'] = this['accessToken'];\n }\n if (this['secret']) {\n obj['oauthTokenSecret'] = this['secret'];\n }\n if (this['nonce']) {\n obj['nonce'] = this['nonce'];\n }\n if (this.pendingToken_) {\n obj['pendingToken'] = this.pendingToken_;\n }\n return obj;\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of an\n * OAuthCredential.\n * @return {?fireauth.OAuthCredential} The OAuth/OIDC credential if the object\n * is a JSON representation of an OAuthCredential, null otherwise.\n */\nfireauth.OAuthCredential.fromJSON = function(json) {\n if (json &&\n json['providerId'] &&\n json['signInMethod']) {\n // Convert to OAuthResponse format.\n var oauthResponse = {\n // OIDC && google.com.\n 'idToken': json['oauthIdToken'],\n // OAuth 2.0 providers.\n 'accessToken': json['oauthTokenSecret'] ? null : json['oauthAccessToken'],\n // OAuth 1.0 provider, eg. Twitter.\n 'oauthTokenSecret': json['oauthTokenSecret'],\n 'oauthToken': json['oauthTokenSecret'] && json['oauthAccessToken'],\n 'nonce': json['nonce'],\n 'pendingToken': json['pendingToken']\n };\n try {\n // Constructor will validate the OAuthResponse.\n return new fireauth.OAuthCredential(\n json['providerId'], oauthResponse, json['signInMethod']);\n } catch (e) {\n return null;\n }\n }\n return null;\n};\n\n\n/**\n * A generic OAuth provider (OAuth1 or OAuth2).\n * @param {string} providerId The IdP provider ID (e.g. google.com,\n * facebook.com) registered with the backend.\n * @param {?Array<string>=} opt_reservedParams The backlist of parameters that\n * cannot be set through setCustomParameters.\n * @constructor\n */\nfireauth.FederatedProvider = function(providerId, opt_reservedParams) {\n /** @private {!Array<string>} */\n this.reservedParams_ = opt_reservedParams || [];\n\n // Set read only instance providerId property.\n // Set read only instance isOAuthProvider property.\n fireauth.object.setReadonlyProperties(this, {\n 'providerId': providerId,\n 'isOAuthProvider': true\n });\n\n /** @private {!Object} The OAuth custom parameters for current provider. */\n this.customParameters_ = {};\n /** @protected {?string} The custom OAuth language parameter. */\n this.languageParameter =\n (fireauth.idp.getIdpSettings(/** @type {!fireauth.idp.ProviderId} */ (\n providerId)) || {}).languageParam || null;\n /** @protected {?string} The default language. */\n this.defaultLanguageCode = null;\n};\n\n/**\n * @param {!Object} customParameters The custom OAuth parameters to pass\n * in OAuth request.\n * @return {!fireauth.FederatedProvider} The FederatedProvider instance, for\n * chaining method calls.\n */\nfireauth.FederatedProvider.prototype.setCustomParameters =\n function(customParameters) {\n this.customParameters_ = goog.object.clone(customParameters);\n return this;\n};\n\n\n/**\n * Set the default language code on the provider instance.\n * @param {?string} languageCode The default language code to set if not already\n * provided in the custom parameters.\n */\nfireauth.FederatedProvider.prototype.setDefaultLanguage =\n function(languageCode) {\n this.defaultLanguageCode = languageCode;\n};\n\n\n/**\n * @return {!Object} The custom OAuth parameters to pass in OAuth request.\n */\nfireauth.FederatedProvider.prototype.getCustomParameters = function() {\n // The backend already checks for these values and makes sure no reserved\n // fields like client ID, redirect URI, state are overwritten by these\n // fields.\n var params =\n fireauth.util.copyWithoutNullsOrUndefined(this.customParameters_);\n // Convert to strings.\n for (var key in params) {\n params[key] = params[key].toString();\n }\n // Remove blacklisted OAuth custom parameters.\n var customParams =\n fireauth.util.removeEntriesWithKeys(params, this.reservedParams_);\n // If language param supported and not already provided, use default language.\n if (this.languageParameter &&\n this.defaultLanguageCode &&\n !customParams[this.languageParameter]) {\n customParams[this.languageParameter] = this.defaultLanguageCode;\n }\n return customParams;\n};\n\n\n/**\n * Generic SAML auth provider.\n * @param {string} providerId The SAML IdP provider ID (e.g. saml.saml2rp)\n * registered with the backend.\n * @constructor\n * @extends {fireauth.FederatedProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.SAMLAuthProvider = function(providerId) {\n // SAML provider IDs must be prefixed with the SAML_PREFIX.\n if (!fireauth.idp.isSaml(providerId)) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n 'SAML provider IDs must be prefixed with \"' +\n fireauth.constants.SAML_PREFIX + '\"');\n }\n // isOAuthProvider is true even though this is not an OAuth provider.\n // This can be confusing as this is a SAML provider. However, this property\n // is needed to allow signInWithPopup/Redirect. We should rename it to\n // something more accurate: isFederatedProvider.\n fireauth.SAMLAuthProvider.base(this, 'constructor', providerId, []);\n};\ngoog.inherits(fireauth.SAMLAuthProvider, fireauth.FederatedProvider);\n\n\n/**\n * Generic OAuth2 Auth provider.\n * @param {string} providerId The IdP provider ID (e.g. google.com,\n * facebook.com) registered with the backend.\n * @constructor\n * @extends {fireauth.FederatedProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.OAuthProvider = function(providerId) {\n fireauth.OAuthProvider.base(this, 'constructor', providerId,\n fireauth.idp.RESERVED_OAUTH2_PARAMS);\n\n /** @private {!Array<string>} The list of OAuth2 scopes to request. */\n this.scopes_ = [];\n};\ngoog.inherits(fireauth.OAuthProvider, fireauth.FederatedProvider);\n\n\n/**\n * @param {string} scope The OAuth scope to request.\n * @return {!fireauth.OAuthProvider} The OAuthProvider instance, for chaining\n * method calls.\n */\nfireauth.OAuthProvider.prototype.addScope = function(scope) {\n // If not already added, add scope to list.\n if (!goog.array.contains(this.scopes_, scope)) {\n this.scopes_.push(scope);\n }\n return this;\n};\n\n\n/** @return {!Array<string>} The Auth provider's list of scopes. */\nfireauth.OAuthProvider.prototype.getScopes = function() {\n return goog.array.clone(this.scopes_);\n};\n\n\n/**\n * Initializes an OAuth AuthCredential. At least one of ID token or access token\n * must be defined. When providing an OIDC ID token with a nonce encoded, the\n * raw nonce must also be provided.\n * @param {?Object|string} optionsOrIdToken Either the options object containing\n * the ID token, access token and raw nonce or the ID token string.\n * @param {?string=} opt_accessToken The optional OAuth access token.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.OAuthProvider.prototype.credential =\n function(optionsOrIdToken, opt_accessToken) {\n var oauthResponse;\n if (goog.isObject(optionsOrIdToken)) {\n oauthResponse = {\n 'idToken': optionsOrIdToken['idToken'] || null,\n 'accessToken': optionsOrIdToken['accessToken'] || null,\n 'nonce': optionsOrIdToken['rawNonce'] || null\n };\n } else {\n oauthResponse = {\n 'idToken': optionsOrIdToken || null,\n 'accessToken': opt_accessToken || null\n };\n }\n if (!oauthResponse['idToken'] && !oauthResponse['accessToken']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'credential failed: must provide the ID token and/or the access ' +\n 'token.');\n }\n // For OAuthCredential, sign in method is same as providerId.\n return new fireauth.OAuthCredential(this['providerId'],\n oauthResponse,\n this['providerId']);\n};\n\n\n/**\n * Facebook Auth provider.\n * @constructor\n * @extends {fireauth.OAuthProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.FacebookAuthProvider = function() {\n fireauth.FacebookAuthProvider.base(this, 'constructor',\n fireauth.idp.ProviderId.FACEBOOK);\n};\ngoog.inherits(fireauth.FacebookAuthProvider, fireauth.OAuthProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.FacebookAuthProvider,\n 'PROVIDER_ID', fireauth.idp.ProviderId.FACEBOOK);\n\nfireauth.object.setReadonlyProperty(fireauth.FacebookAuthProvider,\n 'FACEBOOK_SIGN_IN_METHOD', fireauth.idp.SignInMethod.FACEBOOK);\n\n\n/**\n * Initializes a Facebook AuthCredential.\n * @param {string} accessTokenOrObject The Facebook access token, or object\n * containing the token for FirebaseUI backwards compatibility.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.FacebookAuthProvider.credential = function(accessTokenOrObject) {\n if (!accessTokenOrObject) {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'credential failed: expected 1 argument (the OAuth access token).');\n }\n var accessToken = accessTokenOrObject;\n if (goog.isObject(accessTokenOrObject)) {\n accessToken = accessTokenOrObject['accessToken'];\n }\n return new fireauth.FacebookAuthProvider().credential({\n 'accessToken': /** @type {string} */ (accessToken)\n });\n};\n\n\n/**\n * GitHub Auth provider.\n * @constructor\n * @extends {fireauth.OAuthProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.GithubAuthProvider = function() {\n fireauth.GithubAuthProvider.base(this, 'constructor',\n fireauth.idp.ProviderId.GITHUB);\n};\ngoog.inherits(fireauth.GithubAuthProvider, fireauth.OAuthProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.GithubAuthProvider,\n 'PROVIDER_ID', fireauth.idp.ProviderId.GITHUB);\n\nfireauth.object.setReadonlyProperty(fireauth.GithubAuthProvider,\n 'GITHUB_SIGN_IN_METHOD', fireauth.idp.SignInMethod.GITHUB);\n\n\n/**\n * Initializes a GitHub AuthCredential.\n * @param {string} accessTokenOrObject The GitHub access token, or object\n * containing the token for FirebaseUI backwards compatibility.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.GithubAuthProvider.credential = function(accessTokenOrObject) {\n if (!accessTokenOrObject) {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'credential failed: expected 1 argument (the OAuth access token).');\n }\n var accessToken = accessTokenOrObject;\n if (goog.isObject(accessTokenOrObject)) {\n accessToken = accessTokenOrObject['accessToken'];\n }\n return new fireauth.GithubAuthProvider().credential({\n 'accessToken': /** @type {string} */ (accessToken)\n });\n};\n\n\n/**\n * Google Auth provider.\n * @constructor\n * @extends {fireauth.OAuthProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.GoogleAuthProvider = function() {\n fireauth.GoogleAuthProvider.base(this, 'constructor',\n fireauth.idp.ProviderId.GOOGLE);\n\n // Add profile scope to Google Auth provider as default scope.\n // This is to ensure profile info is populated in current user.\n this.addScope('profile');\n};\ngoog.inherits(fireauth.GoogleAuthProvider, fireauth.OAuthProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.GoogleAuthProvider,\n 'PROVIDER_ID', fireauth.idp.ProviderId.GOOGLE);\n\nfireauth.object.setReadonlyProperty(fireauth.GoogleAuthProvider,\n 'GOOGLE_SIGN_IN_METHOD', fireauth.idp.SignInMethod.GOOGLE);\n\n\n/**\n * Initializes a Google AuthCredential.\n * @param {?string=} idTokenOrObject The Google ID token. If null or undefined,\n * we expect the access token to be passed. It can also be an object\n * containing the tokens for FirebaseUI backwards compatibility.\n * @param {?string=} accessToken The Google access token. If null or\n * undefined, we expect the ID token to have been passed.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.GoogleAuthProvider.credential =\n function(idTokenOrObject, accessToken) {\n var idToken = idTokenOrObject;\n if (goog.isObject(idTokenOrObject)) {\n idToken = idTokenOrObject['idToken'];\n accessToken = idTokenOrObject['accessToken'];\n }\n return new fireauth.GoogleAuthProvider().credential({\n 'idToken': /** @type {string} */ (idToken),\n 'accessToken': /** @type {string} */ (accessToken)\n });\n};\n\n\n/**\n * Twitter Auth provider.\n * @constructor\n * @extends {fireauth.FederatedProvider}\n * @implements {fireauth.AuthProvider}\n */\nfireauth.TwitterAuthProvider = function() {\n fireauth.TwitterAuthProvider.base(this, 'constructor',\n fireauth.idp.ProviderId.TWITTER,\n fireauth.idp.RESERVED_OAUTH1_PARAMS);\n};\ngoog.inherits(fireauth.TwitterAuthProvider, fireauth.FederatedProvider);\n\nfireauth.object.setReadonlyProperty(fireauth.TwitterAuthProvider,\n 'PROVIDER_ID', fireauth.idp.ProviderId.TWITTER);\n\nfireauth.object.setReadonlyProperty(fireauth.TwitterAuthProvider,\n 'TWITTER_SIGN_IN_METHOD', fireauth.idp.SignInMethod.TWITTER);\n\n\n/**\n * Initializes a Twitter AuthCredential.\n * @param {string} tokenOrObject The Twitter access token, or object\n * containing the token for FirebaseUI backwards compatibility.\n * @param {string} secret The Twitter secret.\n * @return {!fireauth.AuthCredential} The Auth credential object.\n */\nfireauth.TwitterAuthProvider.credential = function(tokenOrObject, secret) {\n var tokenObject = tokenOrObject;\n if (!goog.isObject(tokenObject)) {\n tokenObject = {\n 'oauthToken': tokenOrObject,\n 'oauthTokenSecret': secret\n };\n }\n\n if (!tokenObject['oauthToken'] || !tokenObject['oauthTokenSecret']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'credential failed: expected 2 arguments (the OAuth access token ' +\n 'and secret).');\n }\n\n return new fireauth.OAuthCredential(fireauth.idp.ProviderId.TWITTER,\n /** @type {!fireauth.OAuthResponse} */ (tokenObject),\n fireauth.idp.SignInMethod.TWITTER);\n};\n\n\n/**\n * The email and password credential class.\n * @param {string} email The credential email.\n * @param {string} password The credential password.\n * @param {string=} opt_signInMethod The credential sign in method can be either\n * 'password' or 'emailLink'\n * @constructor\n * @implements {fireauth.AuthCredential}\n */\nfireauth.EmailAuthCredential = function(email, password, opt_signInMethod) {\n this.email_ = email;\n this.password_ = password;\n fireauth.object.setReadonlyProperty(this, 'providerId',\n fireauth.idp.ProviderId.PASSWORD);\n var signInMethod = opt_signInMethod ===\n fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD'] ?\n fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD'] :\n fireauth.EmailAuthProvider['EMAIL_PASSWORD_SIGN_IN_METHOD'];\n fireauth.object.setReadonlyProperty(this, 'signInMethod', signInMethod);\n};\n\n\n/**\n * Returns a promise to retrieve ID token using the underlying RPC handler API\n * for the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object, !fireauth.AuthError>}\n * idTokenPromise The RPC handler method that returns a promise which\n * resolves with an ID token.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.getIdTokenProvider =\n function(rpcHandler) {\n if (this['signInMethod'] ==\n fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']) {\n return rpcHandler.emailLinkSignIn(this.email_, this.password_);\n }\n return rpcHandler.verifyPassword(this.email_, this.password_);\n};\n\n\n/**\n * Adds an email and password account to an existing account, identified by an\n * ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n * are linked, returning the backend response.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.linkToIdToken =\n function(rpcHandler, idToken) {\n if (this['signInMethod'] ==\n fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']) {\n return rpcHandler.emailLinkSignInForLinking(\n idToken, this.email_, this.password_);\n }\n return rpcHandler.updateEmailAndPassword(\n idToken, this.email_, this.password_);\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The rpc handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n * reauthentication succeeds.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.matchIdTokenWithUid =\n function(rpcHandler, uid) {\n // Do not create a new account if the user doesn't exist.\n return fireauth.AuthCredential.verifyTokenResponseUid(\n // This shouldn't create a new email/password account.\n this.getIdTokenProvider(rpcHandler),\n uid);\n};\n\n\n/**\n * @return {!Object} The plain object representation of an Auth credential.\n * @override\n */\nfireauth.EmailAuthCredential.prototype.toPlainObject = function() {\n return {\n 'email': this.email_,\n 'password': this.password_,\n 'signInMethod': this['signInMethod']\n };\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of a\n * EmailAuthCredential.\n * @return {?fireauth.EmailAuthCredential} The email credential if the object\n * is a JSON representation of an EmailAuthCredential, null otherwise.\n */\nfireauth.EmailAuthCredential.fromJSON = function(json) {\n if (json && json['email'] && json['password']) {\n return new fireauth.EmailAuthCredential(\n json['email'],\n json['password'],\n json['signInMethod']);\n }\n return null;\n};\n\n\n/**\n * Email password Auth provider implementation.\n * @constructor\n * @implements {fireauth.AuthProvider}\n */\nfireauth.EmailAuthProvider = function() {\n // Set read-only instance providerId and isOAuthProvider property.\n fireauth.object.setReadonlyProperties(this, {\n 'providerId': fireauth.idp.ProviderId.PASSWORD,\n 'isOAuthProvider': false\n });\n};\n\n\n/**\n * Initializes an instance of an email/password Auth credential.\n * @param {string} email The credential email.\n * @param {string} password The credential password.\n * @return {!fireauth.EmailAuthCredential} The Auth credential object.\n */\nfireauth.EmailAuthProvider.credential = function(email, password) {\n return new fireauth.EmailAuthCredential(email, password);\n};\n\n\n/**\n * @param {string} email The credential email.\n * @param {string} emailLink The credential email link.\n * @return {!fireauth.EmailAuthCredential} The Auth credential object.\n */\nfireauth.EmailAuthProvider.credentialWithLink = function(email, emailLink) {\n var actionCodeUrl = fireauth.EmailAuthProvider\n .getActionCodeUrlFromSignInEmailLink(emailLink);\n if (!actionCodeUrl) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!');\n }\n return new fireauth.EmailAuthCredential(email, actionCodeUrl['code'],\n fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']);\n};\n\n\n/**\n * @param {string} emailLink The sign in email link to be validated.\n * @return {?fireauth.ActionCodeURL} The sign in email link action code URL.\n * Returns null if the email link is invalid.\n */\nfireauth.EmailAuthProvider.getActionCodeUrlFromSignInEmailLink =\n function(emailLink) {\n emailLink = fireauth.DynamicLink.parseDeepLink(emailLink);\n var actionCodeUrl = fireauth.ActionCodeURL.parseLink(emailLink);\n if (actionCodeUrl && (actionCodeUrl['operation'] ===\n fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN)) {\n return actionCodeUrl;\n }\n return null;\n};\n\n\n// Set read only PROVIDER_ID property.\nfireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, {\n 'PROVIDER_ID': fireauth.idp.ProviderId.PASSWORD\n});\n\n// Set read only EMAIL_LINK_SIGN_IN_METHOD property.\nfireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, {\n 'EMAIL_LINK_SIGN_IN_METHOD': fireauth.idp.SignInMethod.EMAIL_LINK\n});\n\n// Set read only EMAIL_PASSWORD_SIGN_IN_METHOD property.\nfireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, {\n 'EMAIL_PASSWORD_SIGN_IN_METHOD': fireauth.idp.SignInMethod.EMAIL_PASSWORD\n});\n\n\n/**\n * A credential for phone number sign-in. Phone credentials can also be used as\n * second factor assertions.\n * A `PhoneAuthCredential` is also a `MultiFactorAuthCredential`. A\n * `PhoneMultiFactorAssertion` requires a `PhoneAuthCredential`.\n * @param {!fireauth.PhoneAuthCredential.Parameters_} params The credential\n * parameters that prove the user owns the claimed phone number.\n * @constructor\n * @implements {fireauth.MultiFactorAuthCredential}\n */\nfireauth.PhoneAuthCredential = function(params) {\n // Either verification ID and code, or phone number temporary proof must be\n // provided.\n if (!(params.verificationId && params.verificationCode) &&\n !(params.temporaryProof && params.phoneNumber)) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n\n /**\n * The phone Auth parameters that prove ownership of a phone number, either\n * through completion of a phone verification flow, or by referencing a\n * previously completed verification flow (\"temporaryProof\").\n * @private {!fireauth.PhoneAuthCredential.Parameters_}\n */\n this.params_ = params;\n\n fireauth.object.setReadonlyProperty(this, 'providerId',\n fireauth.idp.ProviderId.PHONE);\n /**\n * @public {string} The provider ID required by the\n * `fireauth.MultiFactorAuthCredential` interface.\n */\n this.providerId = fireauth.idp.ProviderId.PHONE;\n\n fireauth.object.setReadonlyProperty(\n this, 'signInMethod', fireauth.idp.SignInMethod.PHONE);\n};\n\n\n/**\n * Parameters that prove ownership of a phone number via a ID \"verificationId\"\n * of a request to send a code to the phone number, with the code\n * \"verificationCode\" that the user received on their phone.\n * @private\n * @typedef {{\n * verificationId: string,\n * verificationCode: string\n * }}\n */\nfireauth.PhoneAuthCredential.VerificationParameters_;\n\n\n/**\n * Parameters that prove ownership of a phone number by referencing a previously\n * completed phone Auth flow.\n * @private\n * @typedef {{\n * temporaryProof: string,\n * phoneNumber: string\n * }}\n */\nfireauth.PhoneAuthCredential.TemporaryProofParameters_;\n\n\n/**\n * @private\n * @typedef {\n * !fireauth.PhoneAuthCredential.VerificationParameters_|\n * !fireauth.PhoneAuthCredential.TemporaryProofParameters_\n * }\n */\nfireauth.PhoneAuthCredential.Parameters_;\n\n\n/**\n * Retrieves an ID token from the backend given the current credential.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @return {!goog.Promise<!Object>} A Promise that resolves with the\n * backend response.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.getIdTokenProvider =\n function(rpcHandler) {\n return rpcHandler.verifyPhoneNumber(this.makeVerifyPhoneNumberRequest_());\n};\n\n\n/**\n * Adds a phone credential to an existing account identified by an ID token.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} idToken The ID token of the existing account.\n * @return {!goog.Promise<!Object>} A Promise that resolves when the accounts\n * are linked, returning the backend response.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.linkToIdToken =\n function(rpcHandler, idToken) {\n var request = this.makeVerifyPhoneNumberRequest_();\n request['idToken'] = idToken;\n return rpcHandler.verifyPhoneNumberForLinking(request);\n};\n\n\n/**\n * Tries to match the credential's idToken with the provided UID.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler.\n * @param {string} uid The UID of the user to reauthenticate.\n * @return {!goog.Promise<!Object>} A Promise that resolves when\n * reauthentication succeeds.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.matchIdTokenWithUid =\n function(rpcHandler, uid) {\n var request = this.makeVerifyPhoneNumberRequest_();\n return fireauth.AuthCredential.verifyTokenResponseUid(\n rpcHandler.verifyPhoneNumberForExisting(request),\n uid);\n};\n\n\n/**\n * Converts a PhoneAuthCredential to a plain object.\n * @return {!Object}\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.toPlainObject = function() {\n var obj = {\n 'providerId': fireauth.idp.ProviderId.PHONE\n };\n if (this.params_.verificationId) {\n obj['verificationId'] = this.params_.verificationId;\n }\n if (this.params_.verificationCode) {\n obj['verificationCode'] = this.params_.verificationCode;\n }\n if (this.params_.temporaryProof) {\n obj['temporaryProof'] = this.params_.temporaryProof;\n }\n if (this.params_.phoneNumber) {\n obj['phoneNumber'] = this.params_.phoneNumber;\n }\n return obj;\n};\n\n\n/**\n * @param {?Object|undefined} json The plain object representation of a\n * PhoneAuthCredential.\n * @return {?fireauth.PhoneAuthCredential} The phone credential if the object\n * is a JSON representation of an PhoneAuthCredential, null otherwise.\n */\nfireauth.PhoneAuthCredential.fromJSON = function(json) {\n if (json &&\n json['providerId'] === fireauth.idp.ProviderId.PHONE &&\n ((json['verificationId'] && json['verificationCode']) ||\n (json['temporaryProof'] && json['phoneNumber']))) {\n var params = {};\n var allowedKeys = [\n 'verificationId', 'verificationCode', 'temporaryProof', 'phoneNumber'\n ];\n goog.array.forEach(allowedKeys, function(key) {\n if (json[key]) {\n params[key] = json[key];\n }\n });\n return new fireauth.PhoneAuthCredential(\n /** @type {!fireauth.PhoneAuthCredential.Parameters_} */ (params));\n }\n return null;\n};\n\n\n/**\n * @return {!Object} A request to the verifyPhoneNumber endpoint based on the\n * current state of the object.\n * @private\n */\nfireauth.PhoneAuthCredential.prototype.makeVerifyPhoneNumberRequest_ =\n function() {\n if (this.params_.temporaryProof && this.params_.phoneNumber) {\n return {\n 'temporaryProof': this.params_.temporaryProof,\n 'phoneNumber': this.params_.phoneNumber\n };\n }\n\n return {\n 'sessionInfo': this.params_.verificationId,\n 'code': this.params_.verificationCode\n };\n};\n\n\n/**\n * Finalizes the 2nd factor enrollment flow with the current AuthCredential\n * using the enrollment request identifier.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorEnrollmentRequestIdentifier} enrollmentRequest\n * The enrollment request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the updated ID and refresh tokens.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.finalizeMfaEnrollment =\n function(rpcHandler, enrollmentRequest) {\n goog.object.extend(\n enrollmentRequest,\n {\n 'phoneVerificationInfo': this.makeVerifyPhoneNumberRequest_()\n });\n return /** @type {!goog.Promise<{idToken: string, refreshToken: string}>} */ (\n rpcHandler.finalizePhoneMfaEnrollment(enrollmentRequest));\n};\n\n\n/**\n * Finalizes the 2nd factor sign-in flow with the current AuthCredential\n * using the sign-in request identifier.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSignInRequestIdentifier} signInRequest\n * The sign-in request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the signed in user's ID and refresh tokens.\n * @override\n */\nfireauth.PhoneAuthCredential.prototype.finalizeMfaSignIn =\n function(rpcHandler, signInRequest) {\n goog.object.extend(\n signInRequest,\n {\n 'phoneVerificationInfo': this.makeVerifyPhoneNumberRequest_()\n });\n return /** @type {!goog.Promise<{idToken: string, refreshToken: string}>} */ (\n rpcHandler.finalizePhoneMfaSignIn(signInRequest));\n};\n\n\n/**\n * Phone Auth provider implementation.\n * @param {?fireauth.Auth=} opt_auth The Firebase Auth instance.\n * @constructor\n * @implements {fireauth.AuthProvider}\n */\nfireauth.PhoneAuthProvider = function(opt_auth) {\n try {\n /** @private {!fireauth.Auth} */\n this.auth_ = opt_auth || firebase['auth']();\n } catch (e) {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'Either an instance of firebase.auth.Auth must be passed as an ' +\n 'argument to the firebase.auth.PhoneAuthProvider constructor, or the ' +\n 'default firebase App instance must be initialized via ' +\n 'firebase.initializeApp().');\n }\n fireauth.object.setReadonlyProperties(this, {\n 'providerId': fireauth.idp.ProviderId.PHONE,\n 'isOAuthProvider': false\n });\n};\n\n\n/**\n * The phone info options for single-factor sign-in. Only phone number is\n * required.\n * @private\n * @typedef {{\n * phoneNumber: string\n * }}\n */\nfireauth.PhoneAuthProvider.PhoneSingleFactorInfoOptions_;\n\n/**\n * The phone info options for multi-factor enrollment. Phone number and\n * multi-factor session are required.\n * @private\n * @typedef {{\n * phoneNumber: string,\n * session: !fireauth.MultiFactorSession\n * }}\n */\nfireauth.PhoneAuthProvider.PhoneMultiFactorEnrollInfoOptions_;\n\n\n/**\n * The phone info options for multi-factor sign-in. Either multi-factor hint or\n * multi-factor UID and multi-factor session are required.\n * @private\n * @typedef {{\n * multiFactorHint: !fireauth.MultiFactorInfo,\n * session: !fireauth.MultiFactorSession\n * }|{\n * multiFactorUid: string,\n * session: !fireauth.MultiFactorSession\n * }}\n */\nfireauth.PhoneAuthProvider.PhoneMultiFactorSignInInfoOptions_;\n\n\n/**\n * The options for verifying the ownership of the phone number. It could be\n * used for single-factor sign-in, multi-factor enrollment or multi-factor\n * sign-in.\n * @typedef {\n * !fireauth.PhoneAuthProvider.PhoneSingleFactorInfoOptions_|\n * !fireauth.PhoneAuthProvider.PhoneMultiFactorEnrollInfoOptions_|\n * !fireauth.PhoneAuthProvider.PhoneMultiFactorSignInInfoOptions_\n * }\n */\nfireauth.PhoneAuthProvider.PhoneInfoOptions;\n\n\n/**\n * Initiates a phone number confirmation flow. If session is provided, it is\n * used to verify ownership of the second factor phone number.\n *\n * @param {string|!fireauth.PhoneAuthProvider.PhoneInfoOptions} phoneInfoOptions\n * The user's phone options for verifying the ownship of the phone number.\n * @param {!firebase.auth.ApplicationVerifier} applicationVerifier The\n * application verifier for anti-abuse purposes.\n * @return {!goog.Promise<string>} A Promise that resolves with the\n * verificationId of the phone number confirmation flow.\n */\nfireauth.PhoneAuthProvider.prototype.verifyPhoneNumber =\n function(phoneInfoOptions, applicationVerifier) {\n var rpcHandler = this.auth_.getRpcHandler();\n\n // Convert the promise into a goog.Promise. If the applicationVerifier throws\n // an error, just propagate it to the client. Reset the reCAPTCHA widget every\n // time after sending the token to the server.\n return goog.Promise.resolve(applicationVerifier['verify']())\n .then(function(assertion) {\n if (typeof assertion !== 'string') {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'An implementation of firebase.auth.ApplicationVerifier' +\n '.prototype.verify() must return a firebase.Promise ' +\n 'that resolves with a string.');\n }\n\n switch (applicationVerifier['type']) {\n case 'recaptcha':\n var session = goog.isObject(phoneInfoOptions) ?\n phoneInfoOptions['session'] : null;\n // PhoneInfoOptions can be a phone number string for backward\n // compatibility.\n var phoneNumber = goog.isObject(phoneInfoOptions) ?\n phoneInfoOptions['phoneNumber'] : phoneInfoOptions;\n var verifyPromise;\n if (session &&\n session.type == fireauth.MultiFactorSession.Type.ENROLL) {\n verifyPromise = session.getRawSession()\n .then(function(rawSession) {\n return rpcHandler.startPhoneMfaEnrollment({\n 'idToken': rawSession,\n 'phoneEnrollmentInfo': {\n 'phoneNumber': phoneNumber,\n 'recaptchaToken': assertion\n }\n });\n });\n } else if (session &&\n session.type ==\n fireauth.MultiFactorSession.Type.SIGN_IN) {\n verifyPromise = session.getRawSession()\n .then(function(rawSession) {\n var mfaEnrollmentId =\n (phoneInfoOptions['multiFactorHint'] &&\n phoneInfoOptions['multiFactorHint']['uid']) ||\n phoneInfoOptions['multiFactorUid'];\n return rpcHandler.startPhoneMfaSignIn({\n 'mfaPendingCredential': rawSession,\n 'mfaEnrollmentId': mfaEnrollmentId,\n 'phoneSignInInfo': {\n 'recaptchaToken': assertion\n }\n });\n });\n } else {\n verifyPromise = rpcHandler.sendVerificationCode({\n 'phoneNumber': phoneNumber,\n 'recaptchaToken': assertion\n });\n }\n // Reset the applicationVerifier after code is sent.\n return verifyPromise.then(function(verificationId) {\n if (typeof applicationVerifier.reset === 'function') {\n applicationVerifier.reset();\n }\n return verificationId;\n }, function(error) {\n if (typeof applicationVerifier.reset === 'function') {\n applicationVerifier.reset();\n }\n throw error;\n });\n default:\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n 'Only firebase.auth.ApplicationVerifiers with ' +\n 'type=\"recaptcha\" are currently supported.');\n }\n });\n};\n\n\n/**\n * Creates a PhoneAuthCredential.\n * @param {string} verificationId The ID of the phone number flow, to correlate\n * this request with a previous call to\n * PhoneAuthProvider.prototype.verifyPhoneNumber.\n * @param {string} verificationCode The verification code that was sent to the\n * user's phone.\n * @return {!fireauth.PhoneAuthCredential}\n */\nfireauth.PhoneAuthProvider.credential =\n function(verificationId, verificationCode) {\n if (!verificationId) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_SESSION_INFO);\n }\n if (!verificationCode) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CODE);\n }\n return new fireauth.PhoneAuthCredential({\n verificationId: verificationId,\n verificationCode: verificationCode\n });\n};\n\n\n// Set read only PROVIDER_ID property.\nfireauth.object.setReadonlyProperties(fireauth.PhoneAuthProvider, {\n 'PROVIDER_ID': fireauth.idp.ProviderId.PHONE\n});\n\n\n// Set read only PHONE_SIGN_IN_METHOD property.\nfireauth.object.setReadonlyProperties(fireauth.PhoneAuthProvider, {\n 'PHONE_SIGN_IN_METHOD': fireauth.idp.SignInMethod.PHONE\n});\n\n\n/**\n * Constructs an Auth credential from a backend response.\n * Note, unlike fromJSON which constructs the AuthCredential from a toJSON()\n * response, this helper constructs the credential from the server response.\n * @param {?Object} response The backend response to build a credential from.\n * @return {?fireauth.AuthCredential} The corresponding AuthCredential.\n */\nfireauth.AuthProvider.getCredentialFromResponse = function(response) {\n // Handle phone Auth credential responses, as they have a different format\n // from other backend responses (i.e. no providerId).\n if (response['temporaryProof'] && response['phoneNumber']) {\n return new fireauth.PhoneAuthCredential({\n temporaryProof: response['temporaryProof'],\n phoneNumber: response['phoneNumber']\n });\n }\n\n // Get all OAuth response parameters from response.\n var providerId = response && response['providerId'];\n\n // Email and password is not supported as there is no situation where the\n // server would return the password to the client.\n if (!providerId || providerId === fireauth.idp.ProviderId.PASSWORD) {\n return null;\n }\n\n var accessToken = response && response['oauthAccessToken'];\n var accessTokenSecret = response && response['oauthTokenSecret'];\n // Note this is not actually returned by the backend. It is introduced in\n // rpcHandler.\n var rawNonce = response && response['nonce'];\n // Google Id Token returned when no additional scopes provided.\n var idToken = response && response['oauthIdToken'];\n // Pending token for SAML and OAuth/OIDC providers.\n var pendingToken = response && response['pendingToken'];\n try {\n switch (providerId) {\n case fireauth.idp.ProviderId.GOOGLE:\n return fireauth.GoogleAuthProvider.credential(\n idToken, accessToken);\n\n case fireauth.idp.ProviderId.FACEBOOK:\n return fireauth.FacebookAuthProvider.credential(\n accessToken);\n\n case fireauth.idp.ProviderId.GITHUB:\n return fireauth.GithubAuthProvider.credential(\n accessToken);\n\n case fireauth.idp.ProviderId.TWITTER:\n return fireauth.TwitterAuthProvider.credential(\n accessToken, accessTokenSecret);\n\n default:\n if (!accessToken && !accessTokenSecret && !idToken && !pendingToken) {\n return null;\n }\n if (pendingToken) {\n if (providerId.indexOf(fireauth.constants.SAML_PREFIX) == 0) {\n return new fireauth.SAMLAuthCredential(providerId, pendingToken);\n } else {\n // OIDC and non-default providers excluding Twitter.\n return new fireauth.OAuthCredential(\n providerId,\n {\n 'pendingToken': pendingToken,\n 'idToken': response['oauthIdToken'],\n 'accessToken': response['oauthAccessToken']\n },\n providerId);\n }\n }\n return new fireauth.OAuthProvider(providerId).credential({\n 'idToken': idToken,\n 'accessToken': accessToken,\n 'rawNonce': rawNonce\n });\n }\n } catch (e) {\n return null;\n }\n};\n\n\n/**\n * Constructs an Auth credential from a JSON representation.\n * Note, unlike getCredentialFromResponse which constructs the AuthCredential\n * from a server response, this helper constructs credential from the toJSON()\n * result.\n * @param {!Object|string} json The JSON representation to construct credential\n * from.\n * @return {?fireauth.AuthCredential} The corresponding AuthCredential.\n */\nfireauth.AuthProvider.getCredentialFromJSON = function(json) {\n var obj = typeof json === 'string' ? JSON.parse(json) : json;\n var credential;\n var fromJSON = [\n fireauth.OAuthCredential.fromJSON,\n fireauth.EmailAuthCredential.fromJSON,\n fireauth.PhoneAuthCredential.fromJSON,\n fireauth.SAMLAuthCredential.fromJSON\n ];\n for (var i = 0; i < fromJSON.length; i++) {\n credential = fromJSON[i](obj);\n if (credential) {\n return credential;\n }\n }\n return null;\n};\n\n\n/**\n * Constructs an Auth credential from a JSON representation.\n * @param {!Object|string} json The JSON representation to construct credential from.\n * @return {?fireauth.AuthCredential} The corresponding AuthCredential.\n */\nfireauth.AuthCredential.fromPlainObject =\n fireauth.AuthProvider.getCredentialFromJSON;\n\n\n/**\n * Checks if OAuth is supported by provider, if not throws an error.\n * @param {!fireauth.AuthProvider} provider The provider to check.\n */\nfireauth.AuthProvider.checkIfOAuthSupported =\n function(provider) {\n if (!provider['isOAuthProvider']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_OAUTH_PROVIDER);\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Utility for handling RPC requests to server.\n */\ngoog.provide('fireauth.RpcHandler');\ngoog.provide('fireauth.RpcHandler.ApiMethodHandler');\ngoog.provide('fireauth.RpcHandler.VerifyAssertionData');\ngoog.provide('fireauth.XmlHttpFactory');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthErrorWithCredential');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.idp.ProviderId');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Uri');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.json');\ngoog.require('goog.net.CorsXmlHttpFactory');\ngoog.require('goog.net.EventType');\ngoog.require('goog.net.FetchXmlHttpFactory');\ngoog.require('goog.net.XhrIo');\ngoog.require('goog.net.XmlHttpFactory');\ngoog.require('goog.net.jsloader');\ngoog.require('goog.object');\ngoog.require('goog.string.Const');\n\n\n\n/**\n * Firebase Auth XmlHttpRequest factory. This is useful for environments like\n * Node.js where XMLHttpRequest does not exist. XmlHttpFactory would be\n * initialized using the polyfill XMLHttpRequest module.\n * @param {function(new:XMLHttpRequest)} xmlHttpRequest The xmlHttpRequest\n * constructor.\n * @constructor\n * @extends {goog.net.XmlHttpFactory}\n * @final\n */\nfireauth.XmlHttpFactory = function(xmlHttpRequest) {\n /**\n * @private {function(new:XMLHttpRequest)} The underlying XHR reference.\n */\n this.xmlHttpRequest_ = xmlHttpRequest;\n fireauth.XmlHttpFactory.base(this, 'constructor');\n};\ngoog.inherits(fireauth.XmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/**\n * @return {!goog.net.XhrLike|!XMLHttpRequest} A new XhrLike instance.\n * @override\n */\nfireauth.XmlHttpFactory.prototype.createInstance = function() {\n return new this.xmlHttpRequest_();\n};\n\n\n/**\n * @return {!Object} Options describing how XHR objects obtained from this\n * factory should be used.\n * @override\n */\nfireauth.XmlHttpFactory.prototype.internalGetOptions = function() {\n return {};\n};\n\n\n\n/**\n * Creates an RPC request handler for the project specified by the API key.\n *\n * @param {string} apiKey The API key.\n * @param {?Object=} opt_config The RPC request processor configuration.\n * @param {?string=} opt_firebaseClientVersion The optional Firebase client\n * version to log with requests to Firebase Auth server.\n * @constructor\n */\nfireauth.RpcHandler = function(apiKey, opt_config, opt_firebaseClientVersion) {\n /** @private {string} The project API key. */\n this.apiKey_ = apiKey;\n var config = opt_config || {};\n this.secureTokenEndpoint_ = config['secureTokenEndpoint'] ||\n fireauth.RpcHandler.SECURE_TOKEN_ENDPOINT_;\n /**\n * @private @const {!fireauth.util.Delay} The delay for secure token endpoint\n * network timeout.\n */\n this.secureTokenTimeout_ = config['secureTokenTimeout'] ||\n fireauth.RpcHandler.DEFAULT_SECURE_TOKEN_TIMEOUT_;\n /** @private @const {!Object} The secure token server headers. */\n this.secureTokenHeaders_ = goog.object.clone(\n config['secureTokenHeaders'] ||\n fireauth.RpcHandler.DEFAULT_SECURE_TOKEN_HEADERS_);\n /** @private @const {string} The Firebase Auth endpoint. */\n this.firebaseEndpoint_ = config['firebaseEndpoint'] ||\n fireauth.RpcHandler.FIREBASE_ENDPOINT_;\n /** @private @const {string} The identity platform endpoint. */\n this.identityPlatformEndpoint_ = config['identityPlatformEndpoint'] ||\n fireauth.RpcHandler.IDENTITY_PLATFORM_ENDPOINT_;\n /**\n * @private @const {!fireauth.util.Delay} The delay for Firebase Auth endpoint\n * network timeout.\n */\n this.firebaseTimeout_ = config['firebaseTimeout'] ||\n fireauth.RpcHandler.DEFAULT_FIREBASE_TIMEOUT_;\n this.firebaseHeaders_ = goog.object.clone(\n config['firebaseHeaders'] ||\n fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_);\n // If Firebase client version needs to be logged too.\n if (opt_firebaseClientVersion) {\n // Log client version for Firebase Auth server.\n this.firebaseHeaders_['X-Client-Version'] = opt_firebaseClientVersion;\n // Log client version for securetoken server.\n this.secureTokenHeaders_['X-Client-Version'] = opt_firebaseClientVersion;\n }\n\n // Get XMLHttpRequest reference.\n var XMLHttpRequest = fireauth.RpcHandler.getXMLHttpRequest();\n if (!XMLHttpRequest && !fireauth.util.isWorker()) {\n // In a Node.js environment, xmlhttprequest module needs to be required.\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'The XMLHttpRequest compatibility library was not found.');\n }\n /** @private {!goog.net.XmlHttpFactory|undefined} The XHR factory. */\n this.rpcHandlerXhrFactory_ = undefined;\n // Initialize XHR factory. CORS does not apply in native environments or\n // workers so don't use CorsXmlHttpFactory in those cases.\n if (fireauth.util.isWorker()) {\n // For worker environment use FetchXmlHttpFactory.\n this.rpcHandlerXhrFactory_ = new goog.net.FetchXmlHttpFactory(\n /** @type {!WorkerGlobalScope} */ (self));\n } else if (fireauth.util.isNativeEnvironment()) {\n // For Node.js, this is the polyfill library. For other environments,\n // this is the native global XMLHttpRequest.\n this.rpcHandlerXhrFactory_ = new fireauth.XmlHttpFactory(\n /** @type {function(new:XMLHttpRequest)} */ (XMLHttpRequest));\n } else {\n // CORS Browser environment.\n this.rpcHandlerXhrFactory_ = new goog.net.CorsXmlHttpFactory();\n }\n /** @private {?string} The tenant ID. */\n this.tenantId_ = null;\n};\n\n\n/**\n * @return {?function(new:XMLHttpRequest)|undefined} The current environment\n * XMLHttpRequest. This is undefined for worker environment.\n */\nfireauth.RpcHandler.getXMLHttpRequest = function() {\n // In Node.js XMLHttpRequest is polyfilled.\n var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE;\n var XMLHttpRequest = goog.global['XMLHttpRequest'] ||\n (isNode &&\n firebase.INTERNAL['node'] &&\n firebase.INTERNAL['node']['XMLHttpRequest']);\n return XMLHttpRequest;\n};\n\n\n/**\n * Enums for HTTP request methods.\n * @enum {string}\n */\nfireauth.RpcHandler.HttpMethod = {\n POST: 'POST',\n GET: 'GET'\n};\n\n\n/**\n * Firebase Auth server error codes.\n * @enum {string}\n */\nfireauth.RpcHandler.ServerError = {\n ADMIN_ONLY_OPERATION: 'ADMIN_ONLY_OPERATION',\n CAPTCHA_CHECK_FAILED: 'CAPTCHA_CHECK_FAILED',\n CORS_UNSUPPORTED: 'CORS_UNSUPPORTED',\n CREDENTIAL_MISMATCH: 'CREDENTIAL_MISMATCH',\n CREDENTIAL_TOO_OLD_LOGIN_AGAIN: 'CREDENTIAL_TOO_OLD_LOGIN_AGAIN',\n DYNAMIC_LINK_NOT_ACTIVATED: 'DYNAMIC_LINK_NOT_ACTIVATED',\n EMAIL_CHANGE_NEEDS_VERIFICATION: 'EMAIL_CHANGE_NEEDS_VERIFICATION',\n EMAIL_EXISTS: 'EMAIL_EXISTS',\n EMAIL_NOT_FOUND: 'EMAIL_NOT_FOUND',\n EXPIRED_OOB_CODE: 'EXPIRED_OOB_CODE',\n FEDERATED_USER_ID_ALREADY_LINKED: 'FEDERATED_USER_ID_ALREADY_LINKED',\n INVALID_APP_CREDENTIAL: 'INVALID_APP_CREDENTIAL',\n INVALID_APP_ID: 'INVALID_APP_ID',\n INVALID_CERT_HASH: 'INVALID_CERT_HASH',\n INVALID_CODE: 'INVALID_CODE',\n INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI',\n INVALID_CUSTOM_TOKEN: 'INVALID_CUSTOM_TOKEN',\n INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN',\n INVALID_EMAIL: 'INVALID_EMAIL',\n INVALID_ID_TOKEN: 'INVALID_ID_TOKEN',\n INVALID_IDP_RESPONSE: 'INVALID_IDP_RESPONSE',\n INVALID_IDENTIFIER: 'INVALID_IDENTIFIER',\n INVALID_MESSAGE_PAYLOAD: 'INVALID_MESSAGE_PAYLOAD',\n INVALID_MFA_PENDING_CREDENTIAL: 'INVALID_MFA_PENDING_CREDENTIAL',\n INVALID_OAUTH_CLIENT_ID: 'INVALID_OAUTH_CLIENT_ID',\n INVALID_OOB_CODE: 'INVALID_OOB_CODE',\n INVALID_PASSWORD: 'INVALID_PASSWORD',\n INVALID_PENDING_TOKEN: 'INVALID_PENDING_TOKEN',\n INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',\n INVALID_PROVIDER_ID: 'INVALID_PROVIDER_ID',\n INVALID_RECIPIENT_EMAIL: 'INVALID_RECIPIENT_EMAIL',\n INVALID_SENDER: 'INVALID_SENDER',\n INVALID_SESSION_INFO: 'INVALID_SESSION_INFO',\n INVALID_TEMPORARY_PROOF: 'INVALID_TEMPORARY_PROOF',\n INVALID_TENANT_ID: 'INVALID_TENANT_ID',\n MFA_ENROLLMENT_NOT_FOUND: 'MFA_ENROLLMENT_NOT_FOUND',\n MISSING_ANDROID_PACKAGE_NAME: 'MISSING_ANDROID_PACKAGE_NAME',\n MISSING_APP_CREDENTIAL: 'MISSING_APP_CREDENTIAL',\n MISSING_CODE: 'MISSING_CODE',\n MISSING_CONTINUE_URI: 'MISSING_CONTINUE_URI',\n MISSING_CUSTOM_TOKEN: 'MISSING_CUSTOM_TOKEN',\n MISSING_IOS_BUNDLE_ID: 'MISSING_IOS_BUNDLE_ID',\n MISSING_MFA_ENROLLMENT_ID: 'MISSING_MFA_ENROLLMENT_ID',\n MISSING_MFA_PENDING_CREDENTIAL: 'MISSING_MFA_PENDING_CREDENTIAL',\n MISSING_OOB_CODE: 'MISSING_OOB_CODE',\n MISSING_OR_INVALID_NONCE: 'MISSING_OR_INVALID_NONCE',\n MISSING_PASSWORD: 'MISSING_PASSWORD',\n MISSING_PHONE_NUMBER: 'MISSING_PHONE_NUMBER',\n MISSING_SESSION_INFO: 'MISSING_SESSION_INFO',\n OPERATION_NOT_ALLOWED: 'OPERATION_NOT_ALLOWED',\n PASSWORD_LOGIN_DISABLED: 'PASSWORD_LOGIN_DISABLED',\n QUOTA_EXCEEDED: 'QUOTA_EXCEEDED',\n RESET_PASSWORD_EXCEED_LIMIT: 'RESET_PASSWORD_EXCEED_LIMIT',\n REJECTED_CREDENTIAL: 'REJECTED_CREDENTIAL',\n SECOND_FACTOR_EXISTS: 'SECOND_FACTOR_EXISTS',\n SECOND_FACTOR_LIMIT_EXCEEDED: 'SECOND_FACTOR_LIMIT_EXCEEDED',\n SESSION_EXPIRED: 'SESSION_EXPIRED',\n TENANT_ID_MISMATCH: 'TENANT_ID_MISMATCH',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n TOO_MANY_ATTEMPTS_TRY_LATER: 'TOO_MANY_ATTEMPTS_TRY_LATER',\n UNSUPPORTED_FIRST_FACTOR: 'UNSUPPORTED_FIRST_FACTOR',\n UNSUPPORTED_TENANT_OPERATION: 'UNSUPPORTED_TENANT_OPERATION',\n UNVERIFIED_EMAIL: 'UNVERIFIED_EMAIL',\n UNAUTHORIZED_DOMAIN: 'UNAUTHORIZED_DOMAIN',\n USER_CANCELLED: 'USER_CANCELLED',\n USER_DISABLED: 'USER_DISABLED',\n USER_NOT_FOUND: 'USER_NOT_FOUND',\n WEAK_PASSWORD: 'WEAK_PASSWORD'\n};\n\n\n/**\n * A map of server error codes to client errors.\n * @typedef {!Object<\n * !fireauth.RpcHandler.ServerError, !fireauth.authenum.Error>}\n */\nfireauth.RpcHandler.ServerErrorMap;\n\n\n/**\n * Firebase Auth response field names.\n * @enum {string}\n */\nfireauth.RpcHandler.AuthServerField = {\n ALL_PROVIDERS: 'allProviders',\n AUTH_URI: 'authUri',\n AUTHORIZED_DOMAINS: 'authorizedDomains',\n DYNAMIC_LINKS_DOMAIN: 'dynamicLinksDomain',\n EMAIL: 'email',\n ERROR_MESSAGE: 'errorMessage',\n EXPIRES_IN: 'expiresIn',\n ID_TOKEN: 'idToken',\n MFA_PENDING_CREDENTIAL: 'mfaPendingCredential',\n NEED_CONFIRMATION: 'needConfirmation',\n OAUTH_ID_TOKEN: 'oauthIdToken',\n PENDING_TOKEN: 'pendingToken',\n PHONE_RESPONSE_INFO: 'phoneResponseInfo',\n PHONE_SESSION_INFO: 'phoneSessionInfo',\n POST_BODY: 'postBody',\n PROVIDER_ID: 'providerId',\n RECAPTCHA_SITE_KEY: 'recaptchaSiteKey',\n REQUEST_URI: 'requestUri',\n REFRESH_TOKEN: 'refreshToken',\n SESSION_ID: 'sessionId',\n SESSION_INFO: 'sessionInfo',\n SIGNIN_METHODS: 'signinMethods',\n TEMPORARY_PROOF: 'temporaryProof'\n};\n\n\n/**\n * Firebase Auth response injected fields.\n * @enum {string}\n */\nfireauth.RpcHandler.InjectedResponseField = {\n NONCE: 'nonce'\n};\n\n\n/**\n * Firebase Auth getOobConfirmationCode requestType possible values.\n * @enum {string}\n */\nfireauth.RpcHandler.GetOobCodeRequestType = {\n EMAIL_SIGNIN: 'EMAIL_SIGNIN',\n NEW_EMAIL_ACCEPT: 'NEW_EMAIL_ACCEPT',\n PASSWORD_RESET: 'PASSWORD_RESET',\n VERIFY_AND_CHANGE_EMAIL: 'VERIFY_AND_CHANGE_EMAIL',\n VERIFY_EMAIL: 'VERIFY_EMAIL'\n};\n\n\n/**\n * Firebase Auth response field names.\n * @enum {string}\n */\nfireauth.RpcHandler.StsServerField = {\n ACCESS_TOKEN: 'access_token',\n EXPIRES_IN: 'expires_in',\n REFRESH_TOKEN: 'refresh_token'\n};\n\n\n/**\n * @return {string} The API key.\n */\nfireauth.RpcHandler.prototype.getApiKey = function() {\n return this.apiKey_;\n};\n\n\n/**\n * The Firebase custom locale header.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.FIREBASE_LOCALE_KEY_ = 'X-Firebase-Locale';\n\n\n/**\n * The secure token endpoint.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.SECURE_TOKEN_ENDPOINT_ =\n 'https://securetoken.googleapis.com/v1/token';\n\n\n/**\n * The default timeout delay (units in milliseconds) for requests sending to\n * STS token endpoint.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_SECURE_TOKEN_TIMEOUT_ =\n new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * The STS token RPC content headers.\n * @const {!Object}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_SECURE_TOKEN_HEADERS_ = {\n 'Content-Type': 'application/x-www-form-urlencoded'\n};\n\n\n/**\n * The Firebase endpoint.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.FIREBASE_ENDPOINT_ =\n 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/';\n\n\n/**\n * The Identity Platform endpoint.\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.IDENTITY_PLATFORM_ENDPOINT_ =\n 'https://identitytoolkit.googleapis.com/v2/';\n\n\n/**\n * The default timeout delay (units in milliseconds) for requests sending to\n * Firebase endpoint.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_FIREBASE_TIMEOUT_ =\n new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * The Firebase RPC content headers.\n * @const {!Object}\n * @private\n */\nfireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_ = {\n 'Content-Type': 'application/json'\n};\n\n\n/**\n * Updates the custom locale header.\n * @param {?string} languageCode The new languageCode.\n */\nfireauth.RpcHandler.prototype.updateCustomLocaleHeader =\n function(languageCode) {\n if (languageCode) {\n // If a language code is provided, add it to the header.\n this.firebaseHeaders_[fireauth.RpcHandler.FIREBASE_LOCALE_KEY_] =\n languageCode;\n } else {\n // Otherwise remove the custom locale header.\n delete this.firebaseHeaders_[fireauth.RpcHandler.FIREBASE_LOCALE_KEY_];\n }\n};\n\n\n/**\n * Updates the X-Client-Version in the header.\n * @param {?string} clientVersion The new client version.\n */\nfireauth.RpcHandler.prototype.updateClientVersion = function(clientVersion) {\n if (clientVersion) {\n // Update client version for Firebase Auth server.\n this.firebaseHeaders_['X-Client-Version'] = clientVersion;\n // Update client version for securetoken server.\n this.secureTokenHeaders_['X-Client-Version'] = clientVersion;\n } else {\n // Remove client version from header.\n delete this.firebaseHeaders_['X-Client-Version'];\n delete this.secureTokenHeaders_['X-Client-Version'];\n }\n};\n\n\n/**\n * Updates the tenant ID in the request.\n * @param {?string} tenantId The new tenant ID.\n */\nfireauth.RpcHandler.prototype.updateTenantId = function(tenantId) {\n this.tenantId_ = tenantId;\n};\n\n\n/**\n * Returns the tenant ID.\n * @return {?string} The tenant ID.\n */\nfireauth.RpcHandler.prototype.getTenantId = function() {\n return this.tenantId_;\n};\n\n\n/**\n * Sends XhrIo request using goog.net.XhrIo.\n * @param {string} url The URL to make a request to.\n * @param {function(?Object)=} opt_callback The callback to run on completion.\n * @param {fireauth.RpcHandler.HttpMethod=} opt_httpMethod The HTTP send method.\n * @param {?ArrayBuffer|?ArrayBufferView|?Blob|?Document|?FormData|string=}\n * opt_data The request content.\n * @param {?Object=} opt_headers The request content headers.\n * @param {number=} opt_timeout The request timeout.\n * @private\n */\nfireauth.RpcHandler.prototype.sendXhr_ = function(\n url,\n opt_callback,\n opt_httpMethod,\n opt_data,\n opt_headers,\n opt_timeout) {\n var sendXhr;\n if (fireauth.util.supportsCors() || fireauth.util.isWorker()) {\n // If supports CORS use goog.net.XhrIo.\n sendXhr = goog.bind(this.sendXhrUsingXhrIo_, this);\n } else {\n // Load gapi.client.request and gapi.auth dependency dynamically.\n if (!fireauth.RpcHandler.loadGApi_) {\n fireauth.RpcHandler.loadGApi_ =\n new goog.Promise(function(resolve, reject) {\n // On load, resolve.\n fireauth.RpcHandler.loadGApiJs_(resolve, reject);\n });\n }\n // If does not support CORS, use gapi.client.request.\n sendXhr = goog.bind(this.sendXhrUsingGApiClient_, this);\n }\n sendXhr(\n url, opt_callback, opt_httpMethod, opt_data, opt_headers, opt_timeout);\n};\n\n\n/**\n * Sends XhrIo request using goog.net.XhrIo.\n * @param {string} url The URL to make a request to.\n * @param {function(?Object)=} opt_callback The callback to run on completion.\n * @param {fireauth.RpcHandler.HttpMethod=} opt_httpMethod The HTTP send method.\n * @param {?ArrayBuffer|?ArrayBufferView|?Blob|?Document|?FormData|string=}\n * opt_data The request content.\n * @param {?Object=} opt_headers The request content headers.\n * @param {number=} opt_timeout The request timeout.\n * @private\n */\nfireauth.RpcHandler.prototype.sendXhrUsingXhrIo_ = function(\n url,\n opt_callback,\n opt_httpMethod,\n opt_data,\n opt_headers,\n opt_timeout) {\n if (fireauth.util.isWorker() && !fireauth.util.isFetchSupported()) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED,\n 'fetch, Headers and Request native APIs or equivalent Polyfills ' +\n 'must be available to support HTTP requests from a Worker ' +\n 'environment.');\n }\n var xhrIo = new goog.net.XhrIo(this.rpcHandlerXhrFactory_);\n\n // xhrIo.setTimeoutInterval not working in IE10 and IE11, handle manually.\n var requestTimeout;\n if (opt_timeout) {\n xhrIo.setTimeoutInterval(opt_timeout);\n requestTimeout = setTimeout(function() {\n xhrIo.dispatchEvent(goog.net.EventType.TIMEOUT);\n }, opt_timeout);\n }\n // Run callback function on completion.\n xhrIo.listen(\n goog.net.EventType.COMPLETE,\n /** @this {goog.net.XhrIo} */\n function() {\n // Clear timeout timer.\n if (requestTimeout) {\n clearTimeout(requestTimeout);\n }\n // Response assumed to be in json format. If not, catch, log error and\n // pass null to callback.\n var response = null;\n try {\n // Do not use this.responseJson() as it uses goog.json.parse\n // underneath. Internal goog.json.parse parsing uses eval and since\n // recommended Content Security Policy does not allow unsafe-eval,\n // this is failing and throwing an error in chrome extensions and\n // warnings else where. Use native parsing instead via JSON.parse.\n response = JSON.parse(this.getResponseText()) || null;\n } catch (e) {\n response = null;\n }\n if (opt_callback) {\n opt_callback(/** @type {?Object} */ (response));\n }\n });\n // Dispose xhrIo on ready.\n xhrIo.listenOnce(\n goog.net.EventType.READY,\n /** @this {goog.net.XhrIo} */\n function() {\n // Clear timeout timer.\n if (requestTimeout) {\n clearTimeout(requestTimeout);\n }\n // Dispose xhrIo.\n this.dispose();\n });\n // Listen to timeout error.\n // This should work when request is aborted too.\n xhrIo.listenOnce(\n goog.net.EventType.TIMEOUT,\n /** @this {goog.net.XhrIo} */\n function() {\n // Clear timeout timer.\n if (requestTimeout) {\n clearTimeout(requestTimeout);\n }\n // Dispose xhrIo.\n this.dispose();\n // The request timed out.\n if (opt_callback) {\n opt_callback(null);\n }\n });\n xhrIo.send(url, opt_httpMethod, opt_data, opt_headers);\n};\n\n\n/**\n * @const {!goog.string.Const} The GApi client library URL.\n * @private\n */\nfireauth.RpcHandler.GAPI_SRC_ = goog.string.Const.from(\n 'https://apis.google.com/js/client.js?onload=%{onload}');\n\n\n/**\n * @const {string}\n * @private\n */\nfireauth.RpcHandler.GAPI_CALLBACK_NAME_ =\n '__fcb' + Math.floor(Math.random() * 1000000).toString();\n\n\n/**\n * Loads the GApi client library if it is not loaded.\n * @param {function()} callback The callback to invoke once it's loaded.\n * @param {function(?Object)} errback The error callback.\n * @private\n */\nfireauth.RpcHandler.loadGApiJs_ = function(callback, errback) {\n // If gapi.client.request not available, load it dynamically.\n if (!((window['gapi'] || {})['client'] || {})['request']) {\n goog.global[fireauth.RpcHandler.GAPI_CALLBACK_NAME_] = function() {\n // Callback will be called by GApi, test properly loaded here instead of\n // after jsloader resolves.\n if (!((window['gapi'] || {})['client'] || {})['request']) {\n errback(new Error(fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED));\n } else {\n callback();\n }\n };\n var url = goog.html.TrustedResourceUrl.format(\n fireauth.RpcHandler.GAPI_SRC_,\n {'onload': fireauth.RpcHandler.GAPI_CALLBACK_NAME_});\n // TODO: replace goog.net.jsloader with our own script includer.\n var result = goog.net.jsloader.safeLoad(url);\n result.addErrback(function() {\n // In case file fails to load.\n errback(new Error(fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED));\n });\n } else {\n callback();\n }\n};\n\n\n/**\n * Sends XhrIo request using gapi.client.\n * @param {string} url The URL to make a request to.\n * @param {function(?Object)=} opt_callback The callback to run on completion.\n * @param {fireauth.RpcHandler.HttpMethod=} opt_httpMethod The HTTP send method.\n * @param {?ArrayBuffer|?ArrayBufferView|?Blob|?Document|?FormData|string=}\n * opt_data The request content.\n * @param {?Object=} opt_headers The request content headers.\n * @param {number=} opt_timeout The request timeout.\n * @private\n */\nfireauth.RpcHandler.prototype.sendXhrUsingGApiClient_ = function(\n url,\n opt_callback,\n opt_httpMethod,\n opt_data,\n opt_headers,\n opt_timeout) {\n var self = this;\n // Wait for GApi dependency to load.\n fireauth.RpcHandler.loadGApi_.then(function() {\n window['gapi']['client']['setApiKey'](self.getApiKey());\n // GApi maintains the Auth result and automatically append the Auth token to\n // all outgoing requests. Firebase Auth requests will be rejected if there\n // are others scopes (e.g. google plus) for the Auth token. Need to empty\n // the token before call gitkit api. Restored in callback.\n var oauth2Token = window['gapi']['auth']['getToken']();\n window['gapi']['auth']['setToken'](null);\n window['gapi']['client']['request']({\n 'path': url,\n 'method': opt_httpMethod,\n 'body': opt_data,\n 'headers': opt_headers,\n // This needs to be set to none, otherwise the access token will be passed\n // in the header field causing apiary to complain.\n 'authType': 'none',\n 'callback': function(response) {\n window['gapi']['auth']['setToken'](oauth2Token);\n if (opt_callback) {\n opt_callback(response);\n }\n }\n });\n }).thenCatch(function(error) {\n // Catches failure to support CORS and propagates it.\n if (opt_callback) {\n // Simulate backend server error to be caught by upper layer.\n opt_callback({\n 'error': {\n 'message': (error && error['message']) ||\n fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED\n }\n });\n }\n });\n};\n\n\n/**\n * Validates the request for the STS access token.\n *\n * @param {?Object} data The STS token request body.\n * @return {boolean} Whether the request is valid.\n * @private\n */\nfireauth.RpcHandler.prototype.validateStsTokenRequest_ = function(data) {\n if (data['grant_type'] == 'refresh_token' && data['refresh_token']) {\n // Exchange refresh token.\n return true;\n } else if (data['grant_type'] == 'authorization_code' && data['code']) {\n // Exchange ID token.\n return true;\n } else {\n // Invalid.\n return false;\n }\n};\n\n\n/**\n * Handles the request for the STS access token.\n *\n * @param {!Object} data The STS token request body.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.requestStsToken = function(data) {\n var self = this;\n return new goog.Promise(function(resolve, reject) {\n if (self.validateStsTokenRequest_(data)) {\n self.sendXhr_(\n self.secureTokenEndpoint_ + '?key=' +\n encodeURIComponent(self.getApiKey()),\n function(response) {\n if (!response) {\n // An unparseable response from the XHR most likely indicates some\n // problem with the network.\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.NETWORK_REQUEST_FAILED));\n } else if (fireauth.RpcHandler.hasError_(response)) {\n reject(fireauth.RpcHandler.getDeveloperError_(response));\n } else if (\n !response[fireauth.RpcHandler.StsServerField.ACCESS_TOKEN] ||\n !response[fireauth.RpcHandler.StsServerField.REFRESH_TOKEN]) {\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR));\n } else {\n resolve(response);\n }\n },\n fireauth.RpcHandler.HttpMethod.POST,\n goog.Uri.QueryData.createFromMap(data).toString(),\n self.secureTokenHeaders_,\n self.secureTokenTimeout_.get());\n } else {\n reject(new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR));\n }\n });\n};\n\n\n/**\n * @param {!Object} data The object to serialize.\n * @return {string} The serialized object with null, undefined and empty string\n * values removed.\n * @private\n */\nfireauth.RpcHandler.serialize_ = function(data) {\n // goog.json.serialize converts undefined values to null.\n // This helper removes all empty strings, nulls and undefined from serialized\n // object.\n // Serialize trimmed data.\n return goog.json.serialize(fireauth.util.copyWithoutNullsOrUndefined(data));\n};\n\n\n/**\n * Creates and executes a request for the given API method using the legacy\n * Firebase Auth endpoint.\n * @param {string} method The API method.\n * @param {!fireauth.RpcHandler.HttpMethod} httpMethod The http request method.\n * @param {!Object} data The data for the API request. In the case of a GET\n * request, the contents of this object will be form encoded and appended\n * to the query string of the URL. No post body is sent in that case. If an\n * object value is specified, it will be converted to a string:\n * encodeURIComponent(String(value)).\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map\n * of server error codes to client errors to override default error\n * handling.\n * @param {boolean=} opt_cachebuster Whether to append a unique string to\n * request to force backend to return an uncached response to request.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.requestFirebaseEndpoint = function(\n method, httpMethod, data, opt_customErrorMap, opt_cachebuster) {\n return this.requestAuthEndpoint_(\n this.firebaseEndpoint_, method, httpMethod, data, opt_customErrorMap,\n opt_cachebuster);\n};\n\n\n/**\n * Creates and executes a request for the given API method using the identity\n * platform endpoint.\n * @param {string} method The API method.\n * @param {!fireauth.RpcHandler.HttpMethod} httpMethod The http request method.\n * @param {!Object} data The data for the API request. In the case of a GET\n * request, the contents of this object will be form encoded and appended\n * to the query string of the URL. No post body is sent in that case. If an\n * object value is specified, it will be converted to a string:\n * encodeURIComponent(String(value)).\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map\n * of server error codes to client errors to override default error\n * handling.\n * @param {boolean=} opt_cachebuster Whether to append a unique string to\n * request to force backend to return an uncached response to request.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.requestIdentityPlatformEndpoint = function(\n method, httpMethod, data, opt_customErrorMap, opt_cachebuster) {\n return this.requestAuthEndpoint_(\n this.identityPlatformEndpoint_, method, httpMethod, data,\n opt_customErrorMap, opt_cachebuster);\n};\n\n\n/**\n * Creates and executes a request for the given API method and Auth endpoint.\n * @param {string} endpoint The Auth endpoint to use.\n * @param {string} method The API method.\n * @param {!fireauth.RpcHandler.HttpMethod} httpMethod The http request method.\n * @param {!Object} data The data for the API request. In the case of a GET\n * request, the contents of this object will be form encoded and appended\n * to the query string of the URL. No post body is sent in that case. If an\n * object value is specified, it will be converted to a string:\n * encodeURIComponent(String(value)).\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map\n * of server error codes to client errors to override default error\n * handling.\n * @param {boolean=} opt_cachebuster Whether to append a unique string to\n * request to force backend to return an uncached response to request.\n * @return {!goog.Promise<!Object>}\n * @private\n */\nfireauth.RpcHandler.prototype.requestAuthEndpoint_ = function(\n endpoint, method, httpMethod, data, opt_customErrorMap, opt_cachebuster) {\n var self = this;\n // Construct endpoint URL.\n var uri = goog.Uri.parse(endpoint + method);\n uri.setParameterValue('key', this.getApiKey());\n // Check whether to append cachebuster to request.\n if (opt_cachebuster) {\n uri.setParameterValue('cb', goog.now().toString());\n }\n // Firebase allows GET endpoints.\n var isGet = httpMethod == fireauth.RpcHandler.HttpMethod.GET;\n if (isGet) {\n // For GET HTTP method, append data to query string.\n for (var key in data) {\n if (data.hasOwnProperty(key)) {\n uri.setParameterValue(key, data[key]);\n }\n }\n }\n return new goog.Promise(function(resolve, reject) {\n self.sendXhr_(\n uri.toString(),\n function(response) {\n if (!response) {\n // An unparseable response from the XHR most likely indicates some\n // problem with the network.\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.NETWORK_REQUEST_FAILED));\n } else if (fireauth.RpcHandler.hasError_(response)) {\n reject(fireauth.RpcHandler.getDeveloperError_(response,\n opt_customErrorMap || {}));\n } else {\n resolve(response);\n }\n },\n httpMethod,\n // No post body data in GET requests.\n isGet ? undefined : fireauth.RpcHandler.serialize_(data),\n self.firebaseHeaders_,\n self.firebaseTimeout_.get());\n });\n};\n\n\n/**\n * Verifies that the request has a valid email set.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateRequestHasEmail_ = function(request) {\n if (!fireauth.util.isValidEmailAddress(request['email'])) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_EMAIL);\n }\n};\n\n\n/**\n * Verifies that the response has a valid email set.\n * @param {!Object} response\n * @private\n */\nfireauth.RpcHandler.validateResponseHasEmail_ = function(response) {\n if (!fireauth.util.isValidEmailAddress(response['email'])) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Verifies that the an email is valid, if it is there.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateEmailIfPresent_ = function(request) {\n if ('email' in request) {\n fireauth.RpcHandler.validateRequestHasEmail_(request);\n }\n};\n\n\n/**\n * @param {string} providerId The provider ID.\n * @param {?Array<string>=} opt_additionalScopes The list of scope strings.\n * @return {?string} The IDP and its comma separated scope strings serialized.\n * @private\n */\nfireauth.RpcHandler.getAdditionalScopes_ =\n function(providerId, opt_additionalScopes) {\n var scopes = {};\n if (opt_additionalScopes && opt_additionalScopes.length) {\n scopes[providerId] = opt_additionalScopes.join(',');\n // Return stringified scopes.\n return goog.json.serialize(scopes);\n }\n return null;\n};\n\n\n/**\n * Validates a response from getAuthUri.\n * @param {?Object} response The getAuthUri response data.\n * @private\n */\nfireauth.RpcHandler.validateGetAuthResponse_ = function(response) {\n if (!response[fireauth.RpcHandler.AuthServerField.AUTH_URI]) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'Unable to determine the authorization endpoint for the specified '+\n 'provider. This may be an issue in the provider configuration.');\n } else if ( !response[fireauth.RpcHandler.AuthServerField.SESSION_ID]) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Requests createAuthUri endpoint to retrieve the authUri and session ID for\n * the start of an OAuth handshake.\n * @param {string} providerId The provider ID.\n * @param {string} continueUri The IdP callback URL.\n * @param {?Object=} opt_customParameters The optional OAuth custom parameters\n * plain object.\n * @param {?Array<string>=} opt_additionalScopes The list of scope strings.\n * @param {?string=} opt_email The optional email.\n * @param {?string=} opt_sessionId The optional session ID.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.getAuthUri = function(\n providerId,\n continueUri,\n opt_customParameters,\n opt_additionalScopes,\n opt_email,\n opt_sessionId) {\n // SAML provider request is constructed differently than OAuth requests.\n var isSaml = fireauth.idp.isSaml(providerId);\n var request = {\n 'identifier': opt_email,\n 'providerId': providerId,\n 'continueUri': continueUri,\n 'customParameter': opt_customParameters || {},\n 'oauthScope': fireauth.RpcHandler.getAdditionalScopes_(\n providerId, opt_additionalScopes),\n 'sessionId': opt_sessionId\n };\n // Custom parameters and OAuth scopes should be ignored.\n if (isSaml) {\n delete request['customParameter'];\n delete request['oauthScope'];\n }\n // When sessionId is provided, mobile flow (Cordova) is being used, force\n // code flow and not implicit flow. All other providers use code flow by\n // default.\n if (opt_sessionId && providerId == fireauth.idp.ProviderId.GOOGLE) {\n request['authFlowType'] = 'CODE_FLOW';\n }\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_AUTH_URI,\n request);\n};\n\n\n/**\n * Gets the list of IDPs that can be used to log in for the given identifier.\n * @param {string} identifier The identifier, such as an email address.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.RpcHandler.prototype.fetchProvidersForIdentifier =\n function(identifier) {\n // createAuthUri returns an error if continue URI is not http or https.\n // For environments like Cordova, Chrome extensions, native frameworks, file\n // systems, etc, use http://localhost as continue URL.\n var continueUri = fireauth.util.isHttpOrHttps() ?\n fireauth.util.getCurrentUrl() : 'http://localhost';\n var request = {\n 'identifier': identifier,\n 'continueUri': continueUri\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.CREATE_AUTH_URI, request)\n .then(function(response) {\n return response[fireauth.RpcHandler.AuthServerField.ALL_PROVIDERS] ||\n [];\n });\n};\n\n\n/**\n * Returns the list of sign in methods for the given identifier.\n * @param {string} identifier The identifier, such as an email address.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.RpcHandler.prototype.fetchSignInMethodsForIdentifier = function(\n identifier) {\n // createAuthUri returns an error if continue URI is not http or https.\n // For environments like Cordova, Chrome extensions, native frameworks, file\n // systems, etc, use http://localhost as continue URL.\n var continueUri = fireauth.util.isHttpOrHttps() ?\n fireauth.util.getCurrentUrl() :\n 'http://localhost';\n var request = {\n 'identifier': identifier,\n 'continueUri': continueUri\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.CREATE_AUTH_URI, request)\n .then(function(response) {\n return response[fireauth.RpcHandler.AuthServerField.SIGNIN_METHODS] ||\n [];\n });\n};\n\n\n/**\n * Gets the list of authorized domains for the specified project.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.RpcHandler.prototype.getAuthorizedDomains = function() {\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, {})\n .then(function(response) {\n return response[\n fireauth.RpcHandler.AuthServerField.AUTHORIZED_DOMAINS] || [];\n });\n};\n\n\n/**\n * Gets the reCAPTCHA parameters needed to render the project's provisioned\n * reCAPTCHA.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.getRecaptchaParam = function() {\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_RECAPTCHA_PARAM, {});\n};\n\n\n/**\n * Gets the list of authorized domains for the specified project.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.getDynamicLinkDomain = function() {\n var request = {\n 'returnDynamicLink': true\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.RETURN_DYNAMIC_LINK, request);\n};\n\n\n/**\n * Checks if the provided iOS bundle ID belongs to the project as specified by\n * the API key.\n * @param {string} iosBundleId The iOS bundle ID to check.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.isIosBundleIdValid = function(iosBundleId) {\n var request = {\n 'iosBundleId': iosBundleId\n };\n // This will either resolve if the identifier is valid or throw INVALID_APP_ID\n // if not.\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, request)\n .then(function(result) {\n // Do not return anything.\n });\n};\n\n\n/**\n * Checks if the provided Android package name belongs to the project as\n * specified by the API key.\n * @param {string} androidPackageName The iOS bundle ID to check.\n * @param {?string=} opt_sha1Cert The optional SHA-1 Android cert to check.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.isAndroidPackageNameValid =\n function(androidPackageName, opt_sha1Cert) {\n var request = {\n 'androidPackageName': androidPackageName\n };\n // This is relevant for the native Android SDK flow.\n // This will redirect to an FDL domain owned by GMScore instead of\n // the developer's FDL domain as is done for Cordova apps.\n if (!!opt_sha1Cert) {\n request['sha1Cert'] = opt_sha1Cert;\n }\n // When no sha1Cert is passed, this will either resolve if the identifier is\n // valid or throw INVALID_APP_ID if not.\n // When sha1Cert is also passed, this will either resolve or fail with an\n // INVALID_CERT_HASH error.\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, request)\n .then(function(result) {\n // Do not return anything.\n });\n};\n\n\n/**\n * Checks if the provided OAuth client ID belongs to the project as specified by\n * the API key.\n * @param {string} clientId The OAuth client ID to check.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.isOAuthClientIdValid = function(clientId) {\n var request = {\n 'clientId': clientId\n };\n // This will either resolve if the client ID is valid or throw\n // INVALID_OAUTH_CLIENT_ID if not.\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.GET_PROJECT_CONFIG, request)\n .then(function(result) {\n // Do not return anything.\n });\n};\n\n\n/**\n * Requests getAccountInfo endpoint using an ID token.\n * @param {string} idToken The ID token.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.getAccountInfoByIdToken = function(idToken) {\n var request = {'idToken': idToken};\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_ACCOUNT_INFO,\n request);\n};\n\n\n/**\n * Validates a request to sign in with email and password.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateVerifyCustomTokenRequest_ = function(request) {\n if (!request['token']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_CUSTOM_TOKEN);\n }\n};\n\n\n/**\n * Verifies a custom token and returns a Promise that resolves with the ID\n * token.\n * @param {string} token The custom token.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyCustomToken = function(token) {\n var request = {'token': token};\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.VERIFY_CUSTOM_TOKEN,\n request);\n};\n\n\n/**\n * Validates a request to sign in with email and password.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateVerifyPasswordRequest_ = function(request) {\n fireauth.RpcHandler.validateRequestHasEmail_(request);\n if (!request['password']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_PASSWORD);\n }\n};\n\n\n/**\n * Verifies a password and returns a Promise that resolves with the ID\n * token.\n * @param {string} email The email address.\n * @param {string} password The entered password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPassword = function(email, password) {\n var request = {\n 'email': email,\n 'password': password\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.VERIFY_PASSWORD,\n request);\n};\n\n\n/**\n * Verifies an email link OTP for sign-in and returns a Promise that resolves\n * with the ID token.\n * @param {string} email The email address.\n * @param {string} oobCode The email action OTP.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.emailLinkSignIn = function(email, oobCode) {\n var request = {\n 'email': email,\n 'oobCode': oobCode\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN, request);\n};\n\n\n/**\n * Verifies an email link OTP for linking and returns a Promise that resolves\n * with the ID token.\n * @param {string} idToken The ID token.\n * @param {string} email The email address.\n * @param {string} oobCode The email action OTP.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.emailLinkSignInForLinking =\n function(idToken, email, oobCode) {\n var request = {\n 'idToken': idToken,\n 'email': email,\n 'oobCode': oobCode\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN_FOR_LINKING,\n request);\n};\n\n\n/**\n * Validates a response that should contain an ID token.\n * If no ID token is available, it checks if a multi-factor pending credential\n * is available instead. In that case, it throws the MFA_REQUIRED error code.\n * @param {?Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateIdTokenResponse_ = function(response) {\n if (!response[fireauth.RpcHandler.AuthServerField.ID_TOKEN]) {\n // User could be a second factor user.\n // When second factor is required, a pending credential is returned.\n if (response[fireauth.RpcHandler.AuthServerField.MFA_PENDING_CREDENTIAL]) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.MFA_REQUIRED,\n null,\n goog.object.clone(response));\n }\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Validates a getRecaptchaParam response.\n * @param {?Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateGetRecaptchaParamResponse_ = function(response) {\n // Both are required. This could change though.\n if (!response[fireauth.RpcHandler.AuthServerField.RECAPTCHA_SITE_KEY]) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Validates a request that sends the verification ID and code for a sign in/up\n * phone Auth flow.\n * @param {!Object} request The server request object.\n * @private\n */\nfireauth.RpcHandler.validateVerifyPhoneNumberRequest_ = function(request) {\n // There are 2 cases here:\n // case 1: sessionInfo and code\n // case 2: phoneNumber and temporaryProof\n if (request['phoneNumber'] || request['temporaryProof']) {\n // Case 2. Both phoneNumber and temporaryProof should be set.\n if (!request['phoneNumber'] || !request['temporaryProof']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n } else {\n // Otherwise it's case 1, so we expect sessionInfo and code.\n if (!request['sessionInfo']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.MISSING_SESSION_INFO);\n }\n if (!request['code']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CODE);\n }\n }\n};\n\n\n/**\n * Validates a request that sends the verification ID and code for a link/update\n * phone Auth flow.\n * @param {!Object} request The server request object.\n * @private\n */\nfireauth.RpcHandler.validateVerifyPhoneNumberLinkRequest_ = function(request) {\n // idToken should be required here.\n if (!request['idToken']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n // The other request parameters match the sign in flow.\n fireauth.RpcHandler.validateVerifyPhoneNumberRequest_(request);\n};\n\n\n/**\n * Validates a request to create an email and password account.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateCreateAccountRequest_ = function(request) {\n fireauth.RpcHandler.validateRequestHasEmail_(request);\n if (!request['password']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.WEAK_PASSWORD);\n }\n};\n\n\n/**\n * Validates a request to createAuthUri.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateGetAuthUriRequest_ = function(request) {\n if (!request['continueUri']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CONTINUE_URI);\n }\n // Either a SAML or non SAML providerId must be provided.\n if (!request['providerId']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'A provider ID must be provided in the request.');\n }\n};\n\n\n/**\n * Creates an email/password account. Returns a Promise that resolves with the\n * ID token.\n * @param {string} email The email address of the account.\n * @param {string} password The password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.createAccount = function(email, password) {\n var request = {\n 'email': email,\n 'password': password\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.CREATE_ACCOUNT,\n request);\n};\n\n\n/**\n * Signs in a user as anonymous. Returns a Promise that resolves with the\n * ID token.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.signInAnonymously = function() {\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.SIGN_IN_ANONYMOUSLY, {});\n};\n\n\n/**\n * Deletes the user's account corresponding to the idToken given.\n * @param {string} idToken The idToken of the user.\n * @return {!goog.Promise<undefined>}\n */\nfireauth.RpcHandler.prototype.deleteAccount = function(idToken) {\n var request = {\n 'idToken': idToken\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.DELETE_ACCOUNT,\n request);\n};\n\n\n/**\n * Requests setAccountInfo endpoint for updateEmail operation.\n * @param {string} idToken The ID token.\n * @param {string} newEmail The new email.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updateEmail = function(idToken, newEmail) {\n var request = {\n 'idToken': idToken,\n 'email': newEmail\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO,\n request);\n};\n\n\n/**\n * Validates a setAccountInfo request that updates the password.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateSetAccountInfoSensitive_ = function(request) {\n fireauth.RpcHandler.validateEmailIfPresent_(request);\n if (!request['password']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.WEAK_PASSWORD);\n }\n};\n\n\n/**\n * Requests setAccountInfo endpoint for updatePassword operation.\n * @param {string} idToken The ID token.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updatePassword = function(idToken, newPassword) {\n var request = {\n 'idToken': idToken,\n 'password': newPassword\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO_SENSITIVE, request);\n};\n\n\n/**\n * Requests setAccountInfo endpoint to set the email and password. This can be\n * used to link an existing account to a new email and password account.\n * @param {string} idToken The ID token.\n * @param {string} newEmail The new email.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updateEmailAndPassword = function(idToken,\n newEmail, newPassword) {\n var request = {\n 'idToken': idToken,\n 'email': newEmail,\n 'password': newPassword\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO_SENSITIVE, request);\n};\n\n\n/**\n * Maps the name of a field in the account info object to the backend enum\n * value, for deletion of profile fields.\n * @private {!Object<string, string>}\n */\nfireauth.RpcHandler.PROFILE_FIELD_TO_ENUM_NAME_ = {\n 'displayName': 'DISPLAY_NAME',\n 'photoUrl': 'PHOTO_URL'\n};\n\n\n/**\n * Updates the profile of the user. When resolved, promise returns a response\n * similar to that of getAccountInfo.\n * @param {string} idToken The ID token of the user whose profile is changing.\n * @param {!Object} profileData The new profile data.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.updateProfile = function(idToken, profileData) {\n var data = {\n 'idToken': idToken\n };\n var fieldsToDelete = [];\n\n // Copy over the relevant fields from profileData, or explicitly flag a field\n // for deletion if null is passed as the value. Note that this currently only\n // checks profileData to the first level.\n goog.object.forEach(fireauth.RpcHandler.PROFILE_FIELD_TO_ENUM_NAME_,\n function(enumName, fieldName) {\n var fieldValue = profileData[fieldName];\n if (fieldValue === null) {\n // If null is explicitly provided, delete the field.\n fieldsToDelete.push(enumName);\n } else if (fieldName in profileData) {\n // If the field is explicitly set, send it to the backend.\n data[fieldName] = fieldValue;\n }\n });\n if (fieldsToDelete.length) {\n data['deleteAttribute'] = fieldsToDelete;\n }\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.SET_ACCOUNT_INFO, data);\n};\n\n\n/**\n * Validates a request for an email action code for password reset.\n * @param {!Object} request The getOobCode request data for password reset.\n * @private\n */\nfireauth.RpcHandler.validateOobCodeRequest_ = function(request) {\n if (request['requestType'] !=\n fireauth.RpcHandler.GetOobCodeRequestType.PASSWORD_RESET) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n fireauth.RpcHandler.validateRequestHasEmail_(request);\n};\n\n\n/**\n * Validates a request for an email action for passwordless email sign-in.\n * @param {!Object} request The getOobCode request data for email sign-in.\n * @private\n */\nfireauth.RpcHandler.validateEmailSignInCodeRequest_ = function(request) {\n if (request['requestType'] !=\n fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n fireauth.RpcHandler.validateRequestHasEmail_(request);\n};\n\n\n/**\n * Validates a request for an email action for email verification.\n * @param {!Object} request The getOobCode request data for email verification.\n * @private\n */\nfireauth.RpcHandler.validateEmailVerificationCodeRequest_ = function(request) {\n if (request['requestType'] !=\n fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_EMAIL) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Validates a request for an email action for email verification before update.\n * @param {!Object} request The getOobCode request data for email verification\n * before update.\n * @private\n */\nfireauth.RpcHandler.validateEmailVerificationCodeBeforeUpdateRequest_ =\n function(request) {\n if (request['requestType'] !=\n fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_AND_CHANGE_EMAIL) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Requests getOobCode endpoint for password reset, returns promise that\n * resolves with user's email.\n * @param {string} email The email account with the password to be reset.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendPasswordResetEmail =\n function(email, additionalRequestData) {\n var request = {\n 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.PASSWORD_RESET,\n 'email': email\n };\n // Extend the original request with the additional data.\n goog.object.extend(request, additionalRequestData);\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.GET_OOB_CODE, request);\n};\n\n\n/**\n * Requests getOobCode endpoint for passwordless email sign-in, returns promise\n * that resolves with user's email.\n * @param {string} email The email account to sign in with.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendSignInLinkToEmail = function(\n email, additionalRequestData) {\n var request = {\n 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN,\n 'email': email\n };\n // Extend the original request with the additional data.\n goog.object.extend(request, additionalRequestData);\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.GET_EMAIL_SIGNIN_CODE, request);\n};\n\n\n/**\n * Requests getOobCode endpoint for email verification, returns promise that\n * resolves with user's email.\n * @param {string} idToken The idToken of the user confirming his email.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendEmailVerification =\n function(idToken, additionalRequestData) {\n var request = {\n 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_EMAIL,\n 'idToken': idToken\n };\n // Extend the original request with the additional data.\n goog.object.extend(request, additionalRequestData);\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.GET_EMAIL_VERIFICATION_CODE, request);\n};\n\n\n/**\n * Requests getOobCode endpoint for email verification before updating the\n * email.\n * @param {string} idToken The idToken of the user updating his email.\n * @param {string} newEmail The new email.\n * @param {!Object} additionalRequestData Additional data to add to the request.\n * @return {!goog.Promise<void>}\n */\nfireauth.RpcHandler.prototype.verifyBeforeUpdateEmail =\n function(idToken, newEmail, additionalRequestData) {\n var request = {\n 'requestType':\n fireauth.RpcHandler.GetOobCodeRequestType.VERIFY_AND_CHANGE_EMAIL,\n 'idToken': idToken,\n 'newEmail': newEmail\n };\n // Extend the original request with the additional data.\n goog.object.extend(request, additionalRequestData);\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.GET_EMAIL_VERIFICATION_CODE_BEFORE_UPDATE,\n request);\n};\n\n\n/**\n * Requests sendVerificationCode endpoint for verifying the user's ownership of\n * a phone number. It resolves with a sessionInfo (verificationId).\n * @param {!Object} request The verification request which contains a phone\n * number and an assertion.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.sendVerificationCode = function(request) {\n // In the future, we could support other types of assertions so for now,\n // we are keeping the request an object.\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.SEND_VERIFICATION_CODE, request);\n};\n\n\n/**\n * Requests verifyPhoneNumber endpoint for sign in/sign up phone number\n * authentication flow and resolves with the STS token response.\n * @param {!Object} request The phone number ID and code to exchange for a\n * Firebase Auth session.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPhoneNumber = function(request) {\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER, request);\n};\n\n\n/**\n * Requests verifyPhoneNumber endpoint for link/update phone number\n * authentication flow and resolves with the STS token response.\n * @param {!Object} request The phone number ID and code to exchange for a\n * Firebase Auth session.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPhoneNumberForLinking = function(request) {\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER_FOR_LINKING, request);\n};\n\n\n/**\n * Validates a response to a phone number linking request.\n * @param {?Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyPhoneNumberForLinkingResponse_ =\n function(response) {\n if (response[fireauth.RpcHandler.AuthServerField.TEMPORARY_PROOF]) {\n response['code'] = fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE;\n throw fireauth.AuthErrorWithCredential.fromPlainObject(response);\n }\n\n // If there's no temporary proof, then we expect the request to have\n // succeeded and returned an ID token.\n fireauth.RpcHandler.validateIdTokenResponse_(response);\n};\n\n\n/**\n * Requests verifyPhoneNumber endpoint for reauthenticating with a phone number\n * and resolves with the STS token response.\n * @param {!Object} request The phone number ID, code, and current ID token to\n * exchange for a refreshed Firebase Auth session.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyPhoneNumberForExisting = function(request) {\n request['operation'] = 'REAUTH';\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.VERIFY_PHONE_NUMBER_FOR_EXISTING,\n request);\n};\n\n\n/**\n * Validates a request for starting phone MFA enrollment.\n * @param {!Object} request The startPhoneMfaEnrollment request data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaEnrollmentRequest_ =\n function(request) {\n if (!request['phoneEnrollmentInfo']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n if (!request['phoneEnrollmentInfo']['phoneNumber']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_PHONE_NUMBER);\n }\n if (!request['phoneEnrollmentInfo']['recaptchaToken']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.MISSING_APP_CREDENTIAL);\n }\n};\n\n\n/**\n * Validates a response to a start phone MFA enrollment request.\n * @param {!Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaEnrollmentResponse_ =\n function(response) {\n if (!response[fireauth.RpcHandler.AuthServerField.PHONE_SESSION_INFO] ||\n !response[fireauth.RpcHandler.AuthServerField.PHONE_SESSION_INFO]\n [fireauth.RpcHandler.AuthServerField.SESSION_INFO]) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Requests startMfaEnrollment endpoint for verifying the user's ownership of\n * a phone number before enrolling to MFA. It resolves with a sessionInfo\n * (verificationId) string.\n * @param {!Object} request The enroll MFA request for phone.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.startPhoneMfaEnrollment = function(request) {\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.START_PHONE_MFA_ENROLLMENT, request)\n .then(function(response) {\n // Extract the sessionInfo(verificationId) from response.\n return response[fireauth.RpcHandler.AuthServerField.PHONE_SESSION_INFO]\n [fireauth.RpcHandler.AuthServerField.SESSION_INFO];\n });\n};\n\n\n/**\n * Validates a request for finalizing phone MFA enrollment or sign-in.\n * @param {!Object} request The finalizePhoneMfaEnrollment or\n * finalizePhoneMfaSignIn request data.\n * @private\n */\nfireauth.RpcHandler.validateFinalizePhoneMfaRequest_ = function(request) {\n if (!request['phoneVerificationInfo']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n if (!request['phoneVerificationInfo']['sessionInfo']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_SESSION_INFO);\n }\n if (!request['phoneVerificationInfo']['code']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_CODE);\n }\n};\n\n\n/**\n * Requests finalizeMfaEnrollment endpoint to finish the enrollment flow for\n * phone MFA. It resolves with the MFA token response.\n * @param {!Object} request The enroll MFA request for phone.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.finalizePhoneMfaEnrollment = function(request) {\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.FINALIZE_PHONE_MFA_ENROLLMENT, request);\n};\n\n\n/**\n * Validates a request for starting phone MFA sign-in.\n * @param {!Object} request The startPhoneMfaSignIn request data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaSignInRequest_ = function(request) {\n if (!request['phoneSignInInfo'] ||\n !request['phoneSignInInfo']['recaptchaToken']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.MISSING_APP_CREDENTIAL);\n }\n};\n\n\n/**\n * Validates a response to a start phone MFA sign-in request.\n * @param {!Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateStartPhoneMfaSignInResponse_ = function(response) {\n if (!response[fireauth.RpcHandler.AuthServerField.PHONE_RESPONSE_INFO] ||\n !response[fireauth.RpcHandler.AuthServerField.PHONE_RESPONSE_INFO]\n [fireauth.RpcHandler.AuthServerField.SESSION_INFO]) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Requests startMfaSignIn endpoint for verifying the user's ownership of\n * a phone number before signing in to MFA. It resolves with a sessionInfo\n * (verificationId) string.\n * @param {!Object} request The sign in MFA request for phone.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.startPhoneMfaSignIn = function(request) {\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.START_PHONE_MFA_SIGN_IN, request)\n .then(function(response) {\n // Extract the sessionInfo(verificationId) from response.\n return response[fireauth.RpcHandler.AuthServerField.PHONE_RESPONSE_INFO]\n [fireauth.RpcHandler.AuthServerField.SESSION_INFO];\n });\n};\n\n\n/**\n * Requests finalizeMfaSignIn endpoint to finish the sign-in flow for\n * phone MFA. It resolves with the MFA token response.\n * @param {!Object} request The sign in MFA request for phone.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.finalizePhoneMfaSignIn = function(request) {\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.FINALIZE_PHONE_MFA_SIGN_IN, request);\n};\n\n\n/**\n * Validates the response for unenrolling a second factor. If the user is still\n * considered signed in, the endpoint returns new tokens. However, if the\n * user session is revoked no tokens will be returned.\n * @param {!Object} response The server response data.\n * @private\n */\nfireauth.RpcHandler.validateWithdrawMfaResponse_ = function(response) {\n var hasIdToken = !!response[fireauth.RpcHandler.AuthServerField.ID_TOKEN];\n var hasRefreshToken =\n !!response[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN];\n\n if (hasIdToken ^ hasRefreshToken) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Requests the withdraw endpoint to unenroll a second factor. Returns new\n * tokens if the user is still considered signed in or no tokens if the user\n * session is revoked and the user is being signed out.\n * @param {string} idToken The ID token.\n * @param {string} mfaEnrollmentId The MFA enrollment ID.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.withdrawMfa = function(idToken, mfaEnrollmentId) {\n var request = {\n 'idToken': idToken,\n 'mfaEnrollmentId': mfaEnrollmentId\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.WITHDRAW_MFA, request);\n};\n\n\n/**\n * The custom error map for reauth with verifyPhoneNumber.\n * @private {!fireauth.RpcHandler.ServerErrorMap}\n */\nfireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_ = {};\n\n// For most RPCs, the backend error USER_NOT_FOUND means that the sent STS\n// token is invalid. However, for this specific case, USER_NOT_FOUND actually\n// means that the sent credential is invalid.\nfireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_[\n fireauth.RpcHandler.ServerError.USER_NOT_FOUND] =\n fireauth.authenum.Error.USER_DELETED;\n\n\n/**\n * Validates a request to deleteLinkedAccounts.\n * @param {?Object} request\n * @private\n */\nfireauth.RpcHandler.validateDeleteLinkedAccountsRequest_ = function(request) {\n if (!goog.isArray(request['deleteProvider'])) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Updates the providers for the account associated with the idToken.\n * @param {string} idToken The ID token.\n * @param {!Array<string>} providersToDelete The array of providers to delete.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.deleteLinkedAccounts =\n function(idToken, providersToDelete) {\n var request = {\n 'idToken': idToken,\n 'deleteProvider': providersToDelete\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.DELETE_LINKED_ACCOUNTS,\n request);\n};\n\n\n/**\n * Validates a verifyAssertion request.\n * @param {?Object} request The verifyAssertion request data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionRequest_ = function(request) {\n // Either (requestUri and sessionId), (requestUri and postBody) or\n // (requestUri and pendingToken) are required.\n if (!request[fireauth.RpcHandler.AuthServerField.REQUEST_URI] ||\n (!request[fireauth.RpcHandler.AuthServerField.SESSION_ID] &&\n !request[fireauth.RpcHandler.AuthServerField.POST_BODY] &&\n !request[fireauth.RpcHandler.AuthServerField.PENDING_TOKEN])) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Processes the verifyAssertion response and injects the same raw nonce\n * if available in request.\n * @param {!Object} request The verifyAssertion request data.\n * @param {!Object} response The original verifyAssertion response data.\n * @return {!Object} The modified verifyAssertion response.\n * @private\n */\nfireauth.RpcHandler.processVerifyAssertionResponse_ =\n function(request, response) {\n // This makes it possible for OIDC providers to:\n // 1. Initialize an OIDC Auth credential on successful response.\n // 2. Initialize an OIDC Auth credential within the recovery error.\n\n // When request has sessionId and response has OIDC ID token and no pending\n // token, a credential with raw nonce and OIDC ID token needs to be returned.\n if (response[fireauth.RpcHandler.AuthServerField.OAUTH_ID_TOKEN] &&\n response[fireauth.RpcHandler.AuthServerField.PROVIDER_ID] &&\n response[fireauth.RpcHandler.AuthServerField.PROVIDER_ID]\n .indexOf(fireauth.constants.OIDC_PREFIX) == 0 &&\n // Use pendingToken instead of idToken and rawNonce when available.\n !response[fireauth.RpcHandler.AuthServerField.PENDING_TOKEN]) {\n if (request[fireauth.RpcHandler.AuthServerField.SESSION_ID]) {\n // For full OAuth flow, the nonce is in the session ID.\n response[fireauth.RpcHandler.InjectedResponseField.NONCE] =\n request[fireauth.RpcHandler.AuthServerField.SESSION_ID];\n } else if (request[fireauth.RpcHandler.AuthServerField.POST_BODY]) {\n // For credential flow, the nonce is in the postBody nonce field.\n var queryData = new goog.Uri.QueryData(\n request[fireauth.RpcHandler.AuthServerField.POST_BODY]);\n if (queryData.containsKey(\n fireauth.RpcHandler.InjectedResponseField.NONCE)) {\n response[fireauth.RpcHandler.InjectedResponseField.NONCE] =\n queryData.get(fireauth.RpcHandler.InjectedResponseField.NONCE);\n }\n }\n }\n return response;\n};\n\n\n/**\n * Validates a response from verifyAssertionForExisting.\n * @param {?Object} response The verifyAssertionForExisting response data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionForExistingResponse_ =\n function(response) {\n // When returnIdpCredential is set to true and the account is new, no error\n // is thrown but an errorMessage is added to the response. No idToken is\n // passed.\n if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] &&\n response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] ==\n fireauth.RpcHandler.ServerError.USER_NOT_FOUND) {\n // This corresponds to user-not-found.\n throw new fireauth.AuthError(fireauth.authenum.Error.USER_DELETED);\n } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]) {\n // Construct developer facing error message from server code in errorMessage\n // field.\n throw fireauth.RpcHandler.getDeveloperErrorFromCode_(\n response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]);\n }\n // Need confirmation should not be returned when do not create new user flag\n // is set.\n // Validate if ID token or multi-factor pending credential is available.\n fireauth.RpcHandler.validateIdTokenResponse_(response);\n};\n\n\n/**\n * Validates a response from verifyAssertion.\n * @param {?Object} response The verifyAssertion response data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionResponse_ = function(response) {\n var error = null;\n if (response[fireauth.RpcHandler.AuthServerField.NEED_CONFIRMATION]) {\n // Account linking required, previously logged in to another account\n // with same email. User must authenticate they are owners of the\n // first account.\n // If enough info for Auth linking error, throw an instance of Auth linking\n // error. This will be used by developer after reauthenticating with email\n // provided by error to link using the credentials in Auth linking error.\n // If missing information, return regular Auth error.\n response['code'] = fireauth.authenum.Error.NEED_CONFIRMATION;\n error = fireauth.AuthErrorWithCredential.fromPlainObject(response);\n } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] ==\n fireauth.RpcHandler.ServerError.FEDERATED_USER_ID_ALREADY_LINKED) {\n // When FEDERATED_USER_ID_ALREADY_LINKED returned in error message, auth\n // credential and email will also be returned, throw relevant error in that\n // case.\n // In this case the developer needs to signInWithCredential to the returned\n // credentials.\n response['code'] = fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE;\n error = fireauth.AuthErrorWithCredential.fromPlainObject(response);\n } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE] ==\n fireauth.RpcHandler.ServerError.EMAIL_EXISTS) {\n // When EMAIL_EXISTS returned in error message, Auth credential and email\n // will also be returned, throw relevant error in that case.\n // In this case, the developers needs to sign in the user to the original\n // owner of the account and then link to the returned credential here.\n response['code'] = fireauth.authenum.Error.EMAIL_EXISTS;\n error = fireauth.AuthErrorWithCredential.fromPlainObject(response);\n } else if (response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]) {\n // Construct developer facing error message from server code in errorMessage\n // field.\n error = fireauth.RpcHandler.getDeveloperErrorFromCode_(\n response[fireauth.RpcHandler.AuthServerField.ERROR_MESSAGE]);\n }\n // If error found, throw it.\n if (error) {\n throw error;\n }\n // Validate if ID token or multi-factor pending credential is available.\n fireauth.RpcHandler.validateIdTokenResponse_(response);\n};\n\n\n/**\n * Validates a verifyAssertion with linking request.\n * @param {?Object} request The verifyAssertion request data.\n * @private\n */\nfireauth.RpcHandler.validateVerifyAssertionLinkRequest_ = function(request) {\n // idToken with either (requestUri and sessionId) or (requestUri and postBody)\n // are required.\n fireauth.RpcHandler.validateVerifyAssertionRequest_(request);\n if (!request['idToken']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * @typedef {{\n * autoCreate: (boolean|undefined),\n * requestUri: string,\n * postBody: (?string|undefined),\n * pendingIdToken: (?string|undefined),\n * sessionId: (?string|undefined),\n * idToken: (?string|undefined),\n * returnIdpCredential: (boolean|undefined),\n * tenantId: (?string|undefined)\n * }}\n */\nfireauth.RpcHandler.VerifyAssertionData;\n\n\n/**\n * Requests verifyAssertion endpoint. When resolved, promise returns the whole\n * response.\n * @param {!fireauth.RpcHandler.VerifyAssertionData} request\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyAssertion = function(request) {\n // Force Auth credential to be returned on the following errors:\n // FEDERATED_USER_ID_ALREADY_LINKED\n // EMAIL_EXISTS\n request['returnIdpCredential'] = true;\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION,\n request);\n};\n\n\n/**\n * Requests verifyAssertion endpoint for federated account linking. When\n * resolved, promise returns the whole response.\n * @param {!fireauth.RpcHandler.VerifyAssertionData} request\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyAssertionForLinking = function(request) {\n // Force Auth credential to be returned on the following errors:\n // FEDERATED_USER_ID_ALREADY_LINKED\n // EMAIL_EXISTS\n request['returnIdpCredential'] = true;\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION_FOR_LINKING,\n request);\n};\n\n\n/**\n * Requests verifyAssertion endpoint for an existing federated account. When\n * resolved, promise returns the whole response. If not existing, a\n * user-not-found error is thrown.\n * @param {!fireauth.RpcHandler.VerifyAssertionData} request\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.verifyAssertionForExisting = function(request) {\n // Since we are setting returnIdpCredential to true, a response will be\n // returned even though the account doesn't exist but an error message is\n // appended with value set to USER_NOT_FOUND. If this flag is not passed, only\n // the USER_NOT_FOUND error is thrown without any response.\n request['returnIdpCredential'] = true;\n // Do not create a new account if the user doesn't exist.\n request['autoCreate'] = false;\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.VERIFY_ASSERTION_FOR_EXISTING,\n request);\n};\n\n\n/**\n * Validates a request that should contain an action code.\n * @param {!Object} request\n * @private\n */\nfireauth.RpcHandler.validateApplyActionCodeRequest_ = function(request) {\n if (!request['oobCode']) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_OOB_CODE);\n }\n};\n\n\n/**\n * Validates that a checkActionCode response contains the email and requestType\n * fields.\n * @param {!Object} response The raw response returned by the server.\n * @private\n */\nfireauth.RpcHandler.validateCheckActionCodeResponse_ = function(response) {\n // If the code is invalid, usually a clear error would be returned.\n // In this case, something unexpected happened.\n // Email could be empty only if the request type is EMAIL_SIGNIN.\n var operation = response['requestType'];\n if (!operation ||\n (!response['email'] && operation != 'EMAIL_SIGNIN' &&\n operation != 'VERIFY_AND_CHANGE_EMAIL')) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n};\n\n\n/**\n * Requests resetPassword endpoint for password reset, returns promise that\n * resolves with user's email.\n * @param {string} code The email action code to confirm for password reset.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<string>}\n */\nfireauth.RpcHandler.prototype.confirmPasswordReset =\n function(code, newPassword) {\n var request = {\n 'oobCode': code,\n 'newPassword': newPassword\n };\n return this.invokeRpc(fireauth.RpcHandler.ApiMethod.RESET_PASSWORD, request);\n};\n\n\n/**\n * Checks the validity of an email action code and returns the response\n * received.\n * @param {string} code The email action code to check.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.RpcHandler.prototype.checkActionCode = function(code) {\n var request = {\n 'oobCode': code\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.CHECK_ACTION_CODE, request);\n};\n\n\n/**\n * Applies an out-of-band email action code, such as an email verification code.\n * @param {string} code The email action code.\n * @return {!goog.Promise<string>} A promise that resolves with the user's\n * email.\n */\nfireauth.RpcHandler.prototype.applyActionCode = function(code) {\n var request = {\n 'oobCode': code\n };\n return this.invokeRpc(\n fireauth.RpcHandler.ApiMethod.APPLY_OOB_CODE, request);\n};\n\n\n/**\n * The specification of an RPC call. The fields are:\n * <ul>\n * <li>cachebuster: defines whether to send a unique string with request to\n * force the backend to return an uncached response to request.\n * <li>customErrorMap: A map of backend error codes to client-side errors.\n * Any entries set here override the default handling of the backend error\n * code.\n * <li>endpoint: defines the backend endpoint to call.\n * <li>httpMethod: defines the HTTP method to use, defaulting to POST if not\n * specified.\n * <li>requestRequiredFields: an array of the fields that are required in the\n * request. The RPC call will fail with an INTERNAL_ERROR error if a\n * required field is not present or if it is null, undefined, or the empty\n * string.\n * <li>requestValidator: a function that takes in the request object and throws\n * an error if the request is invalid.\n * <li>responsePreprocessor: a function to modify the response before running\n * validation. The function takes in the request and response object.\n * <li>responseValidator: a function that takes in the response object and\n * throws an error if the response is invalid.\n * <li>responseField: the field of the response object that will be returned\n * from the RPC call. If no field is specified, the entire response object\n * will be returned.\n * <li>returnSecureToken: Set to true to explicitly request STS tokens instead\n * of legacy Google Identity Toolkit tokens from the backend.\n * <li>requireTenantId: Set to true to send tenant ID to backend in the request.\n * <li>useIdentityPlatformEndpoint: Whether to use new identity platform\n * endpoints. The default is false.\n * </ul>\n * @typedef {{\n * cachebuster: (boolean|undefined),\n * customErrorMap: (!fireauth.RpcHandler.ServerErrorMap|undefined),\n * endpoint: string,\n * httpMethod: (!fireauth.RpcHandler.HttpMethod|undefined),\n * requestRequiredFields: (!Array<string>|undefined),\n * requestValidator: (function(!Object):void|undefined),\n * responsePreprocessor: ((function(!Object, !Object):!Object)|undefined),\n * responseValidator: (function(!Object):void|undefined),\n * responseField: (string|undefined),\n * returnSecureToken: (boolean|undefined),\n * requireTenantId: (boolean|undefined),\n * useIdentityPlatformEndpoint: (boolean|undefined)\n * }}\n */\nfireauth.RpcHandler.ApiMethodHandler;\n\n\n/**\n * The specifications for the backend API methods.\n * @enum {!fireauth.RpcHandler.ApiMethodHandler}\n */\nfireauth.RpcHandler.ApiMethod = {\n APPLY_OOB_CODE: {\n endpoint: 'setAccountInfo',\n requestValidator: fireauth.RpcHandler.validateApplyActionCodeRequest_,\n responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n requireTenantId: true\n },\n CHECK_ACTION_CODE: {\n endpoint: 'resetPassword',\n requestValidator: fireauth.RpcHandler.validateApplyActionCodeRequest_,\n responseValidator: fireauth.RpcHandler.validateCheckActionCodeResponse_,\n requireTenantId: true\n },\n CREATE_ACCOUNT: {\n endpoint: 'signupNewUser',\n requestValidator: fireauth.RpcHandler.validateCreateAccountRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true,\n requireTenantId: true\n },\n CREATE_AUTH_URI: {\n endpoint: 'createAuthUri',\n requireTenantId: true\n },\n DELETE_ACCOUNT: {\n endpoint: 'deleteAccount',\n requestRequiredFields: ['idToken']\n },\n DELETE_LINKED_ACCOUNTS: {\n endpoint: 'setAccountInfo',\n requestRequiredFields: ['idToken', 'deleteProvider'],\n requestValidator: fireauth.RpcHandler.validateDeleteLinkedAccountsRequest_\n },\n EMAIL_LINK_SIGNIN: {\n endpoint: 'emailLinkSignin',\n requestRequiredFields: ['email', 'oobCode'],\n requestValidator: fireauth.RpcHandler.validateRequestHasEmail_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true,\n requireTenantId: true\n },\n EMAIL_LINK_SIGNIN_FOR_LINKING: {\n endpoint: 'emailLinkSignin',\n requestRequiredFields: ['idToken', 'email', 'oobCode'],\n requestValidator: fireauth.RpcHandler.validateRequestHasEmail_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true\n },\n FINALIZE_PHONE_MFA_ENROLLMENT: {\n endpoint: 'accounts/mfaEnrollment:finalize',\n requestRequiredFields: ['idToken', 'phoneVerificationInfo'],\n requestValidator:\n fireauth.RpcHandler.validateFinalizePhoneMfaRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n requireTenantId: true,\n useIdentityPlatformEndpoint: true\n },\n FINALIZE_PHONE_MFA_SIGN_IN: {\n endpoint: 'accounts/mfaSignIn:finalize',\n requestRequiredFields: ['mfaPendingCredential', 'phoneVerificationInfo'],\n requestValidator:\n fireauth.RpcHandler.validateFinalizePhoneMfaRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n requireTenantId: true,\n useIdentityPlatformEndpoint: true\n },\n GET_ACCOUNT_INFO: {\n endpoint: 'getAccountInfo'\n },\n GET_AUTH_URI: {\n endpoint: 'createAuthUri',\n requestValidator: fireauth.RpcHandler.validateGetAuthUriRequest_,\n responseValidator: fireauth.RpcHandler.validateGetAuthResponse_,\n requireTenantId: true\n },\n GET_EMAIL_SIGNIN_CODE: {\n endpoint: 'getOobConfirmationCode',\n requestRequiredFields: ['requestType'],\n requestValidator: fireauth.RpcHandler.validateEmailSignInCodeRequest_,\n responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n requireTenantId: true\n },\n GET_EMAIL_VERIFICATION_CODE: {\n endpoint: 'getOobConfirmationCode',\n requestRequiredFields: ['idToken', 'requestType'],\n requestValidator: fireauth.RpcHandler.validateEmailVerificationCodeRequest_,\n responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n requireTenantId: true\n },\n GET_EMAIL_VERIFICATION_CODE_BEFORE_UPDATE: {\n endpoint: 'getOobConfirmationCode',\n requestRequiredFields: ['idToken', 'newEmail', 'requestType'],\n requestValidator:\n fireauth.RpcHandler.validateEmailVerificationCodeBeforeUpdateRequest_,\n responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n requireTenantId: true\n },\n GET_OOB_CODE: {\n endpoint: 'getOobConfirmationCode',\n requestRequiredFields: ['requestType'],\n requestValidator: fireauth.RpcHandler.validateOobCodeRequest_,\n responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n requireTenantId: true\n },\n GET_PROJECT_CONFIG: {\n // Microsoft edge caching bug. There are two getProjectConfig API calls,\n // first from top level window and then from iframe. The second call has a\n // response of 304 which means it's a cached response. We suspect the call\n // from iframe is reusing the response from the first call and checks the\n // allowed origin in the cached response, which only contains the domain for\n // the top level window.\n cachebuster: true,\n endpoint: 'getProjectConfig',\n httpMethod: fireauth.RpcHandler.HttpMethod.GET\n },\n GET_RECAPTCHA_PARAM: {\n cachebuster: true,\n endpoint: 'getRecaptchaParam',\n httpMethod: fireauth.RpcHandler.HttpMethod.GET,\n responseValidator: fireauth.RpcHandler.validateGetRecaptchaParamResponse_\n },\n RESET_PASSWORD: {\n endpoint: 'resetPassword',\n requestValidator: fireauth.RpcHandler.validateApplyActionCodeRequest_,\n responseField: fireauth.RpcHandler.AuthServerField.EMAIL,\n requireTenantId: true\n },\n RETURN_DYNAMIC_LINK: {\n cachebuster: true,\n endpoint: 'getProjectConfig',\n httpMethod: fireauth.RpcHandler.HttpMethod.GET,\n responseField: fireauth.RpcHandler.AuthServerField.DYNAMIC_LINKS_DOMAIN\n },\n SEND_VERIFICATION_CODE: {\n endpoint: 'sendVerificationCode',\n // Currently only reCAPTCHA tokens supported.\n requestRequiredFields: ['phoneNumber', 'recaptchaToken'],\n responseField: fireauth.RpcHandler.AuthServerField.SESSION_INFO,\n requireTenantId: true\n },\n SET_ACCOUNT_INFO: {\n endpoint: 'setAccountInfo',\n requestRequiredFields: ['idToken'],\n requestValidator: fireauth.RpcHandler.validateEmailIfPresent_,\n returnSecureToken: true // Maybe updating email will invalidate token in the\n // future, this will prevent breaking the client.\n },\n SET_ACCOUNT_INFO_SENSITIVE: {\n endpoint: 'setAccountInfo',\n requestRequiredFields: ['idToken'],\n requestValidator: fireauth.RpcHandler.validateSetAccountInfoSensitive_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true // Updating password will send back new sts tokens.\n },\n SIGN_IN_ANONYMOUSLY: {\n endpoint: 'signupNewUser',\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true,\n requireTenantId: true\n },\n START_PHONE_MFA_ENROLLMENT: {\n endpoint: 'accounts/mfaEnrollment:start',\n requestRequiredFields: ['idToken', 'phoneEnrollmentInfo'],\n requestValidator:\n fireauth.RpcHandler.validateStartPhoneMfaEnrollmentRequest_,\n responseValidator:\n fireauth.RpcHandler.validateStartPhoneMfaEnrollmentResponse_,\n requireTenantId: true,\n useIdentityPlatformEndpoint: true\n },\n START_PHONE_MFA_SIGN_IN: {\n endpoint: 'accounts/mfaSignIn:start',\n requestRequiredFields: ['mfaPendingCredential', 'mfaEnrollmentId',\n 'phoneSignInInfo'],\n requestValidator:\n fireauth.RpcHandler.validateStartPhoneMfaSignInRequest_,\n responseValidator:\n fireauth.RpcHandler.validateStartPhoneMfaSignInResponse_,\n requireTenantId: true,\n useIdentityPlatformEndpoint: true\n },\n VERIFY_ASSERTION: {\n endpoint: 'verifyAssertion',\n requestValidator: fireauth.RpcHandler.validateVerifyAssertionRequest_,\n responsePreprocessor: fireauth.RpcHandler.processVerifyAssertionResponse_,\n responseValidator: fireauth.RpcHandler.validateVerifyAssertionResponse_,\n returnSecureToken: true,\n // Tenant ID is required for this endpoint. But for\n // signInWithRedirect/Popup APIs, to make createAuthUri call and\n // verifyAssertion call atomic, the tenant ID on RPC handler will be\n // overridden by the tenant ID passed directly from the\n // request, which is retrieved from Auth event. For signInWithCredential\n // API, the tenant ID will still be retrieved from the RPC handler.\n requireTenantId: true\n },\n VERIFY_ASSERTION_FOR_EXISTING: {\n endpoint: 'verifyAssertion',\n requestValidator: fireauth.RpcHandler.validateVerifyAssertionRequest_,\n responsePreprocessor: fireauth.RpcHandler.processVerifyAssertionResponse_,\n responseValidator:\n fireauth.RpcHandler.validateVerifyAssertionForExistingResponse_,\n returnSecureToken: true,\n // Tenant ID is required for this endpoint. But for\n // reauthenticateWithRedirect/Popup APIs, to make createAuthUri call and\n // verifyAssertion call atomic, the tenant ID on RPC handler will be\n // overridden by the tenant ID passed directly from the\n // request, which is retrieved from Auth event. For\n // reauthenticateWithCredential API, the tenant ID will still be retrieved\n // from the RPC handler.\n requireTenantId: true\n },\n VERIFY_ASSERTION_FOR_LINKING: {\n endpoint: 'verifyAssertion',\n requestValidator: fireauth.RpcHandler.validateVerifyAssertionLinkRequest_,\n responsePreprocessor: fireauth.RpcHandler.processVerifyAssertionResponse_,\n responseValidator: fireauth.RpcHandler.validateVerifyAssertionResponse_,\n returnSecureToken: true\n },\n VERIFY_CUSTOM_TOKEN: {\n endpoint: 'verifyCustomToken',\n requestValidator: fireauth.RpcHandler.validateVerifyCustomTokenRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true,\n requireTenantId: true\n },\n VERIFY_PASSWORD: {\n endpoint: 'verifyPassword',\n requestValidator: fireauth.RpcHandler.validateVerifyPasswordRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n returnSecureToken: true,\n requireTenantId: true\n },\n VERIFY_PHONE_NUMBER: {\n endpoint: 'verifyPhoneNumber',\n requestValidator: fireauth.RpcHandler.validateVerifyPhoneNumberRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n requireTenantId: true\n },\n VERIFY_PHONE_NUMBER_FOR_LINKING: {\n endpoint: 'verifyPhoneNumber',\n requestValidator: fireauth.RpcHandler.validateVerifyPhoneNumberLinkRequest_,\n responseValidator:\n fireauth.RpcHandler.validateVerifyPhoneNumberForLinkingResponse_\n },\n VERIFY_PHONE_NUMBER_FOR_EXISTING: {\n customErrorMap: fireauth.RpcHandler.verifyPhoneNumberForExistingErrorMap_,\n endpoint: 'verifyPhoneNumber',\n requestValidator: fireauth.RpcHandler.validateVerifyPhoneNumberRequest_,\n responseValidator: fireauth.RpcHandler.validateIdTokenResponse_,\n requireTenantId: true\n },\n WITHDRAW_MFA: {\n endpoint: 'accounts/mfaEnrollment:withdraw',\n requestRequiredFields: ['idToken', 'mfaEnrollmentId'],\n responseValidator: fireauth.RpcHandler.validateWithdrawMfaResponse_,\n requireTenantId: true,\n useIdentityPlatformEndpoint: true\n }\n};\n\n\n/**\n * @const {string} The parameter to send to the backend to specify that the\n * client accepts STS tokens directly from Firebear backends.\n * @private\n */\nfireauth.RpcHandler.USE_STS_TOKEN_PARAM_ = 'returnSecureToken';\n\n\n/**\n * @const {string} The parameter to send to the backend to specify the tenant\n * ID.\n * @private\n */\nfireauth.RpcHandler.TENANT_ID_PARAM_ = 'tenantId';\n\n\n/**\n * Invokes an RPC method according to the specification defined by\n * {@code fireauth.RpcHandler.ApiMethod}.\n * @param {!fireauth.RpcHandler.ApiMethod} method The method to invoke.\n * @param {!Object} request The input data to the method.\n * @return {!goog.Promise} A promise that resolves with the results of the RPC.\n * The format of the results can be modified in\n * {@code fireauth.RpcHandler.ApiMethod}.\n */\nfireauth.RpcHandler.prototype.invokeRpc = function(method, request) {\n if (!fireauth.object.hasNonEmptyFields(\n request, method.requestRequiredFields)) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR));\n }\n\n var useIdentityPlatformEndpoint = !!method.useIdentityPlatformEndpoint;\n var httpMethod = method.httpMethod || fireauth.RpcHandler.HttpMethod.POST;\n var self = this;\n var response;\n return goog.Promise.resolve(request)\n .then(method.requestValidator)\n .then(function() {\n if (method.returnSecureToken) {\n // Signal that the client accepts STS tokens, for the legacy Google\n // Identity Toolkit token to STS token migration.\n request[fireauth.RpcHandler.USE_STS_TOKEN_PARAM_] = true;\n }\n // If tenant ID is explicitly passed in the request, it will override\n // the tenant ID on RPC handler.\n if (method.requireTenantId && self.tenantId_ &&\n (typeof request[fireauth.RpcHandler.TENANT_ID_PARAM_] ===\n 'undefined')) {\n request[fireauth.RpcHandler.TENANT_ID_PARAM_] = self.tenantId_;\n }\n return useIdentityPlatformEndpoint ?\n self.requestIdentityPlatformEndpoint(method.endpoint, httpMethod,\n request, method.customErrorMap, method.cachebuster || false) :\n self.requestFirebaseEndpoint(method.endpoint, httpMethod,\n request, method.customErrorMap, method.cachebuster || false);\n })\n .then(function(tempResponse) {\n response = tempResponse;\n // If response processor is available, pass request and response through\n // it. Modifications would be made using response reference.\n if (method.responsePreprocessor) {\n return method.responsePreprocessor(request, response);\n }\n return response;\n })\n .then(method.responseValidator)\n .then(function() {\n if (!method.responseField) {\n return response;\n }\n if (!(method.responseField in response)) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR);\n }\n return response[method.responseField];\n });\n};\n\n\n/**\n * Checks if the server response contains errors.\n * @param {!Object} resp The API response.\n * @return {boolean} {@code true} if the response contains errors.\n * @private\n */\nfireauth.RpcHandler.hasError_ = function(resp) {\n return !!resp['error'];\n};\n\n\n/**\n * Returns the developer facing error corresponding to the server code provided.\n * @param {string} serverErrorCode The server error message.\n * @return {!fireauth.AuthError} The corresponding error object.\n * @private\n */\nfireauth.RpcHandler.getDeveloperErrorFromCode_ = function(serverErrorCode) {\n // Encapsulate the server error code in a typical server error response with\n // the code populated within. This will convert the response to a developer\n // facing one.\n return fireauth.RpcHandler.getDeveloperError_({\n 'error': {\n 'errors': [\n {\n 'message': serverErrorCode\n }\n ],\n 'code': 400,\n 'message': serverErrorCode\n }\n });\n};\n\n\n/**\n * Converts a server response with errors to a developer-facing AuthError.\n * @param {!Object} response The server response.\n * @param {?fireauth.RpcHandler.ServerErrorMap=} opt_customErrorMap A map of\n * backend error codes to client-side errors. Any entries set here\n * override the default handling of the backend error code.\n * @return {!fireauth.AuthError} The corresponding error object.\n * @private\n */\nfireauth.RpcHandler.getDeveloperError_ =\n function(response, opt_customErrorMap) {\n var errorMessage;\n var apiaryError = fireauth.RpcHandler.getApiaryError_(response);\n if (apiaryError) {\n return apiaryError;\n }\n\n var serverErrorCode = fireauth.RpcHandler.getErrorCode_(response);\n\n var errorMap = {};\n\n // Custom token errors.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_CUSTOM_TOKEN] =\n fireauth.authenum.Error.INVALID_CUSTOM_TOKEN;\n errorMap[fireauth.RpcHandler.ServerError.CREDENTIAL_MISMATCH] =\n fireauth.authenum.Error.CREDENTIAL_MISMATCH;\n // This can only happen if the SDK sends a bad request.\n errorMap[fireauth.RpcHandler.ServerError.MISSING_CUSTOM_TOKEN] =\n fireauth.authenum.Error.INTERNAL_ERROR;\n\n // Create Auth URI errors.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_IDENTIFIER] =\n fireauth.authenum.Error.INVALID_EMAIL;\n // This can only happen if the SDK sends a bad request.\n errorMap[fireauth.RpcHandler.ServerError.MISSING_CONTINUE_URI] =\n fireauth.authenum.Error.INTERNAL_ERROR;\n\n // Sign in with email and password errors (some apply to sign up too).\n errorMap[fireauth.RpcHandler.ServerError.INVALID_EMAIL] =\n fireauth.authenum.Error.INVALID_EMAIL;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_PASSWORD] =\n fireauth.authenum.Error.INVALID_PASSWORD;\n errorMap[fireauth.RpcHandler.ServerError.USER_DISABLED] =\n fireauth.authenum.Error.USER_DISABLED;\n // This can only happen if the SDK sends a bad request.\n errorMap[fireauth.RpcHandler.ServerError.MISSING_PASSWORD] =\n fireauth.authenum.Error.INTERNAL_ERROR;\n\n // Sign up with email and password errors.\n errorMap[fireauth.RpcHandler.ServerError.EMAIL_EXISTS] =\n fireauth.authenum.Error.EMAIL_EXISTS;\n errorMap[fireauth.RpcHandler.ServerError.PASSWORD_LOGIN_DISABLED] =\n fireauth.authenum.Error.OPERATION_NOT_ALLOWED;\n\n // Verify assertion for sign in with credential errors:\n errorMap[fireauth.RpcHandler.ServerError.INVALID_IDP_RESPONSE] =\n fireauth.authenum.Error.INVALID_IDP_RESPONSE;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_PENDING_TOKEN] =\n fireauth.authenum.Error.INVALID_IDP_RESPONSE;\n errorMap[fireauth.RpcHandler.ServerError.FEDERATED_USER_ID_ALREADY_LINKED] =\n fireauth.authenum.Error.CREDENTIAL_ALREADY_IN_USE;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_OR_INVALID_NONCE] =\n fireauth.authenum.Error.MISSING_OR_INVALID_NONCE;\n\n // Email template errors while sending emails:\n errorMap[fireauth.RpcHandler.ServerError.INVALID_MESSAGE_PAYLOAD] =\n fireauth.authenum.Error.INVALID_MESSAGE_PAYLOAD;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_RECIPIENT_EMAIL] =\n fireauth.authenum.Error.INVALID_RECIPIENT_EMAIL;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_SENDER] =\n fireauth.authenum.Error.INVALID_SENDER;\n\n // Send Password reset email errors:\n errorMap[fireauth.RpcHandler.ServerError.EMAIL_NOT_FOUND] =\n fireauth.authenum.Error.USER_DELETED;\n errorMap[fireauth.RpcHandler.ServerError.RESET_PASSWORD_EXCEED_LIMIT] =\n fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER;\n\n // Reset password errors:\n errorMap[fireauth.RpcHandler.ServerError.EXPIRED_OOB_CODE] =\n fireauth.authenum.Error.EXPIRED_OOB_CODE;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_OOB_CODE] =\n fireauth.authenum.Error.INVALID_OOB_CODE;\n // This can only happen if the SDK sends a bad request.\n errorMap[fireauth.RpcHandler.ServerError.MISSING_OOB_CODE] =\n fireauth.authenum.Error.INTERNAL_ERROR;\n\n // Get Auth URI errors:\n errorMap[fireauth.RpcHandler.ServerError.INVALID_PROVIDER_ID] =\n fireauth.authenum.Error.INVALID_PROVIDER_ID;\n\n // Operations that require ID token in request:\n errorMap[fireauth.RpcHandler.ServerError.CREDENTIAL_TOO_OLD_LOGIN_AGAIN] =\n fireauth.authenum.Error.CREDENTIAL_TOO_OLD_LOGIN_AGAIN;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_ID_TOKEN] =\n fireauth.authenum.Error.INVALID_AUTH;\n errorMap[fireauth.RpcHandler.ServerError.TOKEN_EXPIRED] =\n fireauth.authenum.Error.TOKEN_EXPIRED;\n errorMap[fireauth.RpcHandler.ServerError.USER_NOT_FOUND] =\n fireauth.authenum.Error.TOKEN_EXPIRED;\n\n // CORS issues.\n errorMap[fireauth.RpcHandler.ServerError.CORS_UNSUPPORTED] =\n fireauth.authenum.Error.CORS_UNSUPPORTED;\n\n // Dynamic link not activated.\n errorMap[fireauth.RpcHandler.ServerError.DYNAMIC_LINK_NOT_ACTIVATED] =\n fireauth.authenum.Error.DYNAMIC_LINK_NOT_ACTIVATED;\n\n // iosBundleId or androidPackageName not valid error.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_APP_ID] =\n fireauth.authenum.Error.INVALID_APP_ID;\n\n // Other errors.\n errorMap[fireauth.RpcHandler.ServerError.TOO_MANY_ATTEMPTS_TRY_LATER] =\n fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER;\n errorMap[fireauth.RpcHandler.ServerError.WEAK_PASSWORD] =\n fireauth.authenum.Error.WEAK_PASSWORD;\n errorMap[fireauth.RpcHandler.ServerError.OPERATION_NOT_ALLOWED] =\n fireauth.authenum.Error.OPERATION_NOT_ALLOWED;\n errorMap[fireauth.RpcHandler.ServerError.USER_CANCELLED] =\n fireauth.authenum.Error.USER_CANCELLED;\n\n // Phone Auth related errors.\n errorMap[fireauth.RpcHandler.ServerError.CAPTCHA_CHECK_FAILED] =\n fireauth.authenum.Error.CAPTCHA_CHECK_FAILED;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_APP_CREDENTIAL] =\n fireauth.authenum.Error.INVALID_APP_CREDENTIAL;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_CODE] =\n fireauth.authenum.Error.INVALID_CODE;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_PHONE_NUMBER] =\n fireauth.authenum.Error.INVALID_PHONE_NUMBER;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_SESSION_INFO] =\n fireauth.authenum.Error.INVALID_SESSION_INFO;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_TEMPORARY_PROOF] =\n fireauth.authenum.Error.INVALID_IDP_RESPONSE;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_APP_CREDENTIAL] =\n fireauth.authenum.Error.MISSING_APP_CREDENTIAL;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_CODE] =\n fireauth.authenum.Error.MISSING_CODE;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_PHONE_NUMBER] =\n fireauth.authenum.Error.MISSING_PHONE_NUMBER;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_SESSION_INFO] =\n fireauth.authenum.Error.MISSING_SESSION_INFO;\n errorMap[fireauth.RpcHandler.ServerError.QUOTA_EXCEEDED] =\n fireauth.authenum.Error.QUOTA_EXCEEDED;\n errorMap[fireauth.RpcHandler.ServerError.SESSION_EXPIRED] =\n fireauth.authenum.Error.CODE_EXPIRED;\n errorMap[fireauth.RpcHandler.ServerError.REJECTED_CREDENTIAL] =\n fireauth.authenum.Error.REJECTED_CREDENTIAL;\n\n // Other action code errors when additional settings passed.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_CONTINUE_URI] =\n fireauth.authenum.Error.INVALID_CONTINUE_URI;\n // MISSING_CONTINUE_URI is getting mapped to INTERNAL_ERROR above.\n // This is OK as this error will be caught by client side validation.\n errorMap[fireauth.RpcHandler.ServerError.MISSING_ANDROID_PACKAGE_NAME] =\n fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_IOS_BUNDLE_ID] =\n fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID;\n errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] =\n fireauth.authenum.Error.UNAUTHORIZED_DOMAIN;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_DYNAMIC_LINK_DOMAIN] =\n fireauth.authenum.Error.INVALID_DYNAMIC_LINK_DOMAIN;\n\n // getProjectConfig errors when clientId is passed.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_OAUTH_CLIENT_ID] =\n fireauth.authenum.Error.INVALID_OAUTH_CLIENT_ID;\n // getProjectConfig errors when sha1Cert is passed.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_CERT_HASH] =\n fireauth.authenum.Error.INVALID_CERT_HASH;\n\n // Multi-tenant related errors.\n errorMap[fireauth.RpcHandler.ServerError.UNSUPPORTED_TENANT_OPERATION] =\n fireauth.authenum.Error.UNSUPPORTED_TENANT_OPERATION;\n errorMap[fireauth.RpcHandler.ServerError.INVALID_TENANT_ID] =\n fireauth.authenum.Error.INVALID_TENANT_ID;\n errorMap[fireauth.RpcHandler.ServerError.TENANT_ID_MISMATCH] =\n fireauth.authenum.Error.TENANT_ID_MISMATCH;\n\n // User actions (sign-up or deletion) disabled errors.\n errorMap[fireauth.RpcHandler.ServerError.ADMIN_ONLY_OPERATION] =\n fireauth.authenum.Error.ADMIN_ONLY_OPERATION;\n\n // Multi-factor related errors.\n errorMap[fireauth.RpcHandler.ServerError.INVALID_MFA_PENDING_CREDENTIAL] =\n fireauth.authenum.Error.INVALID_MFA_PENDING_CREDENTIAL;\n errorMap[fireauth.RpcHandler.ServerError.MFA_ENROLLMENT_NOT_FOUND] =\n fireauth.authenum.Error.MFA_ENROLLMENT_NOT_FOUND;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_MFA_PENDING_CREDENTIAL] =\n fireauth.authenum.Error.MISSING_MFA_PENDING_CREDENTIAL;\n errorMap[fireauth.RpcHandler.ServerError.MISSING_MFA_ENROLLMENT_ID] =\n fireauth.authenum.Error.MISSING_MFA_ENROLLMENT_ID;\n errorMap[fireauth.RpcHandler.ServerError.EMAIL_CHANGE_NEEDS_VERIFICATION] =\n fireauth.authenum.Error.EMAIL_CHANGE_NEEDS_VERIFICATION;\n errorMap[fireauth.RpcHandler.ServerError.SECOND_FACTOR_EXISTS] =\n fireauth.authenum.Error.SECOND_FACTOR_EXISTS;\n errorMap[fireauth.RpcHandler.ServerError.SECOND_FACTOR_LIMIT_EXCEEDED] =\n fireauth.authenum.Error.SECOND_FACTOR_LIMIT_EXCEEDED;\n errorMap[fireauth.RpcHandler.ServerError.UNSUPPORTED_FIRST_FACTOR] =\n fireauth.authenum.Error.UNSUPPORTED_FIRST_FACTOR;\n errorMap[fireauth.RpcHandler.ServerError.UNVERIFIED_EMAIL] =\n fireauth.authenum.Error.UNVERIFIED_EMAIL;\n\n // Override errors set in the custom map.\n var customErrorMap = opt_customErrorMap || {};\n goog.object.extend(errorMap, customErrorMap);\n\n // Get detailed message if available.\n errorMessage = fireauth.RpcHandler.getErrorCodeDetails(serverErrorCode);\n\n // Handle backend errors where the error code can be a prefix of the message\n // (e.g. \"WEAK_PASSWORD : Password should be at least 6 characters\").\n // Use the details after the colon as the error message. If none available,\n // pass undefined, which will default to the client hard coded error messages.\n for (var prefixCode in errorMap) {\n if (serverErrorCode.indexOf(prefixCode) === 0) {\n return new fireauth.AuthError(errorMap[prefixCode], errorMessage);\n }\n }\n\n // No error message found, return the serialized response as the message.\n // This is likely to be an Apiary error for unexpected cases like keyExpired,\n // etc.\n if (!errorMessage && response) {\n errorMessage = fireauth.util.stringifyJSON(response);\n }\n // The backend returned some error we don't recognize; this is an error on\n // our side.\n return new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR, errorMessage);\n};\n\n\n/**\n * @param {string} serverMessage The server error code.\n * @return {string|undefined} The detailed error code message.\n */\nfireauth.RpcHandler.getErrorCodeDetails = function(serverMessage) {\n // Use the error details part as the autherror message.\n // For a message INVALID_CUSTOM_TOKEN : [error detail here],\n // The Auth error message should be [error detail here].\n // No space should be contained in the error code, otherwise no detailed error\n // message returned.\n var matches = serverMessage.match(/^[^\\s]+\\s*:\\s*([\\s\\S]*)$/);\n if (matches && matches.length > 1) {\n return matches[1];\n }\n return undefined;\n};\n\n\n/**\n * Gets the Apiary error from a backend response, if applicable.\n * @param {!Object} response The API response.\n * @return {?fireauth.AuthError} The error, if applicable.\n * @private\n */\nfireauth.RpcHandler.getApiaryError_ = function(response) {\n var error = response['error'] && response['error']['errors'] &&\n response['error']['errors'][0] || {};\n var reason = error['reason'] || '';\n\n var errorReasonMap = {\n 'keyInvalid': fireauth.authenum.Error.INVALID_API_KEY,\n 'ipRefererBlocked': fireauth.authenum.Error.APP_NOT_AUTHORIZED\n };\n\n if (errorReasonMap[reason]) {\n return new fireauth.AuthError(errorReasonMap[reason]);\n }\n\n return null;\n};\n\n\n/**\n * Gets the server error code from the response.\n * @param {!Object} resp The API response.\n * @return {string} The error code if present.\n * @private\n */\nfireauth.RpcHandler.getErrorCode_ = function(resp) {\n return (resp['error'] && resp['error']['message']) || '';\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview The headless Auth class used for authenticating Firebase users.\n */\n\ngoog.provide('fireauth.Auth');\n\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.ActionCodeSettings');\ngoog.require('fireauth.AdditionalUserInfo');\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthEventHandler');\ngoog.require('fireauth.AuthEventManager');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.AuthSettings');\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.ConfirmationResult');\ngoog.require('fireauth.EmailAuthProvider');\ngoog.require('fireauth.MultiFactorError');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.UserEventType');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.deprecation');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.object');\ngoog.require('fireauth.storage.RedirectUserManager');\ngoog.require('fireauth.storage.UserManager');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.object');\n\n\n\n/**\n * Creates the Firebase Auth corresponding for the App provided.\n *\n * @param {!firebase.app.App} app The corresponding Firebase App.\n * @constructor\n * @implements {fireauth.AuthEventHandler}\n * @implements {firebase.Service}\n * @extends {goog.events.EventTarget}\n */\nfireauth.Auth = function(app) {\n /** @private {boolean} Whether this instance is deleted. */\n this.deleted_ = false;\n /** The Auth instance's settings object. */\n fireauth.object.setReadonlyProperty(\n this, 'settings', new fireauth.AuthSettings());\n /** Auth's corresponding App. */\n fireauth.object.setReadonlyProperty(this, 'app', app);\n // Initialize RPC handler.\n // API key is required for web client RPC calls.\n if (this.app_().options && this.app_().options['apiKey']) {\n var clientFullVersion = firebase.SDK_VERSION ?\n fireauth.util.getClientVersion(\n fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION) :\n null;\n this.rpcHandler_ = new fireauth.RpcHandler(\n this.app_().options && this.app_().options['apiKey'],\n // Get the client Auth endpoint used.\n fireauth.constants.getEndpointConfig(fireauth.constants.clientEndpoint),\n clientFullVersion);\n } else {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_API_KEY);\n }\n /** @private {!Array<!goog.Promise<*, *>|!goog.Promise<void>>} List of\n * pending promises. */\n this.pendingPromises_ = [];\n /** @private {!Array<!function(?string)>} Auth token listeners. */\n this.authListeners_ = [];\n /** @private {!Array<!function(?string)>} User change listeners. */\n this.userChangeListeners_ = [];\n /**\n * @private {!firebase.Subscribe} The subscribe function to the Auth ID token\n * change observer. This will trigger on ID token changes, including\n * token refresh on the same user.\n */\n this.onIdTokenChanged_ = firebase.INTERNAL.createSubscribe(\n goog.bind(this.initIdTokenChangeObserver_, this));\n /**\n * @private {?string|undefined} The UID of the user that last triggered the\n * user state change listener.\n */\n this.userStateChangeUid_ = undefined;\n /**\n * @private {!firebase.Subscribe} The subscribe function to the user state\n * change observer.\n */\n this.onUserStateChanged_ = firebase.INTERNAL.createSubscribe(\n goog.bind(this.initUserStateObserver_, this));\n // Set currentUser to null.\n this.setCurrentUser_(null);\n /**\n * @private {!fireauth.storage.UserManager} The Auth user storage\n * manager instance.\n */\n this.userStorageManager_ =\n new fireauth.storage.UserManager(this.getStorageKey());\n /**\n * @private {!fireauth.storage.RedirectUserManager} The redirect user\n * storagemanager instance.\n */\n this.redirectUserStorageManager_ =\n new fireauth.storage.RedirectUserManager(this.getStorageKey());\n /**\n * @private {!goog.Promise<undefined>} Promise that resolves when initial\n * state is loaded from storage.\n */\n this.authStateLoaded_ = this.registerPendingPromise_(this.initAuthState_());\n /**\n * @private {!goog.Promise<undefined>} Promise that resolves when state and\n * redirect result is ready, after which sign in and sign out operations\n * are safe to execute.\n */\n this.redirectStateIsReady_ = this.registerPendingPromise_(\n this.initAuthRedirectState_());\n /** @private {boolean} Whether initial state has already been resolved. */\n this.isStateResolved_ = false;\n /**\n * @private {!function()} The syncAuthChanges function with context set to\n * auth instance.\n */\n this.getSyncAuthUserChanges_ = goog.bind(this.syncAuthUserChanges_, this);\n /** @private {!function(!fireauth.AuthUser):!goog.Promise} The handler for\n * user state changes. */\n this.userStateChangeListener_ =\n goog.bind(this.handleUserStateChange_, this);\n /** @private {!function(!Object)} The handler for user token changes. */\n this.userTokenChangeListener_ =\n goog.bind(this.handleUserTokenChange_, this);\n /** @private {!function(!Object)} The handler for user deletion. */\n this.userDeleteListener_ = goog.bind(this.handleUserDelete_, this);\n /** @private {!function(!Object)} The handler for user invalidation. */\n this.userInvalidatedListener_ = goog.bind(this.handleUserInvalidated_, this);\n /**\n * @private {?fireauth.AuthEventManager} The Auth event manager instance.\n */\n this.authEventManager_ = null;\n // TODO: find better way to enable or disable auth event manager.\n if (fireauth.AuthEventManager.ENABLED) {\n // Initialize Auth event manager to handle popup and redirect operations.\n this.initAuthEventManager_();\n }\n\n // Export INTERNAL namespace.\n this.INTERNAL = {};\n this.INTERNAL['delete'] = goog.bind(this.delete, this);\n this.INTERNAL['logFramework'] = goog.bind(this.logFramework, this);\n /**\n * @private {number} The number of Firebase services subscribed to Auth\n * changes.\n */\n this.firebaseServices_ = 0;\n // Add call to superclass constructor.\n fireauth.Auth.base(this, 'constructor');\n // Initialize readable/writable Auth properties.\n this.initializeReadableWritableProps_();\n /**\n * @private {!Array<string>} List of Firebase frameworks/libraries used. This\n * is currently only used to log FirebaseUI.\n */\n this.frameworks_ = [];\n};\ngoog.inherits(fireauth.Auth, goog.events.EventTarget);\n\n\n/**\n * Language code change custom event.\n * @param {?string} languageCode The new language code.\n * @constructor\n * @extends {goog.events.Event}\n */\nfireauth.Auth.LanguageCodeChangeEvent = function(languageCode) {\n goog.events.Event.call(\n this, fireauth.constants.AuthEventType.LANGUAGE_CODE_CHANGED);\n this.languageCode = languageCode;\n};\ngoog.inherits(fireauth.Auth.LanguageCodeChangeEvent, goog.events.Event);\n\n\n/**\n * Framework change custom event.\n * @param {!Array<string>} frameworks The new frameworks array.\n * @constructor\n * @extends {goog.events.Event}\n */\nfireauth.Auth.FrameworkChangeEvent = function(frameworks) {\n goog.events.Event.call(\n this, fireauth.constants.AuthEventType.FRAMEWORK_CHANGED);\n this.frameworks = frameworks;\n};\ngoog.inherits(fireauth.Auth.FrameworkChangeEvent, goog.events.Event);\n\n\n/**\n * Changes the Auth state persistence to the specified one.\n * @param {!fireauth.authStorage.Persistence} persistence The Auth state\n * persistence mechanism.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.setPersistence = function(persistence) {\n // TODO: fix auth.delete() behavior and how this affects persistence\n // change after deletion.\n // Throw an error if already destroyed.\n // Set current persistence.\n var p = this.userStorageManager_.setPersistence(persistence);\n return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(p));\n};\n\n\n/**\n * Get rid of Closure warning - the property is adding in the constructor.\n * @type {!firebase.app.App}\n */\nfireauth.Auth.prototype.app;\n\n\n/**\n * Sets the language code.\n * @param {?string} languageCode\n */\nfireauth.Auth.prototype.setLanguageCode = function(languageCode) {\n // Don't do anything if no change detected.\n if (this.languageCode_ !== languageCode && !this.deleted_) {\n this.languageCode_ = languageCode;\n // Update custom Firebase locale field.\n this.rpcHandler_.updateCustomLocaleHeader(this.languageCode_);\n // Notify external language code change listeners.\n this.notifyLanguageCodeListeners_();\n }\n};\n\n\n/**\n * Returns the current auth instance's language code if available.\n * @return {?string}\n */\nfireauth.Auth.prototype.getLanguageCode = function() {\n return this.languageCode_;\n};\n\n\n/**\n * Sets the current language to the default device/browser preference.\n */\nfireauth.Auth.prototype.useDeviceLanguage = function() {\n this.setLanguageCode(fireauth.util.getUserLanguage());\n};\n\n\n/**\n * @param {string} frameworkId The framework identifier.\n */\nfireauth.Auth.prototype.logFramework = function(frameworkId) {\n // Theoretically multiple frameworks could be used\n // (angularfire and FirebaseUI). Once a framework is used, it is not going\n // to be unused, so no point adding a method to remove the framework ID.\n this.frameworks_.push(frameworkId);\n // Update the client version in RPC handler with the new frameworks.\n this.rpcHandler_.updateClientVersion(firebase.SDK_VERSION ?\n fireauth.util.getClientVersion(\n fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION,\n this.frameworks_) :\n null);\n this.dispatchEvent(new fireauth.Auth.FrameworkChangeEvent(\n this.frameworks_));\n};\n\n\n/** @return {!Array<string>} The current Firebase frameworks. */\nfireauth.Auth.prototype.getFramework = function() {\n return goog.array.clone(this.frameworks_);\n};\n\n\n/**\n * Updates the framework list on the provided user and configures the user to\n * listen to the Auth instance for any framework ID changes.\n * @param {!fireauth.AuthUser} user The user to whose framework list needs to be\n * updated.\n * @private\n */\nfireauth.Auth.prototype.setUserFramework_ = function(user) {\n // Sets the framework ID on the user.\n user.setFramework(this.frameworks_);\n // Sets current Auth instance as framework list change dispatcher on the user.\n user.setFrameworkChangeDispatcher(this);\n};\n\n\n/**\n * Sets the tenant ID.\n * @param {?string} tenantId The tenant ID of the tenant project if available.\n */\nfireauth.Auth.prototype.setTenantId = function(tenantId) {\n // Don't do anything if no change detected.\n if (this.tenantId_ !== tenantId && !this.deleted_) {\n this.tenantId_ = tenantId;\n this.rpcHandler_.updateTenantId(this.tenantId_);\n }\n};\n\n\n/**\n * Returns the current Auth instance's tenant ID.\n * @return {?string}\n */\nfireauth.Auth.prototype.getTenantId = function() {\n return this.tenantId_;\n};\n\n\n/**\n * Initializes readable/writable properties on Auth.\n * @suppress {invalidCasts}\n * @private\n */\nfireauth.Auth.prototype.initializeReadableWritableProps_ = function() {\n Object.defineProperty(/** @type {!Object} */ (this), 'lc', {\n /**\n * @this {!Object}\n * @return {?string} The current language code.\n */\n get: function() {\n return this.getLanguageCode();\n },\n /**\n * @this {!Object}\n * @param {string} value The new language code.\n */\n set: function(value) {\n this.setLanguageCode(value);\n },\n enumerable: false\n });\n // Initialize to null.\n /** @private {?string} The current Auth instance's language code. */\n this.languageCode_ = null;\n\n // Initialize tenant ID.\n Object.defineProperty(/** @type {!Object} */ (this), 'ti', {\n /**\n * @this {!Object}\n * @return {?string} The current tenant ID.\n */\n get: function() {\n return this.getTenantId();\n },\n /**\n * @this {!Object}\n * @param {?string} value The new tenant ID.\n */\n set: function(value) {\n this.setTenantId(value);\n },\n enumerable: false\n });\n // Initialize to null.\n /** @private {?string} The current Auth instance's tenant ID. */\n this.tenantId_ = null;\n};\n\n\n/**\n * Notifies all external listeners of the language code change.\n * @private\n */\nfireauth.Auth.prototype.notifyLanguageCodeListeners_ = function() {\n // Notify external listeners on the language code change.\n this.dispatchEvent(new fireauth.Auth.LanguageCodeChangeEvent(\n this.getLanguageCode()));\n};\n\n\n\n\n\n/**\n * @return {!Object} The object representation of the Auth instance.\n * @override\n */\nfireauth.Auth.prototype.toJSON = function() {\n // Return the plain object representation in case JSON.stringify is called on\n // an Auth instance.\n return {\n 'apiKey': this.app_().options['apiKey'],\n 'authDomain': this.app_().options['authDomain'],\n 'appName': this.app_().name,\n 'currentUser': this.currentUser_() && this.currentUser_().toPlainObject()\n };\n};\n\n\n/**\n * Returns the Auth event manager promise.\n * @return {!goog.Promise<!fireauth.AuthEventManager>}\n * @private\n */\nfireauth.Auth.prototype.getAuthEventManager_ = function() {\n // Either return cached Auth event manager promise provider if available or a\n // promise that rejects with missing Auth domain error.\n return this.eventManagerProviderPromise_ ||\n goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.MISSING_AUTH_DOMAIN));\n};\n\n\n/**\n * Initializes the Auth event manager when state is ready.\n * @private\n */\nfireauth.Auth.prototype.initAuthEventManager_ = function() {\n // Initialize Auth event manager on initState.\n var self = this;\n var authDomain = this.app_().options['authDomain'];\n var apiKey = this.app_().options['apiKey'];\n // Make sure environment also supports popup and redirect.\n if (authDomain && fireauth.util.isPopupRedirectSupported()) {\n // Auth domain is required for Auth event manager to resolve.\n // Auth state has to be loaded first. One reason is to process link events.\n this.eventManagerProviderPromise_ = this.authStateLoaded_.then(function() {\n if (self.deleted_) {\n return;\n }\n // By this time currentUser should be ready if available and will be able\n // to resolve linkWithRedirect if detected.\n self.authEventManager_ = fireauth.AuthEventManager.getManager(\n authDomain, apiKey, self.app_().name);\n // Subscribe Auth instance.\n self.authEventManager_.subscribe(self);\n // Subscribe current user by enabling popup and redirect on that user.\n if (self.currentUser_()) {\n self.currentUser_().enablePopupRedirect();\n }\n // If a redirect user is present, subscribe to popup and redirect events.\n // In case current user was not available and the developer called link\n // with redirect on a signed out user, this will work and the linked\n // logged out user will be returned in getRedirectResult.\n // current user and redirect user are the same (was already logged in),\n // currentUser will have priority as it is subscribed before redirect\n // user. This change will also allow further popup and redirect events on\n // the redirect user going forward.\n if (self.redirectUser_) {\n self.redirectUser_.enablePopupRedirect();\n // Set the user language for the redirect user.\n self.setUserLanguage_(\n /** @type {!fireauth.AuthUser} */ (self.redirectUser_));\n // Set the user Firebase frameworks for the redirect user.\n self.setUserFramework_(\n /** @type {!fireauth.AuthUser} */ (self.redirectUser_));\n // Reference to redirect user no longer needed.\n self.redirectUser_ = null;\n }\n return self.authEventManager_;\n });\n }\n};\n\n\n/**\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The event ID.\n * @return {boolean} Whether the auth event handler can handler the provided\n * event.\n * @override\n */\nfireauth.Auth.prototype.canHandleAuthEvent = function(mode, opt_eventId) {\n // Only sign in events are handled.\n switch (mode) {\n // Accept all general sign in with redirect and unknowns.\n // Migrating redirect events to use session storage will prevent this event\n // from leaking to other tabs.\n case fireauth.AuthEvent.Type.UNKNOWN:\n case fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT:\n return true;\n case fireauth.AuthEvent.Type. SIGN_IN_VIA_POPUP:\n // Pending sign in with popup event must match the stored popup event ID.\n return this.popupEventId_ == opt_eventId &&\n !!this.pendingPopupResolvePromise_;\n default:\n return false;\n }\n};\n\n\n/**\n * Completes the pending popup operation. If error is not null, rejects with the\n * error. Otherwise, it resolves with the popup redirect result.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The result\n * to resolve with when no error supplied.\n * @param {?fireauth.AuthError} error When supplied, the promise will reject.\n * @param {?string=} opt_eventId The event ID.\n * @override\n */\nfireauth.Auth.prototype.resolvePendingPopupEvent =\n function(mode, popupRedirectResult, error, opt_eventId) {\n // Only handles popup events of type sign in and which match popup event ID.\n if (mode != fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP ||\n this.popupEventId_ != opt_eventId) {\n return;\n }\n if (error && this.pendingPopupRejectPromise_) {\n // Reject with error for supplied mode.\n this.pendingPopupRejectPromise_(error);\n } else if (popupRedirectResult &&\n !error &&\n this.pendingPopupResolvePromise_) {\n // Resolve with result for supplied mode.\n this.pendingPopupResolvePromise_(popupRedirectResult);\n }\n // Now that event is resolved, delete popup timeout promise.\n if (this.popupTimeoutPromise_) {\n this.popupTimeoutPromise_.cancel();\n this.popupTimeoutPromise_ = null;\n }\n // Delete pending promises.\n delete this.pendingPopupResolvePromise_;\n delete this.pendingPopupRejectPromise_;\n};\n\n\n/**\n * Returns the handler's appropriate popup and redirect sign in operation\n * finisher.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The optional event ID.\n * @return {?function(string, string, ?string,\n * ?string=):!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @override\n */\nfireauth.Auth.prototype.getAuthEventHandlerFinisher =\n function(mode, opt_eventId) {\n // Sign in events will be completed by finishPopupAndRedirectSignIn.\n if (mode == fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT) {\n return goog.bind(this.finishPopupAndRedirectSignIn, this);\n } else if (mode == fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP &&\n this.popupEventId_ == opt_eventId &&\n this.pendingPopupResolvePromise_) {\n return goog.bind(this.finishPopupAndRedirectSignIn, this);\n }\n return null;\n};\n\n\n/**\n * Finishes the popup and redirect sign in operations.\n * @param {string} requestUri The callback url with the oauth response.\n * @param {string} sessionId The session id used to generate the authUri.\n * @param {?string} tenantId The tenant ID.\n * @param {?string=} opt_postBody The optional POST body content.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.finishPopupAndRedirectSignIn =\n function(requestUri, sessionId, tenantId, opt_postBody) {\n var self = this;\n // Verify assertion request.\n var request = {\n 'requestUri': requestUri,\n 'postBody': opt_postBody,\n 'sessionId': sessionId,\n // Even if tenant ID is null, still pass it to RPC handler explicitly so\n // that it won't be overridden by RPC handler's tenant ID.\n 'tenantId': tenantId\n };\n // Now that popup has responded, delete popup timeout promise.\n if (this.popupTimeoutPromise_) {\n this.popupTimeoutPromise_.cancel();\n this.popupTimeoutPromise_ = null;\n }\n // When state is ready, run verify assertion request.\n // This will only run either after initial and redirect state is ready for\n // popups or after initial state is ready for redirect resolution.\n return self.authStateLoaded_.then(function() {\n return self.signInWithIdTokenProvider_(\n self.rpcHandler_.verifyAssertion(request));\n });\n};\n\n\n/**\n * @return {string} The generated event ID used to identify a popup event.\n * @private\n */\nfireauth.Auth.prototype.generateEventId_ = function() {\n return fireauth.util.generateEventId();\n};\n\n\n/**\n * Signs in to Auth provider via popup.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithPopup = function(provider) {\n // Check if popup and redirect are supported in this environment.\n if (!fireauth.util.isPopupRedirectSupported()) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n }\n var mode = fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP;\n var self = this;\n // Popup the window immediately to make sure the browser associates the\n // popup with the click that triggered it.\n\n // Get provider settings.\n var settings = fireauth.idp.getIdpSettings(provider['providerId']);\n // There could multiple sign in with popup events in different windows.\n // We need to match the correct popup to the correct pending promise.\n var eventId = this.generateEventId_();\n // If incapable of redirecting popup from opener, popup destination URL\n // directly. This could also happen in a sandboxed iframe.\n var oauthHelperWidgetUrl = null;\n if ((!fireauth.util.runsInBackground() || fireauth.util.isIframe()) &&\n this.app_().options['authDomain'] &&\n provider['isOAuthProvider']) {\n oauthHelperWidgetUrl =\n fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n this.app_().options['authDomain'],\n this.app_().options['apiKey'],\n this.app_().name,\n mode,\n provider,\n null,\n eventId,\n firebase.SDK_VERSION || null,\n null,\n null,\n this.getTenantId());\n }\n // The popup must have a name, otherwise when successive popups are triggered\n // they will all render in the same instance and none will succeed since the\n // popup cancel of first window will close the shared popup window instance.\n var popupWin =\n fireauth.util.popup(\n oauthHelperWidgetUrl,\n fireauth.util.generateRandomString(),\n settings && settings.popupWidth,\n settings && settings.popupHeight);\n // Auth event manager must be available for popup sign in to be possible.\n var p = this.getAuthEventManager_().then(function(manager) {\n // Process popup request tagging it with newly created event ID.\n return manager.processPopup(\n popupWin, mode, provider, eventId, !!oauthHelperWidgetUrl,\n self.getTenantId());\n }).then(function() {\n return new goog.Promise(function(resolve, reject) {\n // Expire other pending promises if still available..\n self.resolvePendingPopupEvent(\n mode,\n null,\n new fireauth.AuthError(fireauth.authenum.Error.EXPIRED_POPUP_REQUEST),\n // Existing pending popup event ID.\n self.popupEventId_);\n // Save current pending promises.\n self.pendingPopupResolvePromise_ = resolve;\n self.pendingPopupRejectPromise_ = reject;\n // Overwrite popup event ID with new one corresponding to popup.\n self.popupEventId_ = eventId;\n // Keep track of timeout promise to cancel it on promise resolution before\n // it times out.\n self.popupTimeoutPromise_ =\n self.authEventManager_.startPopupTimeout(\n self, mode, /** @type {!Window} */ (popupWin), eventId);\n });\n }).then(function(result) {\n // On resolution, close popup if still opened and pass result through.\n if (popupWin) {\n fireauth.util.closeWindow(popupWin);\n }\n if (result) {\n return fireauth.object.makeReadonlyCopy(result);\n }\n return null;\n }).thenCatch(function(error) {\n if (popupWin) {\n fireauth.util.closeWindow(popupWin);\n }\n throw error;\n });\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(p));\n};\n\n\n/**\n * Signs in to Auth provider via redirect.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.signInWithRedirect = function(provider) {\n // Check if popup and redirect are supported in this environment.\n if (!fireauth.util.isPopupRedirectSupported()) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n }\n var self = this;\n var mode = fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT;\n // Auth event manager must be available for sign in via redirect to be\n // possible.\n var p = this.getAuthEventManager_().then(function(manager) {\n // Remember current persistence to apply it on the next page.\n // This is the only time the state is passed to the next page (when user is\n // not already logged in).\n // This is not needed for link and reauthenticate as the user is already\n // stored with specified persistence.\n return self.userStorageManager_.savePersistenceForRedirect();\n }).then(function() {\n // Process redirect operation.\n return self.authEventManager_.processRedirect(\n mode, provider, undefined, self.getTenantId());\n });\n return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(p));\n};\n\n\n/**\n * Returns the redirect result. If coming back from a successful redirect sign\n * in, will resolve to the signed in user. If coming back from an unsuccessful\n * redirect sign, will reject with the proper error. If no redirect operation\n * called, resolves with null.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @private\n */\nfireauth.Auth.prototype.getRedirectResultWithoutClearing_ = function() {\n // Check if popup and redirect are supported in this environment.\n if (!fireauth.util.isPopupRedirectSupported()) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n }\n var self = this;\n // Auth event manager must be available for get redirect result to be\n // possible.\n var p = this.getAuthEventManager_().then(function(manager) {\n // Return redirect result when resolved.\n return self.authEventManager_.getRedirectResult();\n }).then(function(result) {\n if (result) {\n return fireauth.object.makeReadonlyCopy(result);\n }\n return null;\n });\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(p));\n};\n\n\n/**\n * In addition to returning the redirect result as in\n * `getRedirectResultWithoutClearing_`, this will also clear the cached\n * redirect result for security reasons.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.getRedirectResult = function() {\n return this.getRedirectResultWithoutClearing_()\n .then((result) => {\n if (this.authEventManager_) {\n this.authEventManager_.clearRedirectResult();\n }\n return result;\n })\n .thenCatch((error) => {\n if (this.authEventManager_) {\n this.authEventManager_.clearRedirectResult();\n }\n throw error;\n });\n};\n\n\n/**\n * Asynchronously sets the provided user as currentUser on the current Auth\n * instance.\n * @param {?fireauth.AuthUser} user The user to be copied to Auth instance.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.updateCurrentUser = function(user) {\n if (!user) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.NULL_USER));\n }\n if (this.tenantId_ != user['tenantId']) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.TENANT_ID_MISMATCH));\n }\n var self = this;\n var options = {};\n options['apiKey'] = this.app_().options['apiKey'];\n options['authDomain'] = this.app_().options['authDomain'];\n options['appName'] = this.app_().name;\n var newUser = fireauth.AuthUser.copyUser(user, options,\n self.redirectUserStorageManager_, self.getFramework());\n return this.registerPendingPromise_(\n this.redirectStateIsReady_.then(function() {\n if (self.app_().options['apiKey'] != user.getApiKey()) {\n // Throws auth/invalid-user-token if user doesn't belong to app.\n // Throws auth/user-token-expired if token expires.\n return newUser.reload();\n }\n }).then(function() {\n if (self.currentUser_() && user['uid'] == self.currentUser_()['uid']) {\n // Same user signed in. Update user data and notify Auth listeners.\n // No need to resubscribe to user events.\n // TODO: Check if the user to copy is older than current user and skip\n // the copy logic in that case.\n self.currentUser_().copy(user);\n return self.handleUserStateChange_(user);\n }\n self.setCurrentUser_(newUser);\n // Enable popup and redirect events.\n newUser.enablePopupRedirect();\n // Save user changes.\n return self.handleUserStateChange_(newUser);\n }).then(function(user) {\n self.notifyAuthListeners_();\n }));\n};\n\n\n/**\n * Completes the headless sign in with the server response containing the STS\n * access and refresh tokens, and sets the Auth user as current user while\n * setting all listeners to it and saving it to storage.\n * @param {!Object<string, string>} idTokenResponse The ID token response from\n * the server.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.signInWithIdTokenResponse =\n function(idTokenResponse) {\n var self = this;\n var options = {};\n options['apiKey'] = self.app_().options['apiKey'];\n options['authDomain'] = self.app_().options['authDomain'];\n options['appName'] = self.app_().name;\n // Wait for state to be ready.\n // This is used internally and is also used for redirect sign in so there is\n // no need for waiting for redirect result to resolve since redirect result\n // depends on it.\n return this.authStateLoaded_.then(function() {\n // Initialize an Auth user using the provided ID token response.\n return fireauth.AuthUser.initializeFromIdTokenResponse(\n options,\n idTokenResponse,\n /** @type {!fireauth.storage.RedirectUserManager} */ (\n self.redirectUserStorageManager_),\n // Pass frameworks so they are logged in getAccountInfo while populating\n // the user info.\n self.getFramework());\n }).then(function(user) {\n // Check if the same user is already signed in.\n if (self.currentUser_() &&\n user['uid'] == self.currentUser_()['uid']) {\n // Same user signed in. Update user data and notify Auth listeners.\n // No need to resubscribe to user events.\n self.currentUser_().copy(user);\n return self.handleUserStateChange_(user);\n }\n // New user.\n // Set current user and attach all listeners to it.\n self.setCurrentUser_(user);\n // Enable popup and redirect events.\n user.enablePopupRedirect();\n // Save user changes.\n return self.handleUserStateChange_(user);\n }).then(function() {\n // Notify external Auth listeners only when state is ready.\n self.notifyAuthListeners_();\n });\n};\n\n\n/**\n * Updates the current auth user and attaches event listeners to changes on it.\n * Also removes all event listeners from previously signed in user.\n * @param {?fireauth.AuthUser} user The current user instance.\n * @private\n */\nfireauth.Auth.prototype.setCurrentUser_ = function(user) {\n // Must be called first before updating currentUser reference.\n this.attachEventListeners_(user);\n // Update currentUser property.\n fireauth.object.setReadonlyProperty(this, 'currentUser', user);\n if (user) {\n // If a user is available, set the language code on it and set current Auth\n // instance as language code change dispatcher.\n this.setUserLanguage_(user);\n // Set the current frameworks used on the user and set current Auth instance\n // as the framework change dispatcher.\n this.setUserFramework_(user);\n }\n};\n\n\n/**\n * Signs out the current user while deleting the Auth user from storage and\n * removing all listeners from it.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.signOut = function() {\n var self = this;\n // Wait for final state to be ready first, otherwise a signed out user could\n // come back to life.\n var p = this.redirectStateIsReady_.then(function() {\n // Clear any cached redirect result on sign out, even if user is already\n // signed out. For example, sign in could fail due to account conflict\n // error, the error in redirect result should still be cleared. There is\n // also the use case where you keep a reference to a signed out user and\n // call signedOutUser.linkWithRedirect(provider). Even though the user is\n // signed out, getRedirectResult() will resolve with the modified signed\n // out user. This could also throw an error\n // (provider already linked, etc).\n if (self.authEventManager_) {\n self.authEventManager_.clearRedirectResult();\n }\n // Ignore if already signed out.\n if (!self.currentUser_()) {\n return goog.Promise.resolve();\n }\n // Detach all event listeners.\n // Set current user to null.\n self.setCurrentUser_(null);\n // Remove current user from storage\n return /** @type {!fireauth.storage.UserManager} */ (\n self.userStorageManager_).removeCurrentUser()\n .then(function() {\n // Notify external Auth listeners of this Auth change event.\n self.notifyAuthListeners_();\n });\n });\n return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(p));\n};\n\n\n/**\n * @return {!goog.Promise} A promise that resolved when any stored redirect user\n * is loaded and removed from session storage and then stored locally.\n * @private\n */\nfireauth.Auth.prototype.initRedirectUser_ = function() {\n var self = this;\n var authDomain = this.app_().options['authDomain'];\n // Get any saved redirect user and delete from session storage.\n // Override user's authDomain with app's authDomain if there is a mismatch.\n var p = /** @type {!fireauth.storage.RedirectUserManager} */ (\n this.redirectUserStorageManager_).getRedirectUser(authDomain)\n .then(function(user) {\n // Save redirect user.\n self.redirectUser_ = user;\n if (user) {\n // Set redirect storage manager on user.\n user.setRedirectStorageManager(\n /** @type {!fireauth.storage.RedirectUserManager} */ (\n self.redirectUserStorageManager_));\n }\n // Delete redirect user.\n return /** @type {!fireauth.storage.RedirectUserManager} */ (\n self.redirectUserStorageManager_).removeRedirectUser();\n });\n return /** @type {!goog.Promise<undefined>} */ (\n this.registerPendingPromise_(p));\n};\n\n\n/**\n * Loads the initial Auth state for current application from web storage and\n * initializes Auth user accordingly to reflect that state. This routine does\n * not wait for any pending redirect result to be resolved.\n * @return {!goog.Promise<undefined>} Promise that resolves when state is ready,\n * loaded from storage.\n * @private\n */\nfireauth.Auth.prototype.initAuthState_ = function() {\n // Load current user from storage.\n var self = this;\n var authDomain = this.app_().options['authDomain'];\n // Get any saved redirected user first.\n var p = this.initRedirectUser_().then(function() {\n // Override user's authDomain with app's authDomain if there is a mismatch.\n return /** @type {!fireauth.storage.UserManager} */ (\n self.userStorageManager_).getCurrentUser(authDomain);\n }).then(function(user) {\n // Logged in user.\n if (user) {\n // Set redirect storage manager on user.\n user.setRedirectStorageManager(\n /** @type {!fireauth.storage.RedirectUserManager} */ (\n self.redirectUserStorageManager_));\n // If the current user is undergoing a redirect operation, do not reload\n // as that could could potentially delete the user if the token is\n // expired. Instead any token problems will be detected via the\n // verifyAssertion flow or the remaining flow. This is critical for\n // reauthenticateWithRedirect as this flow is potentially used to recover\n // from a token expiration error.\n if (self.redirectUser_ &&\n self.redirectUser_.getRedirectEventId() ==\n user.getRedirectEventId()) {\n return user;\n }\n // Confirm user valid first before setting listeners.\n return user.reload().then(function() {\n // Force user saving after reload as state change listeners not\n // subscribed yet below via setCurrentUser_. Changes may have happened\n // externally such as email actions or changes on another device.\n return self.userStorageManager_.setCurrentUser(user).then(function() {\n return user;\n });\n }).thenCatch(function(error) {\n if (error['code'] == 'auth/network-request-failed') {\n // Do not delete the user from storage if connection is lost or app is\n // offline.\n return user;\n }\n // Invalid user, could be deleted, remove from storage and resolve with\n // null.\n return /** @type {!fireauth.storage.UserManager} */(\n self.userStorageManager_).removeCurrentUser();\n });\n }\n // No logged in user, resolve with null;\n return null;\n }).then(function(user) {\n // Even though state not ready yet pending any redirect result.\n // Current user needs to be available for link with redirect to complete.\n // This will also set listener on the user changes in case state changes\n // occur they would get updated in storage too.\n self.setCurrentUser_(user || null);\n });\n // In case the app is deleted before it is initialized with state from\n // storage.\n return /** @type {!goog.Promise<undefined>} */ (\n this.registerPendingPromise_(p));\n};\n\n\n/**\n * After initial Auth state is loaded, waits for any pending redirect result,\n * resolves it and then adds the external Auth state change listeners and\n * triggers first state of all observers.\n * @return {!goog.Promise<undefined>} Promise that resolves when state is ready\n * taking into account any pending redirect result.\n * @private\n */\nfireauth.Auth.prototype.initAuthRedirectState_ = function() {\n var self = this;\n // Wait first for state to be loaded from storage.\n return this.authStateLoaded_.then(function() {\n // Resolve any pending redirect result.\n return self.getRedirectResultWithoutClearing_();\n }).thenCatch(function(error) {\n // Ignore any error in the process. Redirect could be not supported.\n return;\n }).then(function() {\n // Make sure instance was not deleted before proceeding.\n if (self.deleted_) {\n return;\n }\n // Between init Auth state and get redirect result resolution there\n // could have been a sign in attempt in another window.\n // Force sync and then add listener to run sync on change below.\n return self.getSyncAuthUserChanges_();\n }).thenCatch(function(error) {\n // Ignore any error in the process.\n return;\n }).then(function() {\n // Now that final state is ready, make sure instance was not deleted before\n // proceeding.\n if (self.deleted_) {\n return;\n }\n // Initial state has been resolved.\n self.isStateResolved_ = true;\n // Add user state change listener so changes are synchronized with\n // other windows and tabs.\n /** @type {!fireauth.storage.UserManager} */ (self.userStorageManager_\n ).addCurrentUserChangeListener(self.getSyncAuthUserChanges_);\n });\n};\n\n\n/**\n * Synchronizes current Auth to stored auth state, used when external state\n * changes occur.\n * @return {!goog.Promise<void>}\n * @private\n */\nfireauth.Auth.prototype.syncAuthUserChanges_ = function() {\n // Get Auth user state from storage and compare to current state.\n // Safe to run when no external change is detected.\n var self = this;\n var authDomain = this.app_().options['authDomain'];\n // Override user's authDomain with app's authDomain if there is a mismatch.\n return /** @type {!fireauth.storage.UserManager} */ (\n this.userStorageManager_).getCurrentUser(authDomain)\n .then(function(user) {\n // In case this was deleted.\n if (self.deleted_) {\n return;\n }\n // Since the authDomain could be modified here, saving to storage here\n // could trigger an infinite loop of changes between this tab and\n // another tab using different Auth domain but since sync Auth user\n // changes does not save changes to storage, except for getToken below\n // if the token needs refreshing but will stop triggering the first time\n // the token is refreshed on one of the first tab that refreshes it.\n // The latter should not happen anyway since getToken should be valid\n // at all times since anything that triggers the storage change should\n // have communicated with the backend and that requires a valid token.\n // In addition, authDomain difference is an edge case to begin with.\n\n // If the same user is to be synchronized.\n if (self.currentUser_() &&\n user &&\n self.currentUser_().hasSameUserIdAs(user)) {\n // Data update, simply copy data changes.\n self.currentUser_().copy(user);\n // If tokens changed from previous user tokens, this will trigger\n // notifyAuthListeners_.\n return self.currentUser_().getIdToken();\n } else if (!self.currentUser_() && !user) {\n // No change, do nothing (was signed out and remained signed out).\n return;\n } else {\n // Update current Auth state. Either a new login or logout.\n self.setCurrentUser_(user);\n // If a new user is signed in, enabled popup and redirect on that\n // user.\n if (user) {\n user.enablePopupRedirect();\n // Set redirect storage manager on user.\n user.setRedirectStorageManager(\n /** @type {!fireauth.storage.RedirectUserManager} */ (\n self.redirectUserStorageManager_));\n }\n if (self.authEventManager_) {\n self.authEventManager_.subscribe(self);\n }\n // Notify external Auth changes of Auth change event.\n self.notifyAuthListeners_();\n }\n });\n};\n\n\n/**\n * Updates the language code on the provided user and configures the user to\n * listen to the Auth instance for any language code changes.\n * @param {!fireauth.AuthUser} user The user to whose language needs to be set.\n * @private\n */\nfireauth.Auth.prototype.setUserLanguage_ = function(user) {\n // Sets the current language code on the user.\n user.setLanguageCode(this.getLanguageCode());\n // Sets current Auth instance as language code change dispatcher on the user.\n user.setLanguageCodeChangeDispatcher(this);\n};\n\n\n/**\n * Handles user state changes.\n * @param {!fireauth.AuthUser} user The user which triggered the state changes.\n * @return {!goog.Promise} The promise that resolves when state changes are\n * handled.\n * @private\n */\nfireauth.Auth.prototype.handleUserStateChange_ = function(user) {\n // Save Auth user state changes.\n return /** @type {!fireauth.storage.UserManager} */ (\n this.userStorageManager_).setCurrentUser(user);\n};\n\n\n/**\n * Handles user token changes.\n * @param {!Object} event The token change event.\n * @private\n */\nfireauth.Auth.prototype.handleUserTokenChange_ = function(event) {\n // This is only called when user is ready and Auth state has been resolved.\n // Notify external Auth change listeners.\n this.notifyAuthListeners_();\n // Save user token changes.\n this.handleUserStateChange_(/** @type {!fireauth.AuthUser} */ (\n this.currentUser_()));\n};\n\n\n/**\n * Handles user deletion events.\n * @param {!Object} event The user delete event.\n * @private\n */\nfireauth.Auth.prototype.handleUserDelete_ = function(event) {\n // A deleted user will be treated like a sign out event.\n this.signOut();\n};\n\n\n/**\n * Handles user invalidation events.\n * @param {!Object} event The user invalidation event.\n * @private\n */\nfireauth.Auth.prototype.handleUserInvalidated_ = function(event) {\n // An invalidated user will be treated like a sign out event.\n this.signOut();\n};\n\n\n/**\n * Detaches all previous listeners on current user and reattach new listeners to\n * provided user if not null.\n * @param {?fireauth.AuthUser} user The user to attach event listeners to.\n * @private\n */\nfireauth.Auth.prototype.attachEventListeners_ = function(user) {\n // Remove existing event listeners from previous current user if available.\n if (this.currentUser_()) {\n this.currentUser_().removeStateChangeListener(\n this.userStateChangeListener_);\n goog.events.unlisten(\n this.currentUser_(),\n fireauth.UserEventType.TOKEN_CHANGED,\n this.userTokenChangeListener_);\n goog.events.unlisten(\n this.currentUser_(),\n fireauth.UserEventType.USER_DELETED,\n this.userDeleteListener_);\n goog.events.unlisten(\n this.currentUser_(),\n fireauth.UserEventType.USER_INVALIDATED,\n this.userInvalidatedListener_);\n // Stop proactive token refresh on the current user.\n this.currentUser_().stopProactiveRefresh();\n }\n // If a new user is provided, attach event listeners to state, token, user\n // invalidation and delete events.\n if (user) {\n user.addStateChangeListener(this.userStateChangeListener_);\n goog.events.listen(\n user,\n fireauth.UserEventType.TOKEN_CHANGED,\n this.userTokenChangeListener_);\n goog.events.listen(\n user,\n fireauth.UserEventType.USER_DELETED,\n this.userDeleteListener_);\n goog.events.listen(\n user,\n fireauth.UserEventType.USER_INVALIDATED,\n this.userInvalidatedListener_);\n // Start proactive token refresh on new user if there is at least one\n // Firebase service subscribed to Auth changes.\n if (this.firebaseServices_ > 0) {\n user.startProactiveRefresh();\n }\n }\n};\n\n\n/**\n * Signs in with ID token promise provider.\n * @param {!goog.Promise<!Object>} idTokenPromise\n * The rpc handler method that returns a promise which resolves with an ID\n * token.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @private\n */\nfireauth.Auth.prototype.signInWithIdTokenProvider_ = function(idTokenPromise) {\n var self = this;\n var credential = null;\n var additionalUserInfo = null;\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(\n idTokenPromise\n .then(function(idTokenResponse) {\n // Get credential if available in the response.\n credential = fireauth.AuthProvider.getCredentialFromResponse(\n idTokenResponse);\n // Get additional IdP data if available in the response.\n additionalUserInfo = fireauth.AdditionalUserInfo.fromPlainObject(\n idTokenResponse);\n // When custom token is exchanged for idToken, continue sign in with\n // ID token and return firebase Auth user.\n return self.signInWithIdTokenResponse(idTokenResponse);\n }, function(error) {\n // Catch the MFA_REQUIRED error rejected in ID token promise and\n // repackage it into a multi-factor error with additional IdP data\n // if available.\n var multiFactorError = null;\n if (error && error['code'] === 'auth/multi-factor-auth-required') {\n multiFactorError = fireauth.MultiFactorError.fromPlainObject(\n error.toPlainObject(),\n self,\n goog.bind(self.handleMultiFactorIdTokenResolver_, self));\n }\n throw multiFactorError || error;\n })\n .then(function() {\n // Resolve promise with a readonly user credential object.\n return fireauth.object.makeReadonlyCopy({\n // Return the current user reference.\n 'user': self.currentUser_(),\n // Return any credential passed from the backend.\n 'credential': credential,\n // Return any additional IdP data passed from the backend.\n 'additionalUserInfo': additionalUserInfo,\n // Sign in operation type.\n 'operationType': fireauth.constants.OperationType.SIGN_IN\n });\n })));\n};\n\n\n/**\n * Completes multi-factor sign-in with ID token response and additional IdP data\n * if available.\n * @param {{idToken: string, refreshToken: string}} response The successful\n * sign-in response containing the new ID tokens.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>} A Promise that\n * resolves with the updated `UserCredential`.\n * @private\n */\nfireauth.Auth.prototype.handleMultiFactorIdTokenResolver_ =\n function(response) {\n var self = this;\n // Wait for state to be ready and then finish sign-in.\n return this.redirectStateIsReady_.then(function() {\n return self.signInWithIdTokenProvider_(goog.Promise.resolve(response));\n });\n};\n\n\n/**\n * Initializes the Auth state change observer returned by the\n * firebase.INTERNAL.createSubscribe helper.\n * @param {!firebase.Observer} observer The Auth state change observer.\n * @private\n */\nfireauth.Auth.prototype.initIdTokenChangeObserver_ = function(observer) {\n var self = this;\n // Adds a listener that will transmit the event everytime it's called.\n this.addAuthTokenListener(function(accessToken) {\n observer.next(self.currentUser_());\n });\n};\n\n\n/**\n * Initializes the user state change observer returned by the\n * firebase.INTERNAL.createSubscribe helper.\n * @param {!firebase.Observer} observer The user state change observer.\n * @private\n */\nfireauth.Auth.prototype.initUserStateObserver_ = function(observer) {\n var self = this;\n // Adds a listener that will transmit the event everytime it's called.\n this.addUserChangeListener_(function(accessToken) {\n observer.next(self.currentUser_());\n });\n};\n\n\n/**\n * Adds an observer for Auth state changes, we need to wrap the call as\n * the args checking code needs a method defined on the prototype this way,\n * not within the constructor, and we also have to implement the behavior\n * that will trigger an observer right away if state is ready.\n * @param {!firebase.Observer|function(?fireauth.AuthUser)}\n * nextOrObserver An observer object or a function triggered on change.\n * @param {function(!fireauth.AuthError)=} opt_error Optional A function\n * triggered on Auth error.\n * @param {function()=} opt_completed Optional A function triggered when the\n * observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\nfireauth.Auth.prototype.onIdTokenChanged = function(\n nextOrObserver, opt_error, opt_completed) {\n var self = this;\n // State already determined. Trigger immediately, otherwise initState will\n // take care of notifying all pending listeners on initialization.\n // In this case we do not trigger synchronously and trigger via a resolved\n // promise as required by specs.\n if (this.isStateResolved_) {\n // The observer cannot be called synchronously. We're using the\n // native Promise implementation as otherwise it creates weird behavior\n // where the order of promises resolution would not be as expected.\n // It is due to the fact fireauth and firebase.app use their own\n // and different promises library and this leads to calls resolutions order\n // being different from the promises registration order.\n Promise.resolve().then(function() {\n if (goog.isFunction(nextOrObserver)) {\n nextOrObserver(self.currentUser_());\n } else if (goog.isFunction(nextOrObserver['next'])) {\n nextOrObserver['next'](self.currentUser_());\n }\n });\n }\n return this.onIdTokenChanged_(\n /** @type {!firebase.Observer|function(*)|undefined} */ (nextOrObserver),\n /** @type {function(!Error)|undefined} */ (opt_error),\n opt_completed);\n};\n\n\n/**\n * Adds an observer for user state changes, we need to wrap the call as\n * the args checking code needs a method defined on the prototype this way,\n * not within the constructor, and we also have to implement the behavior\n * that will trigger an observer right away if state is ready.\n * @param {!firebase.Observer|function(?fireauth.AuthUser)}\n * nextOrObserver An observer object or a function triggered on change.\n * @param {function(!fireauth.AuthError)=} opt_error Optional A function\n * triggered on Auth error.\n * @param {function()=} opt_completed Optional A function triggered when the\n * observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\nfireauth.Auth.prototype.onAuthStateChanged = function(\n nextOrObserver, opt_error, opt_completed) {\n var self = this;\n // State already determined. Trigger immediately, otherwise initState will\n // take care of notifying all pending listeners on initialization.\n // In this case we do not trigger synchronously and trigger via a resolved\n // promise as required by specs.\n if (this.isStateResolved_) {\n // The observer cannot be called synchronously. We're using the\n // native Promise implementation as otherwise it creates weird behavior\n // where the order of promises resolution would not be as expected.\n // It is due to the fact fireauth and firebase.app use their own\n // and different promises library and this leads to calls resolutions order\n // being different from the promises registration order.\n Promise.resolve().then(function() {\n // This ensures that the first time notifyAuthListeners_ is triggered,\n // it has the correct UID before triggering the user state change\n // listeners.\n self.userStateChangeUid_ = self.getUid();\n if (goog.isFunction(nextOrObserver)) {\n nextOrObserver(self.currentUser_());\n } else if (goog.isFunction(nextOrObserver['next'])) {\n nextOrObserver['next'](self.currentUser_());\n }\n });\n }\n return this.onUserStateChanged_(\n /** @type {!firebase.Observer|function(*)|undefined} */ (nextOrObserver),\n /** @type {function(!Error)|undefined} */ (opt_error),\n opt_completed);\n};\n\n\n/**\n * Returns an STS token. If the cached one is unexpired it is directly returned.\n * Otherwise the existing ID token or refresh token is exchanged for a new one.\n * If there is no user signed in, returns null.\n *\n * This method is called getIdTokenInternal as the symbol getIdToken is not\n * obfuscated, which could lead to developers incorrectly calling\n * firebase.auth().getIdToken().\n *\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<?Object>}\n */\nfireauth.Auth.prototype.getIdTokenInternal = function(opt_forceRefresh) {\n var self = this;\n // Wait for state to be ready.\n var p = this.redirectStateIsReady_.then(function() {\n // Call user's underlying getIdToken method.\n if (self.currentUser_()) {\n return self.currentUser_().getIdToken(opt_forceRefresh)\n .then(function(stsAccessToken) {\n // This is used internally by other services which expect the access\n // token to be returned in an object.\n return {\n 'accessToken': stsAccessToken\n };\n });\n }\n // No logged in user, return null token.\n return null;\n });\n return /** @type {!goog.Promise<?Object>} */ (\n this.registerPendingPromise_(p));\n};\n\n\n/**\n * Signs in a user asynchronously using a custom token and returns any\n * additional user info data or credentials returned form the backend.\n * @param {string} token The custom token to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithCustomToken = function(token) {\n var self = this;\n // Wait for the redirect state to be determined before proceeding. If critical\n // errors like web storage unsupported are detected, fail before RPC, instead\n // of after.\n return this.redirectStateIsReady_.then(function() {\n return self.signInWithIdTokenProvider_(\n self.getRpcHandler().verifyCustomToken(token));\n }).then(function(result) {\n var user = result['user'];\n // Manually sets the isAnonymous flag to false as the GetAccountInfo\n // response will look like an anonymous user (no credentials visible).\n user.updateProperty('isAnonymous', false);\n // Save isAnonymous flag changes to current user in storage.\n self.handleUserStateChange_(user);\n return result;\n });\n};\n\n\n/**\n * Sign in using an email and password and returns any additional user info\n * data or credentials returned form the backend.\n * @param {string} email The email to sign in with.\n * @param {string} password The password to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithEmailAndPassword =\n function(email, password) {\n var self = this;\n // Wait for the redirect state to be determined before proceeding. If critical\n // errors like web storage unsupported are detected, fail before RPC, instead\n // of after.\n return this.redirectStateIsReady_.then(function() {\n return self.signInWithIdTokenProvider_(\n self.getRpcHandler().verifyPassword(email, password));\n });\n};\n\n\n/**\n * Creates a new email and password account and returns any additional user\n * info data or credentials returned form the backend.\n * @param {string} email The email to sign up with.\n * @param {string} password The password to sign up with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.createUserWithEmailAndPassword =\n function(email, password) {\n var self = this;\n // Wait for the redirect state to be determined before proceeding. If critical\n // errors like web storage unsupported are detected, fail before RPC, instead\n // of after.\n return this.redirectStateIsReady_.then(function() {\n return self.signInWithIdTokenProvider_(\n self.getRpcHandler().createAccount(email, password));\n });\n};\n\n\n/**\n * Logs into Firebase with the given 3rd party credentials and returns any\n * additional user info data or credentials returned form the backend.\n * @param {!fireauth.AuthCredential} credential The Auth credential.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithCredential = function(credential) {\n // Credential could be extended in the future, so leave it to credential to\n // decide how to retrieve ID token.\n var self = this;\n // Wait for the redirect state to be determined before proceeding. If critical\n // errors like web storage unsupported are detected, fail before RPC, instead\n // of after.\n return this.redirectStateIsReady_.then(function() {\n // Return the full response object and not just the user.\n return self.signInWithIdTokenProvider_(\n credential.getIdTokenProvider(self.getRpcHandler()));\n });\n};\n\n\n/**\n * Logs into Firebase with the given 3rd party credentials and returns any\n * additional user info data or credentials returned form the backend. It has\n * been deprecated in favor of signInWithCredential.\n * @param {!fireauth.AuthCredential} credential The Auth credential.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInAndRetrieveDataWithCredential =\n function(credential) {\n fireauth.deprecation.log(\n fireauth.deprecation.Deprecations.SIGN_IN_WITH_CREDENTIAL);\n return this.signInWithCredential(credential);\n};\n\n\n/**\n * Signs in a user anonymously and returns any additional user info data or\n * credentials returned form the backend.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInAnonymously = function() {\n var self = this;\n // Wait for the redirect state to be determined before proceeding. If critical\n // errors like web storage unsupported are detected, fail before RPC, instead\n // of after.\n return this.redirectStateIsReady_.then(function() {\n var user = self.currentUser_();\n // If an anonymous user is already signed in, no need to sign him again.\n if (user && user['isAnonymous']) {\n var additionalUserInfo = fireauth.object.makeReadonlyCopy({\n 'providerId': null,\n 'isNewUser': false\n });\n return fireauth.object.makeReadonlyCopy({\n // Return the signed in user reference.\n 'user': user,\n // Do not return credential for anonymous user.\n 'credential': null,\n // Return any additional IdP data.\n 'additionalUserInfo': additionalUserInfo,\n // Sign in operation type.\n 'operationType': fireauth.constants.OperationType.SIGN_IN\n });\n } else {\n // No anonymous user currently signed in.\n return self.signInWithIdTokenProvider_(\n self.getRpcHandler().signInAnonymously())\n .then(function(result) {\n var user = result['user'];\n // Manually sets the isAnonymous flag to true as\n // initializeFromIdTokenResponse uses the default value of false and\n // even though getAccountInfo sets that to true, it will be reverted\n // to false in reloadWithoutSaving.\n // TODO: consider optimizing this and cleaning these manual\n // overwrites.\n user.updateProperty('isAnonymous', true);\n // Save isAnonymous flag changes to current user in storage.\n self.handleUserStateChange_(user);\n return result;\n });\n }\n });\n};\n\n\n/**\n * @return {string} The key used for storing Auth state.\n */\nfireauth.Auth.prototype.getStorageKey = function() {\n return fireauth.util.createStorageKey(\n this.app_().options['apiKey'],\n this.app_().name);\n};\n\n\n/**\n * @return {!firebase.app.App} The Firebase App this auth object is connected\n * to.\n * @private\n */\nfireauth.Auth.prototype.app_ = function() {\n return this['app'];\n};\n\n\n/**\n * @return {!fireauth.RpcHandler} The RPC handler.\n */\nfireauth.Auth.prototype.getRpcHandler = function() {\n return this.rpcHandler_;\n};\n\n\n/**\n * @return {?fireauth.AuthUser} The currently logged in user.\n * @private\n */\nfireauth.Auth.prototype.currentUser_ = function() {\n return this['currentUser'];\n};\n\n\n/** @return {?string} The current user UID if available, null if not. */\nfireauth.Auth.prototype.getUid = function() {\n return (this.currentUser_() && this.currentUser_()['uid']) || null;\n};\n\n\n/**\n * @return {?string} The last cached access token.\n * @private\n */\nfireauth.Auth.prototype.getLastAccessToken_ = function() {\n return (this.currentUser_() && this.currentUser_()['_lat']) || null;\n};\n\n\n\n/**\n * Called internally on Auth state change to notify listeners.\n * @private\n */\nfireauth.Auth.prototype.notifyAuthListeners_ = function() {\n // Only run when state is resolved. After state is resolved, the Auth listener\n // will always trigger.\n if (this.isStateResolved_) {\n for (var i = 0; i < this.authListeners_.length; i++) {\n if (this.authListeners_[i]) {\n this.authListeners_[i](this.getLastAccessToken_());\n }\n }\n // Trigger user change only if UID changed.\n if (this.userStateChangeUid_ !== this.getUid() &&\n this.userChangeListeners_.length) {\n // Update user state change UID.\n this.userStateChangeUid_ = this.getUid();\n // Trigger all subscribed user state change listeners.\n for (var i = 0; i < this.userChangeListeners_.length; i++) {\n if (this.userChangeListeners_[i]) {\n this.userChangeListeners_[i](this.getLastAccessToken_());\n }\n }\n }\n }\n};\n\n\n/**\n * Attaches a listener function to Auth state change.\n * This is used only by internal Firebase services.\n * @param {!function(?string)} listener The auth state change listener.\n */\nfireauth.Auth.prototype.addAuthTokenListenerInternal = function(listener) {\n this.addAuthTokenListener(listener);\n // This is not exact science but should be good enough to detect Firebase\n // services subscribing to Auth token changes.\n // This is needed to start proactive token refresh on a user.\n this.firebaseServices_++;\n if (this.firebaseServices_ > 0 && this.currentUser_()) {\n // Start proactive token refresh on the current user.\n this.currentUser_().startProactiveRefresh();\n }\n};\n\n\n/**\n * Detaches the provided listener from Auth state change event.\n * This is used only by internal Firebase services.\n * @param {!function(?string)} listener The Auth state change listener.\n */\nfireauth.Auth.prototype.removeAuthTokenListenerInternal = function(listener) {\n // This is unlikely to be called by Firebase services. Services are unlikely\n // to remove Auth token listeners.\n // Make sure listener is still subscribed before decrementing.\n var self = this;\n goog.array.forEach(this.authListeners_, function(ele) {\n // This covers the case where the same listener is subscribed more than\n // once.\n if (ele == listener) {\n self.firebaseServices_--;\n }\n });\n if (this.firebaseServices_ < 0) {\n this.firebaseServices_ = 0;\n }\n if (this.firebaseServices_ == 0 && this.currentUser_()) {\n // Stop proactive token refresh on the current user.\n this.currentUser_().stopProactiveRefresh();\n }\n this.removeAuthTokenListener(listener);\n};\n\n\n/**\n * Attaches a listener function to Auth state change.\n * @param {!function(?string)} listener The Auth state change listener.\n */\nfireauth.Auth.prototype.addAuthTokenListener = function(listener) {\n var self = this;\n // Save listener.\n this.authListeners_.push(listener);\n // Make sure redirect state is ready and then trigger listener.\n this.registerPendingPromise_(this.redirectStateIsReady_.then(function() {\n // Do nothing if deleted.\n if (self.deleted_) {\n return;\n }\n // Make sure listener is still subscribed.\n if (goog.array.contains(self.authListeners_, listener)) {\n // Trigger the first call for this now that redirect state is resolved.\n listener(self.getLastAccessToken_());\n }\n }));\n};\n\n\n/**\n * Detaches the provided listener from Auth state change event.\n * @param {!function(?string)} listener The Auth state change listener.\n */\nfireauth.Auth.prototype.removeAuthTokenListener = function(listener) {\n // Remove from Auth listeners.\n goog.array.removeAllIf(this.authListeners_, function(ele) {\n return ele == listener;\n });\n};\n\n\n/**\n * Attaches a listener function to user state change.\n * @param {!function(?string)} listener The user state change listener.\n * @private\n */\nfireauth.Auth.prototype.addUserChangeListener_ = function(listener) {\n var self = this;\n // Save listener.\n this.userChangeListeners_.push(listener);\n // Make sure redirect state is ready and then trigger listener.\n this.registerPendingPromise_(this.redirectStateIsReady_.then(function() {\n // Do nothing if deleted.\n if (self.deleted_) {\n return;\n }\n // Make sure listener is still subscribed.\n if (goog.array.contains(self.userChangeListeners_, listener)) {\n // Confirm UID change before triggering.\n if (self.userStateChangeUid_ !== self.getUid()) {\n self.userStateChangeUid_ = self.getUid();\n // Trigger the first call for this now that redirect state is resolved.\n listener(self.getLastAccessToken_());\n }\n }\n }));\n};\n\n\n/**\n * Deletes the Auth instance, handling cancellation of all pending async Auth\n * operations.\n * @return {!Promise<void>}\n */\nfireauth.Auth.prototype.delete = function() {\n this.deleted_ = true;\n // Cancel all pending promises.\n for (var i = 0; i < this.pendingPromises_.length; i++) {\n this.pendingPromises_[i].cancel(fireauth.authenum.Error.MODULE_DESTROYED);\n }\n\n // Empty pending promises array.\n this.pendingPromises_ = [];\n // Remove current user change listener.\n if (this.userStorageManager_) {\n this.userStorageManager_.removeCurrentUserChangeListener(\n this.getSyncAuthUserChanges_);\n }\n // Unsubscribe from Auth event handling.\n if (this.authEventManager_) {\n this.authEventManager_.unsubscribe(this);\n this.authEventManager_.clearRedirectResult();\n }\n return Promise.resolve();\n};\n\n\n/** @return {boolean} Whether Auth instance has pending promises. */\nfireauth.Auth.prototype.hasPendingPromises = function() {\n return this.pendingPromises_.length != 0;\n};\n\n\n/**\n * Takes in a pending promise, saves it and adds a clean up callback which\n * forgets the pending promise after it is fulfilled and echoes the promise\n * back.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.Auth.prototype.registerPendingPromise_ = function(p) {\n var self = this;\n // Save created promise in pending list.\n this.pendingPromises_.push(p);\n p.thenAlways(function() {\n // When fulfilled, remove from pending list.\n goog.array.remove(self.pendingPromises_, p);\n });\n // Return the promise.\n return p;\n};\n\n\n/**\n * Gets the list of possible sign in methods for the given email address.\n * @param {string} email The email address.\n * @return {!goog.Promise<!Array<string>>}\n */\nfireauth.Auth.prototype.fetchSignInMethodsForEmail = function(email) {\n return /** @type {!goog.Promise<!Array<string>>} */ (\n this.registerPendingPromise_(\n this.getRpcHandler().fetchSignInMethodsForIdentifier(email)));\n};\n\n\n/**\n * @param {string} emailLink The email link.\n * @return {boolean} Whether the link is a sign in with email link.\n */\nfireauth.Auth.prototype.isSignInWithEmailLink = function(emailLink) {\n return !!fireauth.EmailAuthProvider\n .getActionCodeUrlFromSignInEmailLink(emailLink);\n};\n\n\n/**\n * Sends the sign-in with email link for the email account provided.\n * @param {string} email The email account to sign in with.\n * @param {!Object} actionCodeSettings The action code settings object.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.sendSignInLinkToEmail = function(\n email, actionCodeSettings) {\n var self = this;\n return this.registerPendingPromise_(\n // Wrap in promise as ActionCodeSettings constructor could throw a\n // synchronous error if invalid arguments are specified.\n goog.Promise.resolve()\n .then(function() {\n var actionCodeSettingsBuilder =\n new fireauth.ActionCodeSettings(actionCodeSettings);\n if (!actionCodeSettingsBuilder.canHandleCodeInApp()) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP +\n ' must be true when sending sign in link to email');\n }\n return actionCodeSettingsBuilder.buildRequest();\n }).then(function(additionalRequestData) {\n return self.getRpcHandler().sendSignInLinkToEmail(\n email, additionalRequestData);\n }).then(function(email) {\n // Do not return the email.\n }));\n};\n\n\n/**\n * Verifies an email action code for password reset and returns a promise\n * that resolves with the associated email if verified.\n * @param {string} code The email action code to verify for password reset.\n * @return {!goog.Promise<string>}\n */\nfireauth.Auth.prototype.verifyPasswordResetCode = function(code) {\n return this.checkActionCode(code).then(function(info) {\n return info['data']['email'];\n });\n};\n\n\n/**\n * Requests resetPassword endpoint for password reset, verifies the action code\n * and updates the new password, returns an empty promise.\n * @param {string} code The email action code to confirm for password reset.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<undefined, !fireauth.AuthError>}\n */\nfireauth.Auth.prototype.confirmPasswordReset = function(code, newPassword) {\n return this.registerPendingPromise_(\n this.getRpcHandler().confirmPasswordReset(code, newPassword)\n .then(function(email) {\n // Do not return the email.\n }));\n};\n\n\n/**\n * Verifies an email action code and returns an empty promise if verified.\n * @param {string} code The email action code to verify for password reset.\n * @return {!goog.Promise<!Object>}\n */\nfireauth.Auth.prototype.checkActionCode = function(code) {\n return this.registerPendingPromise_(\n this.getRpcHandler().checkActionCode(code)\n .then(function(response) {\n return new fireauth.ActionCodeInfo(response);\n }));\n};\n\n\n/**\n * Applies an out-of-band email action code, such as an email verification code.\n * @param {string} code The email action code.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.applyActionCode = function(code) {\n return this.registerPendingPromise_(\n this.getRpcHandler().applyActionCode(code)\n .then(function(email) {\n // Returns nothing.\n }));\n};\n\n\n/**\n * Sends the password reset email for the email account provided.\n * @param {string} email The email account with the password to be reset.\n * @param {?Object=} opt_actionCodeSettings The optional action code settings\n * object.\n * @return {!goog.Promise<void>}\n */\nfireauth.Auth.prototype.sendPasswordResetEmail =\n function(email, opt_actionCodeSettings) {\n var self = this;\n return this.registerPendingPromise_(\n // Wrap in promise as ActionCodeSettings constructor could throw a\n // synchronous error if invalid arguments are specified.\n goog.Promise.resolve().then(function() {\n if (typeof opt_actionCodeSettings !== 'undefined' &&\n // Ignore empty objects.\n !goog.object.isEmpty(opt_actionCodeSettings)) {\n return new fireauth.ActionCodeSettings(\n /** @type {!Object} */ (opt_actionCodeSettings)).buildRequest();\n }\n return {};\n })\n .then(function(additionalRequestData) {\n return self.getRpcHandler().sendPasswordResetEmail(\n email, additionalRequestData);\n }).then(function(email) {\n // Do not return the email.\n }));\n};\n\n\n/**\n * Signs in with a phone number using the app verifier instance and returns a\n * promise that resolves with the confirmation result which on confirmation\n * will resolve with the UserCredential object.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n * verifier.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.Auth.prototype.signInWithPhoneNumber =\n function(phoneNumber, appVerifier) {\n return /** @type {!goog.Promise<!fireauth.ConfirmationResult>} */ (\n this.registerPendingPromise_(fireauth.ConfirmationResult.initialize(\n this,\n phoneNumber,\n appVerifier,\n // This will wait for redirectStateIsReady to resolve first.\n goog.bind(this.signInWithCredential, this))));\n};\n\n\n/**\n * Signs in a Firebase User with the provided email and the passwordless\n * sign-in email link.\n * @param {string} email The email account to sign in with.\n * @param {?string=} opt_link The optional link which contains the OTP needed\n * to complete the sign in with email link. If not specified, the current\n * URL is used instead.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.Auth.prototype.signInWithEmailLink = function(email, opt_link) {\n return this.registerPendingPromise_(goog.Promise.resolve().then(() => {\n const link = opt_link || fireauth.util.getCurrentUrl();\n const credential = fireauth.EmailAuthProvider.credentialWithLink(\n email, link);\n // Check if the tenant ID in the email link matches the tenant ID on Auth\n // instance.\n const actionCodeUrl =\n fireauth.EmailAuthProvider.getActionCodeUrlFromSignInEmailLink(link);\n if (!actionCodeUrl) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!');\n }\n if (actionCodeUrl['tenantId'] !== this.getTenantId()) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.TENANT_ID_MISMATCH);\n }\n return this.signInWithCredential(credential);\n }));\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the Auth event object.\n */\n\ngoog.provide('fireauth.AuthEvent');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\n\n\n/**\n * Defines the authentication event.\n * @param {!fireauth.AuthEvent.Type} type The Auth event type.\n * @param {?string=} opt_eventId The event identifier.\n * @param {?string=} opt_urlResponse The URL with IdP response.\n * @param {?string=} opt_sessionId The session ID used to prevent session\n * fixation attacks.\n * @param {?fireauth.AuthError=} opt_error The optional error encountered.\n * @param {?string=} opt_postBody The optional POST body.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @constructor\n */\nfireauth.AuthEvent = function(\n type, opt_eventId, opt_urlResponse, opt_sessionId, opt_error,\n opt_postBody, opt_tenantId) {\n /** @const @private {!fireauth.AuthEvent.Type} The Auth event type. */\n this.type_ = type;\n /** @const @private {?string} The Auth event ID. */\n this.eventId_ = opt_eventId || null;\n /** @const @private {?string} The callback URL with the sign in response. */\n this.urlResponse_ = opt_urlResponse || null;\n /** @const @private {?string} The sign in operation session ID. */\n this.sessionId_ = opt_sessionId || null;\n /** @const @private {?string} The POST body string if available. */\n this.postBody_ = opt_postBody || null;\n /** @const @private {?string} The tenant ID if available. */\n this.tenantId_ = opt_tenantId || null;\n /**\n * @const @private {?fireauth.AuthError} The Auth event error if available.\n */\n this.error_ = opt_error || null;\n if (!this.urlResponse_ && !this.error_) {\n // Either URL or error is required. They can't be both null.\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n } else if (this.urlResponse_ && this.error_) {\n // An error must not be provided when a URL is available.\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n } else if (this.urlResponse_ && !this.sessionId_) {\n // A session ID must accompany a URL response.\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n }\n};\n\n\n\n/**\n * Auth event operation types.\n * All Auth event types that are used for popup operations should be suffixed\n * with `Popup`, whereas those used for redirect operations should be suffixed\n * with `Redirect`.\n * TODO: consider changing the type from a string to an object with ID\n * and some metadata for determining mode: redirect, popup or none.\n * @enum {string}\n */\nfireauth.AuthEvent.Type = {\n LINK_VIA_POPUP: 'linkViaPopup',\n LINK_VIA_REDIRECT: 'linkViaRedirect',\n REAUTH_VIA_POPUP: 'reauthViaPopup',\n REAUTH_VIA_REDIRECT: 'reauthViaRedirect',\n SIGN_IN_VIA_POPUP: 'signInViaPopup',\n SIGN_IN_VIA_REDIRECT: 'signInViaRedirect',\n UNKNOWN: 'unknown',\n VERIFY_APP: 'verifyApp'\n};\n\n\n/**\n * @param {!fireauth.AuthEvent} event The Auth event.\n * @return {boolean} Whether the event is a redirect type.\n */\nfireauth.AuthEvent.isRedirect = function(event) {\n return !!event.getType().match(/Redirect$/);\n};\n\n\n/**\n * @param {!fireauth.AuthEvent} event The Auth event.\n * @return {boolean} Whether the event is a popup type.\n */\nfireauth.AuthEvent.isPopup = function(event) {\n return !!event.getType().match(/Popup$/);\n};\n\n\n/** @return {!fireauth.AuthEvent.Type} The type of Auth event. */\nfireauth.AuthEvent.prototype.getType = function() {\n return this.type_;\n};\n\n\n/** @return {?string} The Auth event identifier. */\nfireauth.AuthEvent.prototype.getEventId = function() {\n return this.eventId_;\n};\n\n\n/** @return {string} The event unique identifier. */\nfireauth.AuthEvent.prototype.getUid = function() {\n var components = [];\n components.push(this.type_);\n if (this.eventId_) {\n components.push(this.eventId_);\n }\n if (this.sessionId_) {\n components.push(this.sessionId_);\n }\n if (this.tenantId_) {\n components.push(this.tenantId_);\n }\n return components.join('-');\n};\n\n\n/** @return {?string} The url response of Auth event. */\nfireauth.AuthEvent.prototype.getUrlResponse = function() {\n return this.urlResponse_;\n};\n\n\n/** @return {?string} The session ID Auth event. */\nfireauth.AuthEvent.prototype.getSessionId = function() {\n return this.sessionId_;\n};\n\n\n/** @return {?string} The POST body of the Auth event, if available. */\nfireauth.AuthEvent.prototype.getPostBody = function() {\n return this.postBody_;\n};\n\n\n/** @return {?string} The tenant ID of the Auth event, if available. */\nfireauth.AuthEvent.prototype.getTenantId = function() {\n return this.tenantId_;\n};\n\n\n/** @return {?fireauth.AuthError} The error of Auth event. */\nfireauth.AuthEvent.prototype.getError = function() {\n return this.error_;\n};\n\n\n/** @return {boolean} Whether Auth event has an error. */\nfireauth.AuthEvent.prototype.hasError = function() {\n return !!this.error_;\n};\n\n\n/** @return {!Object} The plain object representation of event. */\nfireauth.AuthEvent.prototype.toPlainObject = function() {\n return {\n 'type': this.type_,\n 'eventId': this.eventId_,\n 'urlResponse': this.urlResponse_,\n 'sessionId': this.sessionId_,\n 'postBody': this.postBody_,\n 'tenantId': this.tenantId_,\n 'error': this.error_ && this.error_.toPlainObject()\n };\n};\n\n\n/**\n * @param {?Object} rawResponse The plain object representation of Auth event.\n * @return {?fireauth.AuthEvent} The Auth event representation of plain object.\n */\nfireauth.AuthEvent.fromPlainObject = function(rawResponse) {\n var response = rawResponse || {};\n if (response['type']) {\n return new fireauth.AuthEvent(\n response['type'],\n response['eventId'],\n response['urlResponse'],\n response['sessionId'],\n response['error'] &&\n fireauth.AuthError.fromPlainObject(response['error']),\n response['postBody'],\n response['tenantId']\n );\n }\n return null;\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Provides the universal link subscriber utility to allow\n * multiple subscriptions for incoming universal link detection.\n */\ngoog.provide('fireauth.UniversalLinkSubscriber');\n\ngoog.require('fireauth.util');\ngoog.require('goog.array');\n\n/**\n * Defines the universal link subscriber class used to allow multiple universal\n * link subscriptions since the underlying plugin only works with one.\n * This utility is needed since the universal link cordova plugin can only allow\n * one subscriber and multiple app instances can subscribe to this.\n * @constructor @final @struct\n */\nfireauth.UniversalLinkSubscriber = function() {\n /**\n * @private {?function(?Object)} The master callback that subscribes directly\n * to universalLinks.\n */\n this.masterCb_ = null;\n /**\n * @private {!Array<function(?Object)>} The list of external subscribers that\n * are triggered every time the master callback is triggered.\n */\n this.cb_ = [];\n};\n\n\n/**\n * @return {!fireauth.UniversalLinkSubscriber} The default universal link\n * subscriber instance.\n */\nfireauth.UniversalLinkSubscriber.getInstance = function() {\n if (!fireauth.UniversalLinkSubscriber.instance_) {\n fireauth.UniversalLinkSubscriber.instance_ =\n new fireauth.UniversalLinkSubscriber();\n }\n return fireauth.UniversalLinkSubscriber.instance_;\n};\n\n\n/** Clears singleton instance. Useful for testing. */\nfireauth.UniversalLinkSubscriber.clear = function() {\n fireauth.UniversalLinkSubscriber.instance_ = null;\n};\n\n\n/**\n * @private {?fireauth.UniversalLinkSubscriber} The singleton universal\n * link subscriber instance.\n */\nfireauth.UniversalLinkSubscriber.instance_ = null;\n\n\n/**\n * Subscribes a callback to the universal link plugin listener.\n * @param {function(?Object)} cb The callback to subscribe to the universal\n * link plugin.\n */\nfireauth.UniversalLinkSubscriber.prototype.subscribe = function(cb) {\n var self = this;\n this.cb_.push(cb);\n if (!this.masterCb_) {\n this.masterCb_ = function(event) {\n for (var i = 0; i < self.cb_.length; i++) {\n self.cb_[i](event);\n }\n };\n var subscribe = fireauth.util.getObjectRef(\n 'universalLinks.subscribe', goog.global);\n // For iOS environments, this plugin is not used, therefore this is a no-op\n // and no error needs to be thrown.\n if (typeof subscribe === 'function') {\n subscribe(null, this.masterCb_);\n }\n }\n};\n\n\n/**\n * Unsubscribes a callback from the universal link plugin listener.\n * @param {function(?Object)} cb The callback to unsubscribe from the universal\n * link plugin.\n */\nfireauth.UniversalLinkSubscriber.prototype.unsubscribe = function(cb) {\n goog.array.removeAllIf(this.cb_, function(ele) {\n return ele == cb;\n });\n};\n\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the invalid origin error, a subclass of\n * fireauth.AuthError.\n */\n\n\ngoog.provide('fireauth.InvalidOriginError');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('goog.Uri');\ngoog.require('goog.string');\n\n\n\n/**\n * Invalid origin error that can be returned to the developer.\n * @param {string} origin The invalid domain name.\n * @constructor\n * @extends {fireauth.AuthError}\n */\nfireauth.InvalidOriginError = function(origin) {\n var code = fireauth.authenum.Error.INVALID_ORIGIN;\n var message = undefined;\n var uri = goog.Uri.parse(origin);\n // Get domain.\n var domain = uri.getDomain();\n // Get scheme.\n var scheme = uri.getScheme();\n // Only http, https and chrome-extension currently supported.\n if (scheme == 'chrome-extension') {\n // Chrome extension whitelisting.\n // Replace chrome-extension://CHROME_EXT_ID in error message template.\n message = goog.string.subs(\n fireauth.InvalidOriginError.CHROME_EXTENSION_MESSAGE_TEMPLATE_,\n domain);\n } else if (scheme == 'http' || scheme == 'https') {\n // Replace domain in error message template.\n message = goog.string.subs(\n fireauth.InvalidOriginError.HTTP_MESSAGE_TEMPLATE_,\n domain);\n } else {\n // Throw operation not supported when non http, https or Chrome extension\n // protocol.\n code = fireauth.authenum.Error.OPERATION_NOT_SUPPORTED;\n }\n fireauth.InvalidOriginError.base(this, 'constructor', code, message);\n};\ngoog.inherits(fireauth.InvalidOriginError, fireauth.AuthError);\n\n\n/** @private @const {string} The http invalid origin message template. */\nfireauth.InvalidOriginError.HTTP_MESSAGE_TEMPLATE_ = 'This domain (%s) is no' +\n 't authorized to run this operation. Add it to the OAuth redirect domain' +\n 's list in the Firebase console -> Auth section -> Sign in method tab.';\n\n\n/**\n * @private @const {string} The Chrome extension invalid origin message\n * template.\n */\nfireauth.InvalidOriginError.CHROME_EXTENSION_MESSAGE_TEMPLATE_ = 'This chrom' +\n 'e extension ID (chrome-extension://%s) is not authorized to run this op' +\n 'eration. Add it to the OAuth redirect domains list in the Firebase cons' +\n 'ole -> Auth section -> Sign in method tab.';\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the Auth errors that include emails and an Auth\n * credential, a subclass of fireauth.AuthError.\n */\n\n\ngoog.provide('fireauth.AuthErrorWithCredential');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.object');\ngoog.require('goog.object');\n\n\n/**\n * Error with email and credential that can be returned to the developer.\n * @param {fireauth.authenum.Error} code The error code.\n * @param {?fireauth.AuthErrorWithCredential.CredentialInfo=} opt_credentialInfo\n * Additional credential information to associate with the error.\n * @param {string=} opt_message The human-readable message.\n * @constructor\n * @extends {fireauth.AuthError}\n */\nfireauth.AuthErrorWithCredential =\n function(code, opt_credentialInfo, opt_message) {\n fireauth.AuthErrorWithCredential.base(\n this, 'constructor', code, opt_message);\n var credentialInfo = opt_credentialInfo || {};\n\n // These properties are public.\n if (credentialInfo.email) {\n fireauth.object.setReadonlyProperty(this, 'email', credentialInfo.email);\n }\n if (credentialInfo.phoneNumber) {\n fireauth.object.setReadonlyProperty(this, 'phoneNumber',\n credentialInfo.phoneNumber);\n }\n if (credentialInfo.credential) {\n fireauth.object.setReadonlyProperty(this, 'credential',\n credentialInfo.credential);\n }\n if (credentialInfo.tenantId) {\n fireauth.object.setReadonlyProperty(this, 'tenantId',\n credentialInfo.tenantId);\n }\n};\ngoog.inherits(fireauth.AuthErrorWithCredential, fireauth.AuthError);\n\n\n/**\n * Additional credential information to associate with an error, so that the\n * user does not have to execute the Auth flow again on linking errors.\n * @typedef {{\n * email: (?string|undefined),\n * phoneNumber: (?string|undefined),\n * credential: (?fireauth.AuthCredential|undefined),\n * tenantId: (?string|undefined),\n * }}\n */\nfireauth.AuthErrorWithCredential.CredentialInfo;\n\n\n/**\n * @return {!Object} The plain object form of the error.\n * @override\n */\nfireauth.AuthErrorWithCredential.prototype.toPlainObject = function() {\n var obj = {\n 'code': this['code'],\n 'message': this.message\n };\n if (this['email']) {\n obj['email'] = this['email'];\n }\n if (this['phoneNumber']) {\n obj['phoneNumber'] = this['phoneNumber'];\n }\n if (this['tenantId']) {\n obj['tenantId'] = this['tenantId'];\n }\n\n var credential = this['credential'] && this['credential'].toPlainObject();\n if (credential){\n goog.object.extend(obj, credential);\n }\n return obj;\n};\n\n\n/**\n * @return {!Object} The plain object form of the error. This is used by\n * JSON.toStringify() to return the stringified representation of the error;\n * @override\n */\nfireauth.AuthErrorWithCredential.prototype.toJSON = function() {\n // Return the plain object representation in case JSON.stringify is called on\n // an Auth error instance.\n return this.toPlainObject();\n};\n\n\n/**\n * @param {?Object|undefined} response The object response to convert to a\n * fireauth.AuthErrorWithCredential.\n * @return {?fireauth.AuthError} The error representation of the response.\n */\nfireauth.AuthErrorWithCredential.fromPlainObject = function(response) {\n // Code included.\n if (response['code']) {\n var code = response['code'] || '';\n // Remove prefix from name if available.\n if (code.indexOf(fireauth.AuthError.ERROR_CODE_PREFIX) == 0) {\n code = code.substring(fireauth.AuthError.ERROR_CODE_PREFIX.length);\n }\n\n // Credentials and tenant ID in response.\n var credentialInfo = {\n credential: fireauth.AuthProvider.getCredentialFromResponse(response),\n tenantId: response['tenantId']\n };\n if (response['email']) {\n credentialInfo.email = response['email'];\n } else if (response['phoneNumber']) {\n credentialInfo.phoneNumber = response['phoneNumber'];\n } else if (!credentialInfo.credential) {\n // Neither email, phone number or credentials are set; return a generic\n // error.\n return new fireauth.AuthError(code, response['message'] || undefined);\n }\n\n return new fireauth.AuthErrorWithCredential(code, credentialInfo,\n response['message']);\n }\n // No error or invalid response.\n return null;\n};\n","// Copyright 2010 The Closure Library Authors. All Rights Reserved.\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 * @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 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","// Copyright 2006 The Closure Library Authors. All Rights Reserved.\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 * @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');\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 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 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 goog.nullFunction 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 goog.net.XmlHttp.setGlobalFactory(\n 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 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 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 var 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 var progId = this.getProgId_();\n var 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 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 var ACTIVE_X_IDENTS = [\n 'MSXML2.XMLHTTP.6.0',\n 'MSXML2.XMLHTTP.3.0',\n 'MSXML2.XMLHTTP',\n 'Microsoft.XMLHTTP',\n ];\n for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) {\n var 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","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\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 * @fileoverview This file contain classes that add support for cross-domain XHR\n * requests (see http://www.w3.org/TR/cors/). Most modern browsers are able to\n * use a regular XMLHttpRequest for that, but IE 8 use XDomainRequest object\n * instead. This file provides an adapter from this object to a goog.net.XhrLike\n * and a factory to allow using this with a goog.net.XhrIo instance.\n *\n * IE 7 and older versions are not supported (given that they do not support\n * CORS requests).\n */\ngoog.provide('goog.net.CorsXmlHttpFactory');\ngoog.provide('goog.net.IeCorsXhrAdapter');\n\ngoog.require('goog.net.HttpStatus');\ngoog.require('goog.net.XhrLike');\ngoog.require('goog.net.XmlHttp');\ngoog.require('goog.net.XmlHttpFactory');\n\n\n\n/**\n * A factory of XML http request objects that supports cross domain requests.\n * This class should be instantiated and passed as the parameter of a\n * goog.net.XhrIo constructor to allow cross-domain requests in every browser.\n *\n * @extends {goog.net.XmlHttpFactory}\n * @constructor\n * @final\n */\ngoog.net.CorsXmlHttpFactory = function() {\n goog.net.XmlHttpFactory.call(this);\n};\ngoog.inherits(goog.net.CorsXmlHttpFactory, goog.net.XmlHttpFactory);\n\n\n/** @override */\ngoog.net.CorsXmlHttpFactory.prototype.createInstance = function() {\n var xhr = new XMLHttpRequest();\n if (('withCredentials' in xhr)) {\n return xhr;\n } else if (typeof XDomainRequest != 'undefined') {\n return new goog.net.IeCorsXhrAdapter();\n } else {\n throw new Error('Unsupported browser');\n }\n};\n\n\n/** @override */\ngoog.net.CorsXmlHttpFactory.prototype.internalGetOptions = function() {\n return {};\n};\n\n\n\n/**\n * An adapter around Internet Explorer's XDomainRequest object that makes it\n * look like a standard XMLHttpRequest. This can be used instead of\n * XMLHttpRequest to support CORS.\n *\n * @implements {goog.net.XhrLike}\n * @constructor\n * @struct\n * @final\n */\ngoog.net.IeCorsXhrAdapter = function() {\n /**\n * The underlying XDomainRequest used to make the HTTP request.\n * @type {!XDomainRequest}\n * @private\n */\n this.xdr_ = new XDomainRequest();\n\n /**\n * The simulated ready state.\n * @type {number}\n */\n this.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;\n\n /**\n * The simulated ready state change callback function.\n * @type {?function()|undefined}\n */\n this.onreadystatechange = null;\n\n /** @override */\n this.response = '';\n\n /**\n * The simulated response text parameter.\n * @type {string}\n */\n this.responseText = '';\n\n /**\n * This implementation only supports text response.\n * @type {string}\n * @override\n */\n this.responseType = '';\n\n /**\n * The simulated status code\n * @type {number}\n */\n this.status = -1;\n\n /** @override */\n this.responseXML = null;\n\n /** @override */\n this.statusText = '';\n\n this.xdr_.onload = goog.bind(this.handleLoad_, this);\n this.xdr_.onerror = goog.bind(this.handleError_, this);\n this.xdr_.onprogress = goog.bind(this.handleProgress_, this);\n this.xdr_.ontimeout = goog.bind(this.handleTimeout_, this);\n};\n\n\n/**\n * Opens a connection to the provided URL.\n * @param {string} method The HTTP method to use. Valid methods include GET and\n * POST.\n * @param {string} url The URL to contact. The authority of this URL must match\n * the authority of the current page's URL (e.g. http or https).\n * @param {?boolean=} opt_async Whether the request is asynchronous, defaulting\n * to true. XDomainRequest does not support syncronous requests, so setting\n * it to false will actually raise an exception.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.open = function(method, url, opt_async) {\n if (opt_async != null && (!opt_async)) {\n throw new Error('Only async requests are supported.');\n }\n this.xdr_.open(method, url);\n};\n\n\n/**\n * Sends the request to the remote server. Before calling this function, always\n * call {@link open}.\n * @param {(ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string)=}\n * opt_content The content to send as POSTDATA, if any. Only string data is\n * supported by this implementation.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.send = function(opt_content) {\n if (opt_content) {\n if (typeof opt_content == 'string') {\n this.xdr_.send(opt_content);\n } else {\n throw new Error('Only string data is supported');\n }\n } else {\n this.xdr_.send();\n }\n};\n\n\n/**\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.abort = function() {\n this.xdr_.abort();\n};\n\n\n/**\n * Sets a request header to send to the remote server. Because this\n * implementation does not support request headers, this function does nothing.\n * @param {string} key The name of the HTTP header to set. Ignored.\n * @param {string} value The value to set for the HTTP header. Ignored.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.setRequestHeader = function(key, value) {\n // Unsupported; ignore the header.\n};\n\n\n/**\n * Returns the value of the response header identified by key. This\n * implementation only supports the 'content-type' header.\n * @param {string} key The request header to fetch. If this parameter is set to\n * 'content-type' (case-insensitive), this function returns the value of\n * the 'content-type' request header. If this parameter is set to any other\n * value, this function always returns an empty string.\n * @return {string} The value of the response header, or an empty string if key\n * is not 'content-type' (case-insensitive).\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.getResponseHeader = function(key) {\n if (key.toLowerCase() == 'content-type') {\n return this.xdr_.contentType;\n }\n return '';\n};\n\n\n/**\n * Handles a request that has fully loaded successfully.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleLoad_ = function() {\n // IE only calls onload if the status is 200, so the status code must be OK.\n this.status = goog.net.HttpStatus.OK;\n this.response = this.responseText = this.xdr_.responseText;\n this.setReadyState_(goog.net.XmlHttp.ReadyState.COMPLETE);\n};\n\n\n/**\n * Handles a request that has failed to load.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleError_ = function() {\n // IE doesn't tell us what the status code actually is (other than the fact\n // that it is not 200), so simulate an INTERNAL_SERVER_ERROR.\n this.status = goog.net.HttpStatus.INTERNAL_SERVER_ERROR;\n this.response = this.responseText = '';\n this.setReadyState_(goog.net.XmlHttp.ReadyState.COMPLETE);\n};\n\n\n/**\n * Handles a request that timed out.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleTimeout_ = function() {\n this.handleError_();\n};\n\n\n/**\n * Handles a request that is in the process of loading.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.handleProgress_ = function() {\n // IE only calls onprogress if the status is 200, so the status code must be\n // OK.\n this.status = goog.net.HttpStatus.OK;\n this.setReadyState_(goog.net.XmlHttp.ReadyState.LOADING);\n};\n\n\n/**\n * Sets this XHR's ready state and fires the onreadystatechange listener (if one\n * is set).\n * @param {number} readyState The new ready state.\n * @private\n */\ngoog.net.IeCorsXhrAdapter.prototype.setReadyState_ = function(readyState) {\n this.readyState = readyState;\n if (this.onreadystatechange) {\n this.onreadystatechange();\n }\n};\n\n\n/**\n * Returns the response headers from the server. This implemntation only returns\n * the 'content-type' header.\n * @return {string} The headers returned from the server.\n * @override\n */\ngoog.net.IeCorsXhrAdapter.prototype.getAllResponseHeaders = function() {\n return 'content-type: ' + this.xdr_.contentType;\n};\n","// Copyright 2011 The Closure Library Authors. All Rights Reserved.\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 * @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\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 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 Definition of the LogRecord class. Please minimize\n * dependencies this file has on other closure classes as any dependency it\n * takes won't be able to use the logging infrastructure.\n */\n\ngoog.provide('goog.debug.LogRecord');\n\n\n\n/**\n * LogRecord objects are used to pass logging requests between\n * the logging framework and individual log Handlers.\n * @constructor\n * @param {goog.debug.Logger.Level} level One of the level identifiers.\n * @param {string} msg The string message.\n * @param {string} loggerName The name of the source logger.\n * @param {number=} opt_time Time this log record was created if other than now.\n * If 0, we use #goog.now.\n * @param {number=} opt_sequenceNumber Sequence number of this log record. This\n * should only be passed in when restoring a log record from persistence.\n */\ngoog.debug.LogRecord = function(\n level, msg, loggerName, opt_time, opt_sequenceNumber) {\n this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber);\n};\n\n\n/**\n * Time the LogRecord was created.\n * @type {number}\n * @private\n */\ngoog.debug.LogRecord.prototype.time_;\n\n\n/**\n * Level of the LogRecord\n * @type {goog.debug.Logger.Level}\n * @private\n */\ngoog.debug.LogRecord.prototype.level_;\n\n\n/**\n * Message associated with the record\n * @type {string}\n * @private\n */\ngoog.debug.LogRecord.prototype.msg_;\n\n\n/**\n * Name of the logger that created the record.\n * @type {string}\n * @private\n */\ngoog.debug.LogRecord.prototype.loggerName_;\n\n\n/**\n * Sequence number for the LogRecord. Each record has a unique sequence number\n * that is greater than all log records created before it.\n * @type {number}\n * @private\n */\ngoog.debug.LogRecord.prototype.sequenceNumber_ = 0;\n\n\n/**\n * Exception associated with the record\n * @type {?Object}\n * @private\n */\ngoog.debug.LogRecord.prototype.exception_ = null;\n\n\n/**\n * @define {boolean} Whether to enable log sequence numbers.\n */\ngoog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS =\n goog.define('goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS', true);\n\n\n/**\n * A sequence counter for assigning increasing sequence numbers to LogRecord\n * objects.\n * @type {number}\n * @private\n */\ngoog.debug.LogRecord.nextSequenceNumber_ = 0;\n\n\n/**\n * Sets all fields of the log record.\n * @param {goog.debug.Logger.Level} level One of the level identifiers.\n * @param {string} msg The string message.\n * @param {string} loggerName The name of the source logger.\n * @param {number=} opt_time Time this log record was created if other than now.\n * If 0, we use #goog.now.\n * @param {number=} opt_sequenceNumber Sequence number of this log record. This\n * should only be passed in when restoring a log record from persistence.\n */\ngoog.debug.LogRecord.prototype.reset = function(\n level, msg, loggerName, opt_time, opt_sequenceNumber) {\n if (goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS) {\n this.sequenceNumber_ = typeof opt_sequenceNumber == 'number' ?\n opt_sequenceNumber :\n goog.debug.LogRecord.nextSequenceNumber_++;\n }\n\n this.time_ = opt_time || goog.now();\n this.level_ = level;\n this.msg_ = msg;\n this.loggerName_ = loggerName;\n delete this.exception_;\n};\n\n\n/**\n * Get the source Logger's name.\n *\n * @return {string} source logger name (may be null).\n */\ngoog.debug.LogRecord.prototype.getLoggerName = function() {\n return this.loggerName_;\n};\n\n\n/**\n * Get the exception that is part of the log record.\n *\n * @return {Object} the exception.\n */\ngoog.debug.LogRecord.prototype.getException = function() {\n return this.exception_;\n};\n\n\n/**\n * Set the exception that is part of the log record.\n *\n * @param {Object} exception the exception.\n */\ngoog.debug.LogRecord.prototype.setException = function(exception) {\n this.exception_ = exception;\n};\n\n\n/**\n * Get the source Logger's name.\n *\n * @param {string} loggerName source logger name (may be null).\n */\ngoog.debug.LogRecord.prototype.setLoggerName = function(loggerName) {\n this.loggerName_ = loggerName;\n};\n\n\n/**\n * Get the logging message level, for example Level.SEVERE.\n * @return {goog.debug.Logger.Level} the logging message level.\n */\ngoog.debug.LogRecord.prototype.getLevel = function() {\n return this.level_;\n};\n\n\n/**\n * Set the logging message level, for example Level.SEVERE.\n * @param {goog.debug.Logger.Level} level the logging message level.\n */\ngoog.debug.LogRecord.prototype.setLevel = function(level) {\n this.level_ = level;\n};\n\n\n/**\n * Get the \"raw\" log message, before localization or formatting.\n *\n * @return {string} the raw message string.\n */\ngoog.debug.LogRecord.prototype.getMessage = function() {\n return this.msg_;\n};\n\n\n/**\n * Set the \"raw\" log message, before localization or formatting.\n *\n * @param {string} msg the raw message string.\n */\ngoog.debug.LogRecord.prototype.setMessage = function(msg) {\n this.msg_ = msg;\n};\n\n\n/**\n * Get event time in milliseconds since 1970.\n *\n * @return {number} event time in millis since 1970.\n */\ngoog.debug.LogRecord.prototype.getMillis = function() {\n return this.time_;\n};\n\n\n/**\n * Set event time in milliseconds since 1970.\n *\n * @param {number} time event time in millis since 1970.\n */\ngoog.debug.LogRecord.prototype.setMillis = function(time) {\n this.time_ = time;\n};\n\n\n/**\n * Get the sequence number.\n * <p>\n * Sequence numbers are normally assigned in the LogRecord\n * constructor, which assigns unique sequence numbers to\n * each new LogRecord in increasing order.\n * @return {number} the sequence number.\n */\ngoog.debug.LogRecord.prototype.getSequenceNumber = function() {\n return this.sequenceNumber_;\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 Logger class. Please minimize dependencies\n * this file has on other closure classes as any dependency it takes won't be\n * able to use the logging infrastructure.\n *\n * @see ../demos/debug.html\n */\n\ngoog.provide('goog.debug.LogManager');\ngoog.provide('goog.debug.Loggable');\ngoog.provide('goog.debug.Logger');\ngoog.provide('goog.debug.Logger.Level');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug');\ngoog.require('goog.debug.LogBuffer');\ngoog.require('goog.debug.LogRecord');\n\n\n/**\n * A message value that can be handled by a Logger.\n *\n * Functions are treated like callbacks, but are only called when the event's\n * log level is enabled. This is useful for logging messages that are expensive\n * to construct.\n *\n * @typedef {string|function(): string}\n */\ngoog.debug.Loggable;\n\n\n\n/**\n * The Logger is an object used for logging debug messages. Loggers are\n * normally named, using a hierarchical dot-separated namespace. Logger names\n * can be arbitrary strings, but they should normally be based on the package\n * name or class name of the logged component, such as goog.net.BrowserChannel.\n *\n * The Logger object is loosely based on the java class\n * java.util.logging.Logger. It supports different levels of filtering for\n * different loggers.\n *\n * The logger object should never be instantiated by application code. It\n * should always use the goog.debug.Logger.getLogger function.\n *\n * @constructor\n * @param {string} name The name of the Logger.\n * @final\n */\ngoog.debug.Logger = function(name) {\n /**\n * Name of the Logger. Generally a dot-separated namespace\n * @private {string}\n */\n this.name_ = name;\n\n /**\n * Parent Logger.\n * @private {?goog.debug.Logger}\n */\n this.parent_ = null;\n\n /**\n * Level that this logger only filters above. Null indicates it should\n * inherit from the parent.\n * @private {?goog.debug.Logger.Level}\n */\n this.level_ = null;\n\n /**\n * Map of children loggers. The keys are the leaf names of the children and\n * the values are the child loggers.\n * @private {?Object}\n */\n this.children_ = null;\n\n /**\n * Handlers that are listening to this logger.\n * @private {?Array<?Function>}\n */\n this.handlers_ = null;\n};\n\n\n/** @const */\ngoog.debug.Logger.ROOT_LOGGER_NAME = '';\n\n\n/**\n * @define {boolean} Toggles whether loggers other than the root logger can have\n * log handlers attached to them and whether they can have their log level\n * set. Logging is a bit faster when this is set to false.\n */\ngoog.debug.Logger.ENABLE_HIERARCHY =\n goog.define('goog.debug.Logger.ENABLE_HIERARCHY', true);\n\n\n/**\n * @define {boolean} Toggles whether active log statements are also recorded\n * to the profiler.\n */\ngoog.debug.Logger.ENABLE_PROFILER_LOGGING =\n goog.define('goog.debug.Logger.ENABLE_PROFILER_LOGGING', false);\n\n\nif (!goog.debug.Logger.ENABLE_HIERARCHY) {\n /**\n * @type {!Array<Function>}\n * @private\n */\n goog.debug.Logger.rootHandlers_ = [];\n\n\n /**\n * @type {goog.debug.Logger.Level}\n * @private\n */\n goog.debug.Logger.rootLevel_;\n}\n\n\n\n/**\n * The Level class defines a set of standard logging levels that\n * can be used to control logging output. The logging Level objects\n * are ordered and are specified by ordered integers. Enabling logging\n * at a given level also enables logging at all higher levels.\n * <p>\n * Clients should normally use the predefined Level constants such\n * as Level.SEVERE.\n * <p>\n * The levels in descending order are:\n * <ul>\n * <li>SEVERE (highest value)\n * <li>WARNING\n * <li>INFO\n * <li>CONFIG\n * <li>FINE\n * <li>FINER\n * <li>FINEST (lowest value)\n * </ul>\n * In addition there is a level OFF that can be used to turn\n * off logging, and a level ALL that can be used to enable\n * logging of all messages.\n *\n * @param {string} name The name of the level.\n * @param {number} value The numeric value of the level.\n * @constructor\n * @final\n */\ngoog.debug.Logger.Level = function(name, value) {\n /**\n * The name of the level\n * @type {string}\n */\n this.name = name;\n\n /**\n * The numeric value of the level\n * @type {number}\n */\n this.value = value;\n};\n\n\n/**\n * @return {string} String representation of the logger level.\n * @override\n */\ngoog.debug.Logger.Level.prototype.toString = function() {\n return this.name;\n};\n\n\n/**\n * OFF is a special level that can be used to turn off logging.\n * This level is initialized to <CODE>Infinity</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.OFF = new goog.debug.Logger.Level('OFF', Infinity);\n\n\n/**\n * SHOUT is a message level for extra debugging loudness.\n * This level is initialized to <CODE>1200</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level('SHOUT', 1200);\n\n\n/**\n * SEVERE is a message level indicating a serious failure.\n * This level is initialized to <CODE>1000</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level('SEVERE', 1000);\n\n\n/**\n * WARNING is a message level indicating a potential problem.\n * This level is initialized to <CODE>900</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level('WARNING', 900);\n\n\n/**\n * INFO is a message level for informational messages.\n * This level is initialized to <CODE>800</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.INFO = new goog.debug.Logger.Level('INFO', 800);\n\n\n/**\n * CONFIG is a message level for static configuration messages.\n * This level is initialized to <CODE>700</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level('CONFIG', 700);\n\n\n/**\n * FINE is a message level providing tracing information.\n * This level is initialized to <CODE>500</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.FINE = new goog.debug.Logger.Level('FINE', 500);\n\n\n/**\n * FINER indicates a fairly detailed tracing message.\n * This level is initialized to <CODE>400</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.FINER = new goog.debug.Logger.Level('FINER', 400);\n\n/**\n * FINEST indicates a highly detailed tracing message.\n * This level is initialized to <CODE>300</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\n\ngoog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level('FINEST', 300);\n\n\n/**\n * ALL indicates that all messages should be logged.\n * This level is initialized to <CODE>0</CODE>.\n * @type {!goog.debug.Logger.Level}\n */\ngoog.debug.Logger.Level.ALL = new goog.debug.Logger.Level('ALL', 0);\n\n\n/**\n * The predefined levels.\n * @type {!Array<!goog.debug.Logger.Level>}\n * @final\n */\ngoog.debug.Logger.Level.PREDEFINED_LEVELS = [\n goog.debug.Logger.Level.OFF, goog.debug.Logger.Level.SHOUT,\n goog.debug.Logger.Level.SEVERE, goog.debug.Logger.Level.WARNING,\n goog.debug.Logger.Level.INFO, goog.debug.Logger.Level.CONFIG,\n goog.debug.Logger.Level.FINE, goog.debug.Logger.Level.FINER,\n goog.debug.Logger.Level.FINEST, goog.debug.Logger.Level.ALL\n];\n\n\n/**\n * A lookup map used to find the level object based on the name or value of\n * the level object.\n * @type {?Object}\n * @private\n */\ngoog.debug.Logger.Level.predefinedLevelsCache_ = null;\n\n\n/**\n * Creates the predefined levels cache and populates it.\n * @private\n */\ngoog.debug.Logger.Level.createPredefinedLevelsCache_ = function() {\n goog.debug.Logger.Level.predefinedLevelsCache_ = {};\n for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];\n i++) {\n goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level;\n goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level;\n }\n};\n\n\n/**\n * Gets the predefined level with the given name.\n * @param {string} name The name of the level.\n * @return {goog.debug.Logger.Level} The level, or null if none found.\n */\ngoog.debug.Logger.Level.getPredefinedLevel = function(name) {\n if (!goog.debug.Logger.Level.predefinedLevelsCache_) {\n goog.debug.Logger.Level.createPredefinedLevelsCache_();\n }\n\n return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null;\n};\n\n\n/**\n * Gets the highest predefined level <= #value.\n * @param {number} value Level value.\n * @return {goog.debug.Logger.Level} The level, or null if none found.\n */\ngoog.debug.Logger.Level.getPredefinedLevelByValue = function(value) {\n if (!goog.debug.Logger.Level.predefinedLevelsCache_) {\n goog.debug.Logger.Level.createPredefinedLevelsCache_();\n }\n\n if (value in /** @type {!Object} */ (\n goog.debug.Logger.Level.predefinedLevelsCache_)) {\n return goog.debug.Logger.Level.predefinedLevelsCache_[value];\n }\n\n for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) {\n var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];\n if (level.value <= value) {\n return level;\n }\n }\n return null;\n};\n\n\n/**\n * Finds or creates a logger for a named subsystem. If a logger has already been\n * created with the given name it is returned. Otherwise a new logger is\n * created. If a new logger is created its log level will be configured based\n * on the LogManager configuration and it will configured to also send logging\n * output to its parent's handlers. It will be registered in the LogManager\n * global namespace.\n *\n * @param {string} name A name for the logger. This should be a dot-separated\n * name and should normally be based on the package name or class name of the\n * subsystem, such as goog.net.BrowserChannel.\n * @return {!goog.debug.Logger} The named logger.\n * @deprecated use {@link goog.log} instead.\n */\ngoog.debug.Logger.getLogger = function(name) {\n return goog.debug.LogManager.getLogger(name);\n};\n\n\n/**\n * Logs a message to profiling tools, if available.\n * {@see https://developers.google.com/web-toolkit/speedtracer/logging-api}\n * {@see http://msdn.microsoft.com/en-us/library/dd433074(VS.85).aspx}\n * @param {string} msg The message to log.\n */\ngoog.debug.Logger.logToProfilers = function(msg) {\n // Some browsers also log timeStamp calls to the console, only log\n // if actually asked.\n if (goog.debug.Logger.ENABLE_PROFILER_LOGGING) {\n var msWriteProfilerMark = goog.global['msWriteProfilerMark'];\n if (msWriteProfilerMark) {\n // Logs a message to the Microsoft profiler\n // On IE, console['timeStamp'] may output to console\n msWriteProfilerMark(msg);\n return;\n }\n\n // Using goog.global, as loggers might be used in window-less contexts.\n var console = goog.global['console'];\n if (console && console['timeStamp']) {\n // Logs a message to Firebug, Web Inspector, SpeedTracer, etc.\n console['timeStamp'](msg);\n }\n }\n};\n\n\n/**\n * Gets the name of this logger.\n * @return {string} The name of this logger.\n */\ngoog.debug.Logger.prototype.getName = function() {\n return this.name_;\n};\n\n\n/**\n * Adds a handler to the logger. This doesn't use the event system because\n * we want to be able to add logging to the event system.\n * @param {Function} handler Handler function to add.\n */\ngoog.debug.Logger.prototype.addHandler = function(handler) {\n if (goog.debug.LOGGING_ENABLED) {\n if (goog.debug.Logger.ENABLE_HIERARCHY) {\n if (!this.handlers_) {\n this.handlers_ = [];\n }\n this.handlers_.push(handler);\n } else {\n goog.asserts.assert(\n !this.name_, 'Cannot call addHandler on a non-root logger when ' +\n 'goog.debug.Logger.ENABLE_HIERARCHY is false.');\n goog.debug.Logger.rootHandlers_.push(handler);\n }\n }\n};\n\n\n/**\n * Removes a handler from the logger. This doesn't use the event system because\n * we want to be able to add logging to the event system.\n * @param {Function} handler Handler function to remove.\n * @return {boolean} Whether the handler was removed.\n */\ngoog.debug.Logger.prototype.removeHandler = function(handler) {\n if (goog.debug.LOGGING_ENABLED) {\n var handlers = goog.debug.Logger.ENABLE_HIERARCHY ?\n this.handlers_ :\n goog.debug.Logger.rootHandlers_;\n return !!handlers && goog.array.remove(handlers, handler);\n } else {\n return false;\n }\n};\n\n\n/**\n * Returns the parent of this logger.\n * @return {goog.debug.Logger} The parent logger or null if this is the root.\n */\ngoog.debug.Logger.prototype.getParent = function() {\n return this.parent_;\n};\n\n\n/**\n * Returns the children of this logger as a map of the child name to the logger.\n * @return {!Object} The map where the keys are the child leaf names and the\n * values are the Logger objects.\n */\ngoog.debug.Logger.prototype.getChildren = function() {\n if (!this.children_) {\n this.children_ = {};\n }\n return this.children_;\n};\n\n\n/**\n * Set the log level specifying which message levels will be logged by this\n * logger. Message levels lower than this value will be discarded.\n * The level value Level.OFF can be used to turn off logging. If the new level\n * is null, it means that this node should inherit its level from its nearest\n * ancestor with a specific (non-null) level value.\n *\n * @param {goog.debug.Logger.Level} level The new level.\n */\ngoog.debug.Logger.prototype.setLevel = function(level) {\n if (goog.debug.LOGGING_ENABLED) {\n if (goog.debug.Logger.ENABLE_HIERARCHY) {\n this.level_ = level;\n } else {\n goog.asserts.assert(\n !this.name_, 'Cannot call setLevel() on a non-root logger when ' +\n 'goog.debug.Logger.ENABLE_HIERARCHY is false.');\n goog.debug.Logger.rootLevel_ = level;\n }\n }\n};\n\n\n/**\n * Gets the log level specifying which message levels will be logged by this\n * logger. Message levels lower than this value will be discarded.\n * The level value Level.OFF can be used to turn off logging. If the level\n * is null, it means that this node should inherit its level from its nearest\n * ancestor with a specific (non-null) level value.\n *\n * @return {goog.debug.Logger.Level} The level.\n */\ngoog.debug.Logger.prototype.getLevel = function() {\n return goog.debug.LOGGING_ENABLED ? this.level_ : goog.debug.Logger.Level.OFF;\n};\n\n\n/**\n * Returns the effective level of the logger based on its ancestors' levels.\n * @return {goog.debug.Logger.Level} The level.\n */\ngoog.debug.Logger.prototype.getEffectiveLevel = function() {\n if (!goog.debug.LOGGING_ENABLED) {\n return goog.debug.Logger.Level.OFF;\n }\n\n if (!goog.debug.Logger.ENABLE_HIERARCHY) {\n return goog.debug.Logger.rootLevel_;\n }\n if (this.level_) {\n return this.level_;\n }\n if (this.parent_) {\n return this.parent_.getEffectiveLevel();\n }\n goog.asserts.fail('Root logger has no level set.');\n return null;\n};\n\n\n/**\n * Checks if a message of the given level would actually be logged by this\n * logger. This check is based on the Loggers effective level, which may be\n * inherited from its parent.\n * @param {goog.debug.Logger.Level} level The level to check.\n * @return {boolean} Whether the message would be logged.\n */\ngoog.debug.Logger.prototype.isLoggable = function(level) {\n return goog.debug.LOGGING_ENABLED &&\n level.value >= this.getEffectiveLevel().value;\n};\n\n\n/**\n * Logs a message. If the logger is currently enabled for the\n * given message level then the given message is forwarded to all the\n * registered output Handler objects.\n * @param {goog.debug.Logger.Level} level One of the level identifiers.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error|Object=} opt_exception An exception associated with the\n * message.\n */\ngoog.debug.Logger.prototype.log = function(level, msg, opt_exception) {\n // java caches the effective level, not sure it's necessary here\n if (goog.debug.LOGGING_ENABLED && this.isLoggable(level)) {\n // Message callbacks can be useful when a log message is expensive to build.\n if (goog.isFunction(msg)) {\n msg = msg();\n }\n\n this.doLogRecord_(this.getLogRecord(level, msg, opt_exception));\n }\n};\n\n\n/**\n * Creates a new log record and adds the exception (if present) to it.\n * @param {goog.debug.Logger.Level} level One of the level identifiers.\n * @param {string} msg The string message.\n * @param {Error|Object=} opt_exception An exception associated with the\n * message.\n * @return {!goog.debug.LogRecord} A log record.\n * @suppress {es5Strict}\n */\ngoog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception) {\n if (goog.debug.LogBuffer.isBufferingEnabled()) {\n var logRecord =\n goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_);\n } else {\n logRecord = new goog.debug.LogRecord(level, String(msg), this.name_);\n }\n if (opt_exception) {\n logRecord.setException(opt_exception);\n }\n return logRecord;\n};\n\n\n/**\n * Logs a message at the Logger.Level.SHOUT level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.shout = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.SEVERE level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.severe = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.WARNING level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.warning = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.INFO level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.info = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.INFO, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.CONFIG level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.config = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.FINE level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.fine = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.FINE, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.FINER level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.finer = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.FINER, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Logger.Level.FINEST level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.debug.Logger.prototype.finest = function(msg, opt_exception) {\n if (goog.debug.LOGGING_ENABLED) {\n this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a LogRecord. If the logger is currently enabled for the\n * given message level then the given message is forwarded to all the\n * registered output Handler objects.\n * @param {goog.debug.LogRecord} logRecord A log record to log.\n */\ngoog.debug.Logger.prototype.logRecord = function(logRecord) {\n if (goog.debug.LOGGING_ENABLED && this.isLoggable(logRecord.getLevel())) {\n this.doLogRecord_(logRecord);\n }\n};\n\n\n/**\n * Logs a LogRecord.\n * @param {goog.debug.LogRecord} logRecord A log record to log.\n * @private\n */\ngoog.debug.Logger.prototype.doLogRecord_ = function(logRecord) {\n if (goog.debug.Logger.ENABLE_PROFILER_LOGGING) {\n goog.debug.Logger.logToProfilers('log:' + logRecord.getMessage());\n }\n if (goog.debug.Logger.ENABLE_HIERARCHY) {\n var target = this;\n while (target) {\n target.callPublish_(logRecord);\n target = target.getParent();\n }\n } else {\n for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++];) {\n handler(logRecord);\n }\n }\n};\n\n\n/**\n * Calls the handlers for publish.\n * @param {goog.debug.LogRecord} logRecord The log record to publish.\n * @private\n */\ngoog.debug.Logger.prototype.callPublish_ = function(logRecord) {\n if (this.handlers_) {\n for (var i = 0, handler; handler = this.handlers_[i]; i++) {\n handler(logRecord);\n }\n }\n};\n\n\n/**\n * Sets the parent of this logger. This is used for setting up the logger tree.\n * @param {goog.debug.Logger} parent The parent logger.\n * @private\n */\ngoog.debug.Logger.prototype.setParent_ = function(parent) {\n this.parent_ = parent;\n};\n\n\n/**\n * Adds a child to this logger. This is used for setting up the logger tree.\n * @param {string} name The leaf name of the child.\n * @param {goog.debug.Logger} logger The child logger.\n * @private\n */\ngoog.debug.Logger.prototype.addChild_ = function(name, logger) {\n this.getChildren()[name] = logger;\n};\n\n\n/**\n * There is a single global LogManager object that is used to maintain a set of\n * shared state about Loggers and log services. This is loosely based on the\n * java class java.util.logging.LogManager.\n * @const\n */\ngoog.debug.LogManager = {};\n\n\n/**\n * Map of logger names to logger objects.\n *\n * @type {!Object<string, !goog.debug.Logger>}\n * @private\n */\ngoog.debug.LogManager.loggers_ = {};\n\n\n/**\n * The root logger which is the root of the logger tree.\n * @type {?goog.debug.Logger}\n * @private\n */\ngoog.debug.LogManager.rootLogger_ = null;\n\n\n/**\n * Initializes the LogManager if not already initialized.\n */\ngoog.debug.LogManager.initialize = function() {\n if (!goog.debug.LogManager.rootLogger_) {\n goog.debug.LogManager.rootLogger_ =\n new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME);\n goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] =\n goog.debug.LogManager.rootLogger_;\n goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG);\n }\n};\n\n\n/**\n * Returns all the loggers.\n * @return {!Object<string, !goog.debug.Logger>} Map of logger names to logger\n * objects.\n */\ngoog.debug.LogManager.getLoggers = function() {\n return goog.debug.LogManager.loggers_;\n};\n\n\n/**\n * Returns the root of the logger tree namespace, the logger with the empty\n * string as its name.\n *\n * @return {!goog.debug.Logger} The root logger.\n */\ngoog.debug.LogManager.getRoot = function() {\n goog.debug.LogManager.initialize();\n return /** @type {!goog.debug.Logger} */ (goog.debug.LogManager.rootLogger_);\n};\n\n\n/**\n * Finds a named logger.\n *\n * @param {string} name A name for the logger. This should be a dot-separated\n * name and should normally be based on the package name or class name of the\n * subsystem, such as goog.net.BrowserChannel.\n * @return {!goog.debug.Logger} The named logger.\n */\ngoog.debug.LogManager.getLogger = function(name) {\n goog.debug.LogManager.initialize();\n var ret = goog.debug.LogManager.loggers_[name];\n return ret || goog.debug.LogManager.createLogger_(name);\n};\n\n\n/**\n * Creates a function that can be passed to goog.debug.catchErrors. The function\n * will log all reported errors using the given logger.\n * @param {goog.debug.Logger=} opt_logger The logger to log the errors to.\n * Defaults to the root logger.\n * @return {function(Object)} The created function.\n */\ngoog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) {\n return function(info) {\n var logger = opt_logger || goog.debug.LogManager.getRoot();\n logger.severe(\n 'Error: ' + info.message + ' (' + info.fileName + ' @ Line: ' +\n info.line + ')');\n };\n};\n\n\n/**\n * Creates the named logger. Will also create the parents of the named logger\n * if they don't yet exist.\n * @param {string} name The name of the logger.\n * @return {!goog.debug.Logger} The named logger.\n * @private\n */\ngoog.debug.LogManager.createLogger_ = function(name) {\n // find parent logger\n var logger = new goog.debug.Logger(name);\n if (goog.debug.Logger.ENABLE_HIERARCHY) {\n var lastDotIndex = name.lastIndexOf('.');\n var parentName = name.substr(0, lastDotIndex);\n var leafName = name.substr(lastDotIndex + 1);\n var parentLogger = goog.debug.LogManager.getLogger(parentName);\n\n // tell the parent about the child and the child about the parent\n parentLogger.addChild_(leafName, logger);\n logger.setParent_(parentLogger);\n }\n\n goog.debug.LogManager.loggers_[name] = logger;\n return logger;\n};\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Basic strippable logging definitions.\n * @see http://go/closurelogging\n */\n\ngoog.provide('goog.log');\ngoog.provide('goog.log.Level');\ngoog.provide('goog.log.LogRecord');\ngoog.provide('goog.log.Logger');\n\ngoog.require('goog.debug');\ngoog.require('goog.debug.LogManager');\ngoog.require('goog.debug.LogRecord');\ngoog.require('goog.debug.Logger');\n\n\n/** @define {boolean} Whether logging is enabled. */\ngoog.log.ENABLED = goog.define('goog.log.ENABLED', goog.debug.LOGGING_ENABLED);\n\n\n/** @const {string} */\ngoog.log.ROOT_LOGGER_NAME = goog.debug.Logger.ROOT_LOGGER_NAME;\n\n\n\n/**\n * @constructor\n * @final\n */\ngoog.log.Logger = goog.debug.Logger;\n\n\n\n/**\n * @constructor\n * @final\n */\ngoog.log.Level = goog.debug.Logger.Level;\n\n\n\n/**\n * @constructor\n * @final\n */\ngoog.log.LogRecord = goog.debug.LogRecord;\n\n\n/**\n * Finds or creates a logger for a named subsystem. If a logger has already been\n * created with the given name it is returned. Otherwise a new logger is\n * created. If a new logger is created its log level will be configured based\n * on the goog.debug.LogManager configuration and it will configured to also\n * send logging output to its parent's handlers.\n * @see goog.debug.LogManager\n *\n * @param {string} name A name for the logger. This should be a dot-separated\n * name and should normally be based on the package name or class name of\n * the subsystem, such as goog.net.BrowserChannel.\n * @param {goog.log.Level=} opt_level If provided, override the\n * default logging level with the provided level.\n * @return {goog.log.Logger} The named logger or null if logging is disabled.\n */\ngoog.log.getLogger = function(name, opt_level) {\n if (goog.log.ENABLED) {\n var logger = goog.debug.LogManager.getLogger(name);\n if (opt_level && logger) {\n logger.setLevel(opt_level);\n }\n return logger;\n } else {\n return null;\n }\n};\n\n\n// TODO(johnlenz): try to tighten the types to these functions.\n/**\n * Adds a handler to the logger. This doesn't use the event system because\n * we want to be able to add logging to the event system.\n * @param {goog.log.Logger} logger\n * @param {Function} handler Handler function to add.\n */\ngoog.log.addHandler = function(logger, handler) {\n if (goog.log.ENABLED && logger) {\n logger.addHandler(handler);\n }\n};\n\n\n/**\n * Removes a handler from the logger. This doesn't use the event system because\n * we want to be able to add logging to the event system.\n * @param {goog.log.Logger} logger\n * @param {Function} handler Handler function to remove.\n * @return {boolean} Whether the handler was removed.\n */\ngoog.log.removeHandler = function(logger, handler) {\n if (goog.log.ENABLED && logger) {\n return logger.removeHandler(handler);\n } else {\n return false;\n }\n};\n\n\n/**\n * Logs a message. If the logger is currently enabled for the\n * given message level then the given message is forwarded to all the\n * registered output Handler objects.\n * @param {goog.log.Logger} logger\n * @param {goog.log.Level} level One of the level identifiers.\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error|Object=} opt_exception An exception associated with the\n * message.\n */\ngoog.log.log = function(logger, level, msg, opt_exception) {\n if (goog.log.ENABLED && logger) {\n logger.log(level, msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Level.SEVERE level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.log.Logger} logger\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.log.error = function(logger, msg, opt_exception) {\n if (goog.log.ENABLED && logger) {\n logger.severe(msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Level.WARNING level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.log.Logger} logger\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.log.warning = function(logger, msg, opt_exception) {\n if (goog.log.ENABLED && logger) {\n logger.warning(msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Level.INFO level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.log.Logger} logger\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.log.info = function(logger, msg, opt_exception) {\n if (goog.log.ENABLED && logger) {\n logger.info(msg, opt_exception);\n }\n};\n\n\n/**\n * Logs a message at the Level.Fine level.\n * If the logger is currently enabled for the given message level then the\n * given message is forwarded to all the registered output Handler objects.\n * @param {goog.log.Logger} logger\n * @param {goog.debug.Loggable} msg The message to log.\n * @param {Error=} opt_exception An exception associated with the message.\n */\ngoog.log.fine = function(logger, msg, opt_exception) {\n if (goog.log.ENABLED && logger) {\n logger.fine(msg, opt_exception);\n }\n};\n","// Copyright 2015 The Closure Library Authors. All Rights Reserved.\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\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 * Factory for creating Xhr objects that uses the native fetch() method.\n * https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\n * Note that this factory is intended for use in Service Worker only.\n * @param {!WorkerGlobalScope} worker The Service Worker global scope.\n * @extends {goog.net.XmlHttpFactory}\n * @struct\n * @constructor\n */\ngoog.net.FetchXmlHttpFactory = function(worker) {\n goog.net.FetchXmlHttpFactory.base(this, 'constructor');\n\n /** @private @final {!WorkerGlobalScope} */\n this.worker_ = worker;\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 var instance = new goog.net.FetchXmlHttp(this.worker_);\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 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 this.cacheMode_ = cacheMode;\n};\n\n\n\n/**\n * FetchXmlHttp object constructor.\n * @param {!WorkerGlobalScope} worker\n * @extends {goog.events.EventTarget}\n * @implements {goog.net.XhrLike}\n * @constructor\n * @struct\n */\ngoog.net.FetchXmlHttp = function(worker) {\n goog.net.FetchXmlHttp.base(this, 'constructor');\n\n /** @private @final {!WorkerGlobalScope} */\n this.worker_ = worker;\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}\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 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 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 var 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 this.worker_\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 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 }\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_(false);\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 if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n\n this.fetchResponse_ = response;\n\n if (!this.responseHeaders_) {\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.response = this.responseText = '';\n this.currentReader_ =\n /** @type {!ReadableStreamDefaultReader} */ (response.body.getReader());\n this.textDecoder_ = new TextDecoder();\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 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 {!IteratorResult} result\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleDataFromStream_ = function(result) {\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n\n var dataPacket = result.value ? /** @type {!Uint8Array} */ (result.value) :\n new Uint8Array(0);\n var newText = 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_(true);\n } else {\n this.dispatchCallback_();\n }\n\n if (this.readyState == goog.net.FetchXmlHttp.RequestState.LOADING) {\n this.readInputFromFetch_();\n }\n};\n\n\n/**\n * Handles the response text.\n * @param {string} responseText\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleResponseText_ = function(responseText) {\n if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n this.response = this.responseText = responseText;\n this.requestDone_(true);\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 if (!this.inProgress_) {\n // The request was aborted, ignore.\n return;\n }\n this.response = responseArrayBuffer;\n this.requestDone_(true);\n};\n\n\n/**\n * Handles the send failure.\n * @param {*} error\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.handleSendFailure_ = function(error) {\n var 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_(true);\n};\n\n\n/**\n * Sets the request state to DONE and performs cleanup.\n * @param {boolean} setStatus whether to set the status and statusText fields,\n * this is not necessary when the request is aborted.\n * @private\n */\ngoog.net.FetchXmlHttp.prototype.requestDone_ = function(setStatus) {\n if (setStatus && this.fetchResponse_) {\n this.status = this.fetchResponse_.status;\n this.statusText = this.fetchResponse_.statusText;\n }\n\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 this.requestHeaders_.append(header, value);\n};\n\n\n/** @override */\ngoog.net.FetchXmlHttp.prototype.getResponseHeader = function(header) {\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 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 var lines = [];\n var iter = this.responseHeaders_.entries();\n var entry = iter.next();\n while (!entry.done) {\n var 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 this.credentialsMode_ = credentialsMode;\n};\n\n\n/**\n * @param {!RequestCache} cacheMode The cache mode of the Service Worker fetch.\n */\ngoog.net.FetchXmlHttp.prototype.setCacheMode = function(cacheMode) {\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 if (this.onreadystatechange) {\n this.onreadystatechange.call(this);\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 return function() { return retValue; };\n};\n\n\n/**\n * Always returns false.\n * @type {function(...): boolean}\n */\ngoog.functions.FALSE = function() {\n return false;\n};\n\n\n/**\n * Always returns true.\n * @type {function(...): boolean}\n */\ngoog.functions.TRUE = function() {\n return true;\n};\n\n\n/**\n * Always returns NULL.\n * @type {function(...): null}\n */\ngoog.functions.NULL = function() {\n return null;\n};\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 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 return function() {\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 return function() { throw err; };\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 opt_numArgs = opt_numArgs || 0;\n return function() {\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 return function() { return arguments[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 const rightArgs = Array.prototype.slice.call(arguments, 1);\n return function() {\n const self = /** @type {*} */ (this);\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 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 return function(other) {\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 const functions = arguments;\n const length = functions.length;\n return function() {\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 const functions = arguments;\n const length = functions.length;\n return function() {\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 const functions = arguments;\n const length = functions.length;\n return function() {\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 const functions = arguments;\n const length = functions.length;\n return function() {\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 return function() {\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 /**\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 let called = false;\n let value;\n\n return function() {\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 // 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 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 let timeout = 0;\n return /** @type {function(...?)} */ (function(var_args) {\n goog.global.clearTimeout(timeout);\n const args = arguments;\n timeout = goog.global.setTimeout(function() {\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 let timeout = 0;\n let shouldFire = false;\n let args = [];\n\n const handleTimeout = function() {\n timeout = 0;\n if (shouldFire) {\n shouldFire = false;\n fire();\n }\n };\n\n const fire = function() {\n timeout = goog.global.setTimeout(handleTimeout, interval);\n f.apply(opt_scope, args);\n };\n\n return /** @type {function(...?)} */ (function(var_args) {\n args = 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 let timeout = 0;\n\n const handleTimeout = function() {\n timeout = 0;\n };\n\n return /** @type {function(...?)} */ (function(var_args) {\n if (!timeout) {\n timeout = goog.global.setTimeout(handleTimeout, interval);\n f.apply(opt_scope, arguments);\n }\n });\n};\n","// Copyright 2006 The Closure Library Authors. All Rights Reserved.\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 * @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","// Copyright 2007 The Closure Library Authors. All Rights Reserved.\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 * @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 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","// Copyright 2007 Bob Ippolito. All Rights Reserved.\n// Modifications Copyright 2009 The Closure Library Authors. All Rights\n// Reserved.\n\n/**\n * @license Portions of this code are from MochiKit, received by\n * The Closure Authors under the MIT license. All other code is Copyright\n * 2005-2009 The Closure Authors. All Rights Reserved.\n */\n\n/**\n * @fileoverview Classes for tracking asynchronous operations and handling the\n * results. The Deferred object here is patterned after the Deferred object in\n * the Twisted python networking framework.\n *\n * See: http://twistedmatrix.com/projects/core/documentation/howto/defer.html\n *\n * Based on the Dojo code which in turn is based on the MochiKit code.\n *\n */\n\ngoog.provide('goog.async.Deferred');\ngoog.provide('goog.async.Deferred.AlreadyCalledError');\ngoog.provide('goog.async.Deferred.CanceledError');\n\ngoog.require('goog.Promise');\ngoog.require('goog.Thenable');\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug.Error');\n\n\n\n/**\n * A Deferred represents the result of an asynchronous operation. A Deferred\n * instance has no result when it is created, and is \"fired\" (given an initial\n * result) by calling `callback` or `errback`.\n *\n * Once fired, the result is passed through a sequence of callback functions\n * registered with `addCallback` or `addErrback`. The functions may\n * mutate the result before it is passed to the next function in the sequence.\n *\n * Callbacks and errbacks may be added at any time, including after the Deferred\n * has been \"fired\". If there are no pending actions in the execution sequence\n * of a fired Deferred, any new callback functions will be called with the last\n * computed result. Adding a callback function is the only way to access the\n * result of the Deferred.\n *\n * If a Deferred operation is canceled, an optional user-provided cancellation\n * function is invoked which may perform any special cleanup, followed by firing\n * the Deferred's errback sequence with a `CanceledError`. If the\n * Deferred has already fired, cancellation is ignored.\n *\n * Deferreds may be templated to a specific type they produce using generics\n * with syntax such as:\n *\n * /** @type {goog.async.Deferred<string>} *\\\n * var d = new goog.async.Deferred();\n * // Compiler can infer that foo is a string.\n * d.addCallback(function(foo) {...});\n * d.callback('string'); // Checked to be passed a string\n *\n * Since deferreds are often used to produce different values across a chain,\n * the type information is not propagated across chains, but rather only\n * associated with specifically cast objects.\n *\n * @param {Function=} opt_onCancelFunction A function that will be called if the\n * Deferred is canceled. If provided, this function runs before the\n * Deferred is fired with a `CanceledError`.\n * @param {Object=} opt_defaultScope The default object context to call\n * callbacks and errbacks in.\n * @constructor\n * @implements {goog.Thenable<VALUE>}\n * @template VALUE\n */\ngoog.async.Deferred = function(opt_onCancelFunction, opt_defaultScope) {\n /**\n * Entries in the sequence are arrays containing a callback, an errback, and\n * an optional scope. The callback or errback in an entry may be null.\n * @type {!Array<!Array>}\n * @private\n */\n this.sequence_ = [];\n\n /**\n * Optional function that will be called if the Deferred is canceled.\n * @type {Function|undefined}\n * @private\n */\n this.onCancelFunction_ = opt_onCancelFunction;\n\n /**\n * The default scope to execute callbacks and errbacks in.\n * @type {Object}\n * @private\n */\n this.defaultScope_ = opt_defaultScope || null;\n\n /**\n * Whether the Deferred has been fired.\n * @type {boolean}\n * @private\n */\n this.fired_ = false;\n\n /**\n * Whether the last result in the execution sequence was an error.\n * @type {boolean}\n * @private\n */\n this.hadError_ = false;\n\n /**\n * The current Deferred result, updated as callbacks and errbacks are\n * executed.\n * @type {*}\n * @private\n */\n this.result_ = undefined;\n\n /**\n * Whether the Deferred is blocked waiting on another Deferred to fire. If a\n * callback or errback returns a Deferred as a result, the execution sequence\n * is blocked until that Deferred result becomes available.\n * @type {boolean}\n * @private\n */\n this.blocked_ = false;\n\n /**\n * Whether this Deferred is blocking execution of another Deferred. If this\n * instance was returned as a result in another Deferred's execution\n * sequence,that other Deferred becomes blocked until this instance's\n * execution sequence completes. No additional callbacks may be added to a\n * Deferred once it is blocking another instance.\n * @type {boolean}\n * @private\n */\n this.blocking_ = false;\n\n /**\n * Whether the Deferred has been canceled without having a custom cancel\n * function.\n * @type {boolean}\n * @private\n */\n this.silentlyCanceled_ = false;\n\n /**\n * If an error is thrown during Deferred execution with no errback to catch\n * it, the error is rethrown after a timeout. Reporting the error after a\n * timeout allows execution to continue in the calling context (empty when\n * no error is scheduled).\n * @type {number}\n * @private\n */\n this.unhandledErrorId_ = 0;\n\n /**\n * If this Deferred was created by branch(), this will be the \"parent\"\n * Deferred.\n * @type {?goog.async.Deferred}\n * @private\n */\n this.parent_ = null;\n\n /**\n * The number of Deferred objects that have been branched off this one. This\n * will be decremented whenever a branch is fired or canceled.\n * @type {number}\n * @private\n */\n this.branches_ = 0;\n\n if (goog.async.Deferred.LONG_STACK_TRACES) {\n /**\n * Holds the stack trace at time of deferred creation if the JS engine\n * provides the Error.captureStackTrace API.\n * @private {?string}\n */\n this.constructorStack_ = null;\n if (Error.captureStackTrace) {\n var target = { stack: '' };\n Error.captureStackTrace(target, goog.async.Deferred);\n // Check if Error.captureStackTrace worked. It fails in gjstest.\n if (typeof target.stack == 'string') {\n // Remove first line and force stringify to prevent memory leak due to\n // holding on to actual stack frames.\n this.constructorStack_ = target.stack.replace(/^[^\\n]*\\n/, '');\n }\n }\n }\n};\n\n\n/**\n * @define {boolean} Whether unhandled errors should always get rethrown to the\n * global scope. Defaults to false.\n */\ngoog.async.Deferred.STRICT_ERRORS =\n goog.define('goog.async.Deferred.STRICT_ERRORS', false);\n\n\n/**\n * @define {boolean} Whether to attempt to make stack traces long. Defaults to\n * false.\n */\ngoog.async.Deferred.LONG_STACK_TRACES =\n goog.define('goog.async.Deferred.LONG_STACK_TRACES', false);\n\n\n/**\n * Cancels a Deferred that has not yet been fired, or is blocked on another\n * deferred operation. If this Deferred is waiting for a blocking Deferred to\n * fire, the blocking Deferred will also be canceled.\n *\n * If this Deferred was created by calling branch() on a parent Deferred with\n * opt_propagateCancel set to true, the parent may also be canceled. If\n * opt_deepCancel is set, cancel() will be called on the parent (as well as any\n * other ancestors if the parent is also a branch). If one or more branches were\n * created with opt_propagateCancel set to true, the parent will be canceled if\n * cancel() is called on all of those branches.\n *\n * @param {boolean=} opt_deepCancel If true, cancels this Deferred's parent even\n * if cancel() hasn't been called on some of the parent's branches. Has no\n * effect on a branch without opt_propagateCancel set to true.\n */\ngoog.async.Deferred.prototype.cancel = function(opt_deepCancel) {\n if (!this.hasFired()) {\n if (this.parent_) {\n // Get rid of the parent reference before potentially running the parent's\n // canceler function to ensure that this cancellation isn't\n // double-counted.\n var parent = this.parent_;\n delete this.parent_;\n if (opt_deepCancel) {\n parent.cancel(opt_deepCancel);\n } else {\n parent.branchCancel_();\n }\n }\n\n if (this.onCancelFunction_) {\n // Call in user-specified scope.\n this.onCancelFunction_.call(this.defaultScope_, this);\n } else {\n this.silentlyCanceled_ = true;\n }\n if (!this.hasFired()) {\n this.errback(new goog.async.Deferred.CanceledError(this));\n }\n } else if (this.result_ instanceof goog.async.Deferred) {\n this.result_.cancel();\n }\n};\n\n\n/**\n * Handle a single branch being canceled. Once all branches are canceled, this\n * Deferred will be canceled as well.\n *\n * @private\n */\ngoog.async.Deferred.prototype.branchCancel_ = function() {\n this.branches_--;\n if (this.branches_ <= 0) {\n this.cancel();\n }\n};\n\n\n/**\n * Called after a blocking Deferred fires. Unblocks this Deferred and resumes\n * its execution sequence.\n *\n * @param {boolean} isSuccess Whether the result is a success or an error.\n * @param {*} res The result of the blocking Deferred.\n * @private\n */\ngoog.async.Deferred.prototype.continue_ = function(isSuccess, res) {\n this.blocked_ = false;\n this.updateResult_(isSuccess, res);\n};\n\n\n/**\n * Updates the current result based on the success or failure of the last action\n * in the execution sequence.\n *\n * @param {boolean} isSuccess Whether the new result is a success or an error.\n * @param {*} res The result.\n * @private\n */\ngoog.async.Deferred.prototype.updateResult_ = function(isSuccess, res) {\n this.fired_ = true;\n this.result_ = res;\n this.hadError_ = !isSuccess;\n this.fire_();\n};\n\n\n/**\n * Verifies that the Deferred has not yet been fired.\n *\n * @private\n * @throws {Error} If this has already been fired.\n */\ngoog.async.Deferred.prototype.check_ = function() {\n if (this.hasFired()) {\n if (!this.silentlyCanceled_) {\n throw new goog.async.Deferred.AlreadyCalledError(this);\n }\n this.silentlyCanceled_ = false;\n }\n};\n\n\n/**\n * Fire the execution sequence for this Deferred by passing the starting result\n * to the first registered callback.\n * @param {VALUE=} opt_result The starting result.\n */\ngoog.async.Deferred.prototype.callback = function(opt_result) {\n this.check_();\n this.assertNotDeferred_(opt_result);\n this.updateResult_(true /* isSuccess */, opt_result);\n};\n\n\n/**\n * Fire the execution sequence for this Deferred by passing the starting error\n * result to the first registered errback.\n * @param {*=} opt_result The starting error.\n */\ngoog.async.Deferred.prototype.errback = function(opt_result) {\n this.check_();\n this.assertNotDeferred_(opt_result);\n this.makeStackTraceLong_(opt_result);\n this.updateResult_(false /* isSuccess */, opt_result);\n};\n\n\n/**\n * Attempt to make the error's stack trace be long in that it contains the\n * stack trace from the point where the deferred was created on top of the\n * current stack trace to give additional context.\n * @param {*} error\n * @private\n * @suppress {missingProperties} error.stack\n */\ngoog.async.Deferred.prototype.makeStackTraceLong_ = function(error) {\n if (!goog.async.Deferred.LONG_STACK_TRACES) {\n return;\n }\n if (this.constructorStack_ && goog.isObject(error) && error.stack &&\n // Stack looks like it was system generated. See\n // https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi\n (/^[^\\n]+(\\n [^\\n]+)+/).test(error.stack)) {\n error.stack = error.stack + '\\nDEFERRED OPERATION:\\n' +\n this.constructorStack_;\n }\n};\n\n\n/**\n * Asserts that an object is not a Deferred.\n * @param {*} obj The object to test.\n * @throws {Error} Throws an exception if the object is a Deferred.\n * @private\n */\ngoog.async.Deferred.prototype.assertNotDeferred_ = function(obj) {\n goog.asserts.assert(\n !(obj instanceof goog.async.Deferred),\n 'An execution sequence may not be initiated with a blocking Deferred.');\n};\n\n\n/**\n * Register a callback function to be called with a successful result. If no\n * value is returned by the callback function, the result value is unchanged. If\n * a new value is returned, it becomes the Deferred result and will be passed to\n * the next callback in the execution sequence.\n *\n * If the function throws an error, the error becomes the new result and will be\n * passed to the next errback in the execution chain.\n *\n * If the function returns a Deferred, the execution sequence will be blocked\n * until that Deferred fires. Its result will be passed to the next callback (or\n * errback if it is an error result) in this Deferred's execution sequence.\n *\n * @param {function(this:T,VALUE):?} cb The function to be called with a\n * successful result.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @return {!goog.async.Deferred} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addCallback = function(cb, opt_scope) {\n return this.addCallbacks(cb, null, opt_scope);\n};\n\n\n/**\n * Register a callback function to be called with an error result. If no value\n * is returned by the function, the error result is unchanged. If a new error\n * value is returned or thrown, that error becomes the Deferred result and will\n * be passed to the next errback in the execution sequence.\n *\n * If the errback function handles the error by returning a non-error value,\n * that result will be passed to the next normal callback in the sequence.\n *\n * If the function returns a Deferred, the execution sequence will be blocked\n * until that Deferred fires. Its result will be passed to the next callback (or\n * errback if it is an error result) in this Deferred's execution sequence.\n *\n * @param {function(this:T,?):?} eb The function to be called on an\n * unsuccessful result.\n * @param {T=} opt_scope An optional scope to call the errback in.\n * @return {!goog.async.Deferred<VALUE>} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addErrback = function(eb, opt_scope) {\n return this.addCallbacks(null, eb, opt_scope);\n};\n\n\n/**\n * Registers one function as both a callback and errback.\n *\n * @param {function(this:T,?):?} f The function to be called on any result.\n * @param {T=} opt_scope An optional scope to call the function in.\n * @return {!goog.async.Deferred} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addBoth = function(f, opt_scope) {\n return this.addCallbacks(f, f, opt_scope);\n};\n\n\n/**\n * Like addBoth, but propagates uncaught exceptions in the errback.\n *\n * @param {function(this:T,?):?} f The function to be called on any result.\n * @param {T=} opt_scope An optional scope to call the function in.\n * @return {!goog.async.Deferred<VALUE>} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addFinally = function(f, opt_scope) {\n return this.addCallbacks(f, function(err) {\n var result = f.call(/** @type {?} */ (this), err);\n if (result === undefined) {\n throw err;\n }\n return result;\n }, opt_scope);\n};\n\n\n/**\n * Registers a callback function and an errback function at the same position\n * in the execution sequence. Only one of these functions will execute,\n * depending on the error state during the execution sequence.\n *\n * NOTE: This is not equivalent to {@code def.addCallback().addErrback()}! If\n * the callback is invoked, the errback will be skipped, and vice versa.\n *\n * @param {?(function(this:T,VALUE):?)} cb The function to be called on a\n * successful result.\n * @param {?(function(this:T,?):?)} eb The function to be called on an\n * unsuccessful result.\n * @param {T=} opt_scope An optional scope to call the functions in.\n * @return {!goog.async.Deferred} This Deferred.\n * @template T\n */\ngoog.async.Deferred.prototype.addCallbacks = function(cb, eb, opt_scope) {\n goog.asserts.assert(!this.blocking_, 'Blocking Deferreds can not be re-used');\n this.sequence_.push([cb, eb, opt_scope]);\n if (this.hasFired()) {\n this.fire_();\n }\n return this;\n};\n\n\n/**\n * Implements {@see goog.Thenable} for seamless integration with\n * {@see goog.Promise}.\n * Deferred results are mutable and may represent multiple values over\n * their lifetime. Calling `then` on a Deferred returns a Promise\n * with the result of the Deferred at that point in its callback chain.\n * Note that if the Deferred result is never mutated, and only\n * `then` calls are made, the Deferred will behave like a Promise.\n *\n * @override\n */\ngoog.async.Deferred.prototype.then = function(opt_onFulfilled, opt_onRejected,\n opt_context) {\n var resolve, reject;\n var promise = new goog.Promise(function(res, rej) {\n // Copying resolvers to outer scope, so that they are available when the\n // deferred callback fires (which may be synchronous).\n resolve = res;\n reject = rej;\n });\n this.addCallbacks(resolve, function(reason) {\n if (reason instanceof goog.async.Deferred.CanceledError) {\n promise.cancel();\n } else {\n reject(reason);\n }\n });\n return promise.then(opt_onFulfilled, opt_onRejected, opt_context);\n};\ngoog.Thenable.addImplementation(goog.async.Deferred);\n\n\n/**\n * Links another Deferred to the end of this Deferred's execution sequence. The\n * result of this execution sequence will be passed as the starting result for\n * the chained Deferred, invoking either its first callback or errback.\n *\n * @param {!goog.async.Deferred} otherDeferred The Deferred to chain.\n * @return {!goog.async.Deferred} This Deferred.\n */\ngoog.async.Deferred.prototype.chainDeferred = function(otherDeferred) {\n this.addCallbacks(\n otherDeferred.callback, otherDeferred.errback, otherDeferred);\n return this;\n};\n\n\n/**\n * Makes this Deferred wait for another Deferred's execution sequence to\n * complete before continuing.\n *\n * This is equivalent to adding a callback that returns `otherDeferred`,\n * but doesn't prevent additional callbacks from being added to\n * `otherDeferred`.\n *\n * @param {!goog.async.Deferred|!goog.Thenable} otherDeferred The Deferred\n * to wait for.\n * @return {!goog.async.Deferred} This Deferred.\n */\ngoog.async.Deferred.prototype.awaitDeferred = function(otherDeferred) {\n if (!(otherDeferred instanceof goog.async.Deferred)) {\n // The Thenable case.\n return this.addCallback(function() {\n return otherDeferred;\n });\n }\n return this.addCallback(goog.bind(otherDeferred.branch, otherDeferred));\n};\n\n\n/**\n * Creates a branch off this Deferred's execution sequence, and returns it as a\n * new Deferred. The branched Deferred's starting result will be shared with the\n * parent at the point of the branch, even if further callbacks are added to the\n * parent.\n *\n * All branches at the same stage in the execution sequence will receive the\n * same starting value.\n *\n * @param {boolean=} opt_propagateCancel If cancel() is called on every child\n * branch created with opt_propagateCancel, the parent will be canceled as\n * well.\n * @return {!goog.async.Deferred<VALUE>} A Deferred that will be started with\n * the computed result from this stage in the execution sequence.\n */\ngoog.async.Deferred.prototype.branch = function(opt_propagateCancel) {\n var d = new goog.async.Deferred();\n this.chainDeferred(d);\n if (opt_propagateCancel) {\n d.parent_ = this;\n this.branches_++;\n }\n return d;\n};\n\n\n/**\n * @return {boolean} Whether the execution sequence has been started on this\n * Deferred by invoking `callback` or `errback`.\n */\ngoog.async.Deferred.prototype.hasFired = function() {\n return this.fired_;\n};\n\n\n/**\n * @param {*} res The latest result in the execution sequence.\n * @return {boolean} Whether the current result is an error that should cause\n * the next errback to fire. May be overridden by subclasses to handle\n * special error types.\n * @protected\n */\ngoog.async.Deferred.prototype.isError = function(res) {\n return res instanceof Error;\n};\n\n\n/**\n * @return {boolean} Whether an errback exists in the remaining sequence.\n * @private\n */\ngoog.async.Deferred.prototype.hasErrback_ = function() {\n return goog.array.some(this.sequence_, function(sequenceRow) {\n // The errback is the second element in the array.\n return goog.isFunction(sequenceRow[1]);\n });\n};\n\n\n/**\n * Exhausts the execution sequence while a result is available. The result may\n * be modified by callbacks or errbacks, and execution will block if the\n * returned result is an incomplete Deferred.\n *\n * @private\n */\ngoog.async.Deferred.prototype.fire_ = function() {\n if (this.unhandledErrorId_ && this.hasFired() && this.hasErrback_()) {\n // It is possible to add errbacks after the Deferred has fired. If a new\n // errback is added immediately after the Deferred encountered an unhandled\n // error, but before that error is rethrown, the error is unscheduled.\n goog.async.Deferred.unscheduleError_(this.unhandledErrorId_);\n this.unhandledErrorId_ = 0;\n }\n\n if (this.parent_) {\n this.parent_.branches_--;\n delete this.parent_;\n }\n\n var res = this.result_;\n var unhandledException = false;\n var isNewlyBlocked = false;\n\n while (this.sequence_.length && !this.blocked_) {\n var sequenceEntry = this.sequence_.shift();\n\n var callback = sequenceEntry[0];\n var errback = sequenceEntry[1];\n var scope = sequenceEntry[2];\n\n var f = this.hadError_ ? errback : callback;\n if (f) {\n\n try {\n var ret = f.call(scope || this.defaultScope_, res);\n\n // If no result, then use previous result.\n if (ret !== undefined) {\n // Bubble up the error as long as the return value hasn't changed.\n this.hadError_ = this.hadError_ && (ret == res || this.isError(ret));\n this.result_ = res = ret;\n }\n\n if (goog.Thenable.isImplementedBy(res) ||\n (typeof goog.global['Promise'] === 'function' &&\n res instanceof goog.global['Promise'])) {\n isNewlyBlocked = true;\n this.blocked_ = true;\n }\n\n } catch (ex) {\n res = ex;\n this.hadError_ = true;\n this.makeStackTraceLong_(res);\n\n if (!this.hasErrback_()) {\n // If an error is thrown with no additional errbacks in the queue,\n // prepare to rethrow the error.\n unhandledException = true;\n }\n }\n }\n }\n\n this.result_ = res;\n\n if (isNewlyBlocked) {\n var onCallback = goog.bind(this.continue_, this, true /* isSuccess */);\n var onErrback = goog.bind(this.continue_, this, false /* isSuccess */);\n\n if (res instanceof goog.async.Deferred) {\n res.addCallbacks(onCallback, onErrback);\n res.blocking_ = true;\n } else {\n /** @type {!IThenable} */ (res).then(onCallback, onErrback);\n }\n } else if (goog.async.Deferred.STRICT_ERRORS && this.isError(res) &&\n !(res instanceof goog.async.Deferred.CanceledError)) {\n this.hadError_ = true;\n unhandledException = true;\n }\n\n if (unhandledException) {\n // Rethrow the unhandled error after a timeout. Execution will continue, but\n // the error will be seen by global handlers and the user. The throw will\n // be canceled if another errback is appended before the timeout executes.\n // The error's original stack trace is preserved where available.\n this.unhandledErrorId_ = goog.async.Deferred.scheduleError_(res);\n }\n};\n\n\n/**\n * Creates a Deferred that has an initial result.\n *\n * @param {*=} opt_result The result.\n * @return {!goog.async.Deferred} The new Deferred.\n */\ngoog.async.Deferred.succeed = function(opt_result) {\n var d = new goog.async.Deferred();\n d.callback(opt_result);\n return d;\n};\n\n\n/**\n * Creates a Deferred that fires when the given promise resolves.\n * Use only during migration to Promises.\n *\n * Note: If the promise resolves to a thenable value (which is not allowed by\n * conforming promise implementations), then the deferred may behave\n * unexpectedly as it tries to wait on it. This should not be a risk when using\n * goog.Promise, goog.async.Deferred, or native Promise objects.\n *\n * @param {!IThenable<T>} promise\n * @return {!goog.async.Deferred<T>} The new Deferred.\n * @template T\n */\ngoog.async.Deferred.fromPromise = function(promise) {\n var d = new goog.async.Deferred();\n promise.then(\n function(value) {\n d.callback(value);\n },\n function(error) {\n d.errback(error);\n });\n return d;\n};\n\n\n/**\n * Creates a Deferred that has an initial error result.\n *\n * @param {*} res The error result.\n * @return {!goog.async.Deferred} The new Deferred.\n */\ngoog.async.Deferred.fail = function(res) {\n var d = new goog.async.Deferred();\n d.errback(res);\n return d;\n};\n\n\n/**\n * Creates a Deferred that has already been canceled.\n *\n * @return {!goog.async.Deferred} The new Deferred.\n */\ngoog.async.Deferred.canceled = function() {\n var d = new goog.async.Deferred();\n d.cancel();\n return d;\n};\n\n\n/**\n * Normalizes values that may or may not be Deferreds.\n *\n * If the input value is a Deferred, the Deferred is branched (so the original\n * execution sequence is not modified) and the input callback added to the new\n * branch. The branch is returned to the caller.\n *\n * If the input value is not a Deferred, the callback will be executed\n * immediately and an already firing Deferred will be returned to the caller.\n *\n * In the following (contrived) example, if <code>isImmediate</code> is true\n * then 3 is alerted immediately, otherwise 6 is alerted after a 2-second delay.\n *\n * <pre>\n * var value;\n * if (isImmediate) {\n * value = 3;\n * } else {\n * value = new goog.async.Deferred();\n * setTimeout(function() { value.callback(6); }, 2000);\n * }\n *\n * var d = goog.async.Deferred.when(value, alert);\n * </pre>\n *\n * @param {*} value Deferred or normal value to pass to the callback.\n * @param {function(this:T, ?):?} callback The callback to execute.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @return {!goog.async.Deferred} A new Deferred that will call the input\n * callback with the input value.\n * @template T\n */\ngoog.async.Deferred.when = function(value, callback, opt_scope) {\n if (value instanceof goog.async.Deferred) {\n return value.branch(true).addCallback(callback, opt_scope);\n } else {\n return goog.async.Deferred.succeed(value).addCallback(callback, opt_scope);\n }\n};\n\n\n\n/**\n * An error sub class that is used when a Deferred has already been called.\n * @param {!goog.async.Deferred} deferred The Deferred.\n *\n * @constructor\n * @extends {goog.debug.Error}\n */\ngoog.async.Deferred.AlreadyCalledError = function(deferred) {\n goog.debug.Error.call(this);\n\n /**\n * The Deferred that raised this error.\n * @type {goog.async.Deferred}\n */\n this.deferred = deferred;\n};\ngoog.inherits(goog.async.Deferred.AlreadyCalledError, goog.debug.Error);\n\n\n/** @override */\ngoog.async.Deferred.AlreadyCalledError.prototype.message =\n 'Deferred has already fired';\n\n\n/** @override */\ngoog.async.Deferred.AlreadyCalledError.prototype.name = 'AlreadyCalledError';\n\n\n\n/**\n * An error sub class that is used when a Deferred is canceled.\n *\n * @param {!goog.async.Deferred} deferred The Deferred object.\n * @constructor\n * @extends {goog.debug.Error}\n */\ngoog.async.Deferred.CanceledError = function(deferred) {\n goog.debug.Error.call(this);\n\n /**\n * The Deferred that raised this error.\n * @type {goog.async.Deferred}\n */\n this.deferred = deferred;\n};\ngoog.inherits(goog.async.Deferred.CanceledError, goog.debug.Error);\n\n\n/** @override */\ngoog.async.Deferred.CanceledError.prototype.message = 'Deferred was canceled';\n\n\n/** @override */\ngoog.async.Deferred.CanceledError.prototype.name = 'CanceledError';\n\n\n\n/**\n * Wrapper around errors that are scheduled to be thrown by failing deferreds\n * after a timeout.\n *\n * @param {*} error Error from a failing deferred.\n * @constructor\n * @final\n * @private\n * @struct\n */\ngoog.async.Deferred.Error_ = function(error) {\n /** @const @private {number} */\n this.id_ = goog.global.setTimeout(goog.bind(this.throwError, this), 0);\n\n /** @const @private {*} */\n this.error_ = error;\n};\n\n\n/**\n * Actually throws the error and removes it from the list of pending\n * deferred errors.\n */\ngoog.async.Deferred.Error_.prototype.throwError = function() {\n goog.asserts.assert(goog.async.Deferred.errorMap_[this.id_],\n 'Cannot throw an error that is not scheduled.');\n delete goog.async.Deferred.errorMap_[this.id_];\n throw this.error_;\n};\n\n\n/**\n * Resets the error throw timer.\n */\ngoog.async.Deferred.Error_.prototype.resetTimer = function() {\n goog.global.clearTimeout(this.id_);\n};\n\n\n/**\n * Map of unhandled errors scheduled to be rethrown in a future timestep.\n * @private {!Object<(number|string), goog.async.Deferred.Error_>}\n */\ngoog.async.Deferred.errorMap_ = {};\n\n\n/**\n * Schedules an error to be thrown after a delay.\n * @param {*} error Error from a failing deferred.\n * @return {number} Id of the error.\n * @private\n */\ngoog.async.Deferred.scheduleError_ = function(error) {\n var deferredError = new goog.async.Deferred.Error_(error);\n goog.async.Deferred.errorMap_[deferredError.id_] = deferredError;\n return deferredError.id_;\n};\n\n\n/**\n * Unschedules an error from being thrown.\n * @param {number} id Id of the deferred error to unschedule.\n * @private\n */\ngoog.async.Deferred.unscheduleError_ = function(id) {\n var error = goog.async.Deferred.errorMap_[id];\n if (error) {\n error.resetTimer();\n delete goog.async.Deferred.errorMap_[id];\n }\n};\n\n\n/**\n * Asserts that there are no pending deferred errors. If there are any\n * scheduled errors, one will be thrown immediately to make this function fail.\n */\ngoog.async.Deferred.assertNoErrors = function() {\n var map = goog.async.Deferred.errorMap_;\n for (var key in map) {\n var error = map[key];\n error.resetTimer();\n error.throwError();\n }\n};\n","// Copyright 2011 The Closure Library Authors. All Rights Reserved.\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 * @fileoverview A utility to load JavaScript files via DOM script tags.\n * Refactored from goog.net.Jsonp. Works cross-domain.\n */\n\ngoog.provide('goog.net.jsloader');\ngoog.provide('goog.net.jsloader.Error');\ngoog.provide('goog.net.jsloader.ErrorCode');\ngoog.provide('goog.net.jsloader.Options');\n\ngoog.require('goog.array');\ngoog.require('goog.async.Deferred');\ngoog.require('goog.debug.Error');\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.object');\n\n\n/**\n * The name of the property of goog.global under which the JavaScript\n * verification object is stored by the loaded script.\n * @private {string}\n */\ngoog.net.jsloader.GLOBAL_VERIFY_OBJS_ = 'closure_verification';\n\n\n/**\n * The default length of time, in milliseconds, we are prepared to wait for a\n * load request to complete.\n * @type {number}\n */\ngoog.net.jsloader.DEFAULT_TIMEOUT = 5000;\n\n\n/**\n * Optional parameters for goog.net.jsloader.send.\n * timeout: The length of time, in milliseconds, we are prepared to wait\n * for a load request to complete, or 0 or negative for no timeout. Default\n * is 5 seconds.\n * document: The HTML document under which to load the JavaScript. Default is\n * the current document.\n * cleanupWhenDone: If true clean up the script tag after script completes to\n * load. This is important if you just want to read data from the JavaScript\n * and then throw it away. Default is false.\n * attributes: Additional attributes to set on the script tag.\n *\n * @typedef {{\n * timeout: (number|undefined),\n * document: (HTMLDocument|undefined),\n * cleanupWhenDone: (boolean|undefined),\n * attributes: (!Object<string, string>|undefined)\n * }}\n */\ngoog.net.jsloader.Options;\n\n\n/**\n * Scripts (URIs) waiting to be loaded.\n * @private {!Array<!goog.html.TrustedResourceUrl>}\n */\ngoog.net.jsloader.scriptsToLoad_ = [];\n\n\n/**\n * The deferred result of loading the URIs in scriptsToLoad_.\n * We need to return this to a caller that wants to load URIs while\n * a deferred is already working on them.\n * @private {!goog.async.Deferred<null>}\n */\ngoog.net.jsloader.scriptLoadingDeferred_;\n\n\n\n/**\n * Loads and evaluates the JavaScript files at the specified URIs, guaranteeing\n * the order of script loads.\n *\n * Because we have to load the scripts in serial (load script 1, exec script 1,\n * load script 2, exec script 2, and so on), this will be slower than doing\n * the network fetches in parallel.\n *\n * If you need to load a large number of scripts but dependency order doesn't\n * matter, you should just call goog.net.jsloader.safeLoad N times.\n *\n * If you need to load a large number of scripts on the same domain,\n * you may want to use goog.module.ModuleLoader.\n *\n * @param {Array<!goog.html.TrustedResourceUrl>} trustedUris The URIs to load.\n * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See\n * goog.net.jsloader.options documentation for details.\n * @return {!goog.async.Deferred} The deferred result, that may be used to add\n * callbacks\n */\ngoog.net.jsloader.safeLoadMany = function(trustedUris, opt_options) {\n // Loading the scripts in serial introduces asynchronosity into the flow.\n // Therefore, there are race conditions where client A can kick off the load\n // sequence for client B, even though client A's scripts haven't all been\n // loaded yet.\n //\n // To work around this issue, all module loads share a queue.\n if (!trustedUris.length) {\n return goog.async.Deferred.succeed(null);\n }\n\n var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length;\n goog.array.extend(goog.net.jsloader.scriptsToLoad_, trustedUris);\n if (isAnotherModuleLoading) {\n // jsloader is still loading some other scripts.\n // In order to prevent the race condition noted above, we just add\n // these URIs to the end of the scripts' queue and return the deferred\n // result of the ongoing script load, so the caller knows when they\n // finish loading.\n return goog.net.jsloader.scriptLoadingDeferred_;\n }\n\n trustedUris = goog.net.jsloader.scriptsToLoad_;\n var popAndLoadNextScript = function() {\n var trustedUri = trustedUris.shift();\n var deferred = goog.net.jsloader.safeLoad(trustedUri, opt_options);\n if (trustedUris.length) {\n deferred.addBoth(popAndLoadNextScript);\n }\n return deferred;\n };\n goog.net.jsloader.scriptLoadingDeferred_ = popAndLoadNextScript();\n return goog.net.jsloader.scriptLoadingDeferred_;\n};\n\n\n/**\n * Loads and evaluates a JavaScript file.\n * When the script loads, a user callback is called.\n * It is the client's responsibility to verify that the script ran successfully.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedUri The URI of the JavaScript.\n * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See\n * goog.net.jsloader.Options documentation for details.\n * @return {!goog.async.Deferred} The deferred result, that may be used to add\n * callbacks and/or cancel the transmission.\n * The error callback will be called with a single goog.net.jsloader.Error\n * parameter.\n */\ngoog.net.jsloader.safeLoad = function(trustedUri, opt_options) {\n var options = opt_options || {};\n var doc = options.document || document;\n var uri = goog.html.TrustedResourceUrl.unwrap(trustedUri);\n\n var script = goog.dom.createElement(goog.dom.TagName.SCRIPT);\n var request = {script_: script, timeout_: undefined};\n var deferred = new goog.async.Deferred(goog.net.jsloader.cancel_, request);\n\n // Set a timeout.\n var timeout = null;\n var timeoutDuration = (options.timeout != null) ?\n options.timeout :\n goog.net.jsloader.DEFAULT_TIMEOUT;\n if (timeoutDuration > 0) {\n timeout = window.setTimeout(function() {\n goog.net.jsloader.cleanup_(script, true);\n deferred.errback(\n new goog.net.jsloader.Error(\n goog.net.jsloader.ErrorCode.TIMEOUT,\n 'Timeout reached for loading script ' + uri));\n }, timeoutDuration);\n request.timeout_ = timeout;\n }\n\n // Hang the user callback to be called when the script completes to load.\n // NOTE(user): This callback will be called in IE even upon error. In any\n // case it is the client's responsibility to verify that the script ran\n // successfully.\n script.onload = script.onreadystatechange = function() {\n if (!script.readyState || script.readyState == 'loaded' ||\n script.readyState == 'complete') {\n var removeScriptNode = options.cleanupWhenDone || false;\n goog.net.jsloader.cleanup_(script, removeScriptNode, timeout);\n deferred.callback(null);\n }\n };\n\n // Add an error callback.\n // NOTE(user): Not supported in IE.\n script.onerror = function() {\n goog.net.jsloader.cleanup_(script, true, timeout);\n deferred.errback(\n new goog.net.jsloader.Error(\n goog.net.jsloader.ErrorCode.LOAD_ERROR,\n 'Error while loading script ' + uri));\n };\n\n var properties = options.attributes || {};\n goog.object.extend(\n properties, {'type': 'text/javascript', 'charset': 'UTF-8'});\n goog.dom.setProperties(script, properties);\n // NOTE(user): Safari never loads the script if we don't set the src\n // attribute before appending.\n goog.dom.safe.setScriptSrc(script, trustedUri);\n var scriptParent = goog.net.jsloader.getScriptParentElement_(doc);\n scriptParent.appendChild(script);\n\n return deferred;\n};\n\n\n/**\n * Loads a JavaScript file and verifies it was evaluated successfully, using a\n * verification object.\n * The verification object is set by the loaded JavaScript at the end of the\n * script.\n * We verify this object was set and return its value in the success callback.\n * If the object is not defined we trigger an error callback.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedUri The URI of the JavaScript.\n * @param {string} verificationObjName The name of the verification object that\n * the loaded script should set.\n * @param {goog.net.jsloader.Options} options Optional parameters. See\n * goog.net.jsloader.Options documentation for details.\n * @return {!goog.async.Deferred} The deferred result, that may be used to add\n * callbacks and/or cancel the transmission.\n * The success callback will be called with a single parameter containing\n * the value of the verification object.\n * The error callback will be called with a single goog.net.jsloader.Error\n * parameter.\n */\ngoog.net.jsloader.safeLoadAndVerify = function(\n trustedUri, verificationObjName, options) {\n // Define the global objects variable.\n if (!goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_]) {\n goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_] = {};\n }\n var verifyObjs = goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_];\n var uri = goog.html.TrustedResourceUrl.unwrap(trustedUri);\n\n // Verify that the expected object does not exist yet.\n if (verifyObjs[verificationObjName] !== undefined) {\n // TODO(user): Error or reset variable?\n return goog.async.Deferred.fail(\n new goog.net.jsloader.Error(\n goog.net.jsloader.ErrorCode.VERIFY_OBJECT_ALREADY_EXISTS,\n 'Verification object ' + verificationObjName +\n ' already defined.'));\n }\n\n // Send request to load the JavaScript.\n var sendDeferred = goog.net.jsloader.safeLoad(trustedUri, options);\n\n // Create a deferred object wrapping the send result.\n var deferred =\n new goog.async.Deferred(goog.bind(sendDeferred.cancel, sendDeferred));\n\n // Call user back with object that was set by the script.\n sendDeferred.addCallback(function() {\n var result = verifyObjs[verificationObjName];\n if (result !== undefined) {\n deferred.callback(result);\n delete verifyObjs[verificationObjName];\n } else {\n // Error: script was not loaded properly.\n deferred.errback(\n new goog.net.jsloader.Error(\n goog.net.jsloader.ErrorCode.VERIFY_ERROR, 'Script ' + uri +\n ' loaded, but verification object ' + verificationObjName +\n ' was not defined.'));\n }\n });\n\n // Pass error to new deferred object.\n sendDeferred.addErrback(function(error) {\n if (verifyObjs[verificationObjName] !== undefined) {\n delete verifyObjs[verificationObjName];\n }\n deferred.errback(error);\n });\n\n return deferred;\n};\n\n\n/**\n * Gets the DOM element under which we should add new script elements.\n * How? Take the first head element, and if not found take doc.documentElement,\n * which always exists.\n *\n * @param {!HTMLDocument} doc The relevant document.\n * @return {!Element} The script parent element.\n * @private\n */\ngoog.net.jsloader.getScriptParentElement_ = function(doc) {\n var headElements = goog.dom.getElementsByTagName(goog.dom.TagName.HEAD, doc);\n if (!headElements || goog.array.isEmpty(headElements)) {\n return doc.documentElement;\n } else {\n return headElements[0];\n }\n};\n\n\n/**\n * Cancels a given request.\n * @this {{script_: Element, timeout_: number}} The request context.\n * @private\n */\ngoog.net.jsloader.cancel_ = function() {\n var request = this;\n if (request && request.script_) {\n var scriptNode = request.script_;\n if (scriptNode && scriptNode.tagName == goog.dom.TagName.SCRIPT) {\n goog.net.jsloader.cleanup_(scriptNode, true, request.timeout_);\n }\n }\n};\n\n\n/**\n * Removes the script node and the timeout.\n * @param {Node} scriptNode The node to be cleaned up.\n * @param {boolean} removeScriptNode If true completely remove the script node.\n * @param {?number=} opt_timeout The timeout handler to cleanup.\n * @private\n * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration\n */\ngoog.net.jsloader.cleanup_ = function(\n scriptNode, removeScriptNode, opt_timeout) {\n if (opt_timeout != null) {\n goog.global.clearTimeout(opt_timeout);\n }\n\n scriptNode.onload = goog.nullFunction;\n scriptNode.onerror = goog.nullFunction;\n scriptNode.onreadystatechange = goog.nullFunction;\n\n // Do this after a delay (removing the script node of a running script can\n // confuse older IEs).\n if (removeScriptNode) {\n window.setTimeout(function() { goog.dom.removeNode(scriptNode); }, 0);\n }\n};\n\n\n/**\n * Possible error codes for jsloader.\n * @enum {number}\n */\ngoog.net.jsloader.ErrorCode = {\n LOAD_ERROR: 0,\n TIMEOUT: 1,\n VERIFY_ERROR: 2,\n VERIFY_OBJECT_ALREADY_EXISTS: 3,\n};\n\n\n\n/**\n * A jsloader error.\n *\n * @param {goog.net.jsloader.ErrorCode} code The error code.\n * @param {string=} opt_message Additional message.\n * @constructor\n * @extends {goog.debug.Error}\n * @final\n */\ngoog.net.jsloader.Error = function(code, opt_message) {\n var msg = 'Jsloader error (code #' + code + ')';\n if (opt_message) {\n msg += ': ' + opt_message;\n }\n goog.net.jsloader.Error.base(this, 'constructor', msg);\n\n /**\n * The code for this error.\n *\n * @type {goog.net.jsloader.ErrorCode}\n */\n this.code = code;\n};\ngoog.inherits(goog.net.jsloader.Error, goog.debug.Error);\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines fireauth.iframeclient.IframeWrapper used to communicate\n * with the hidden iframe to detect Auth events.\n */\n\ngoog.provide('fireauth.iframeclient.IframeWrapper');\n\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.net.jsloader');\ngoog.require('goog.string.Const');\n\n\n/**\n * Defines the hidden iframe wrapper for cross origin communications.\n * @param {string} url The hidden iframe src URL.\n * @constructor\n */\nfireauth.iframeclient.IframeWrapper = function(url) {\n /** @private {string} The hidden iframe URL. */\n this.url_ = url;\n\n /**\n * @type {?gapi.iframes.Iframe}\n * @private\n */\n this.iframe_ = null;\n\n /** @private {!goog.Promise} A promise that resolves on iframe open. */\n this.onIframeOpen_ = this.open_();\n};\n\n\n/**\n * @typedef {{\n * type: string\n * }}\n */\nfireauth.iframeclient.IframeWrapper.Message;\n\n/**\n * Returns URL, src of the hidden iframe.\n * @return {string}\n * @private\n */\nfireauth.iframeclient.IframeWrapper.prototype.getPath_ = function() {\n return this.url_;\n};\n\n\n/**\n * @return {!goog.Promise} The promise that resolves when the iframe is ready.\n */\nfireauth.iframeclient.IframeWrapper.prototype.onReady = function() {\n return this.onIframeOpen_;\n};\n\n\n/**\n * Returns options used to open the iframe.\n * @return {!gapi.iframes.OptionsBag}\n * @private\n */\nfireauth.iframeclient.IframeWrapper.prototype.getOptions_ = function() {\n var options = /** @type {!gapi.iframes.OptionsBag} */ ({\n 'where': document.body,\n 'url': this.getPath_(),\n 'messageHandlersFilter': /** @type {!gapi.iframes.IframesFilter} */ (\n fireauth.util.getObjectRef(\n 'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER')),\n 'attributes': {\n 'style': {\n 'position': 'absolute',\n 'top': '-100px',\n 'width': '1px',\n 'height': '1px'\n }\n },\n 'dontclear': true\n });\n return options;\n};\n\n\n/**\n * Opens an iframe.\n * @return {!goog.Promise} A promise that resolves on successful iframe open.\n * @private\n */\nfireauth.iframeclient.IframeWrapper.prototype.open_ = function() {\n var self = this;\n return fireauth.iframeclient.IframeWrapper.loadGApiJs_().then(function() {\n return new goog.Promise(function(resolve, reject) {\n /**\n * @param {?gapi.iframes.Iframe} iframe The new opened iframe.\n */\n var onOpen = function(iframe) {\n self.iframe_ = iframe;\n self.iframe_.restyle({\n // Prevent iframe from closing on mouse out.\n 'setHideOnLeave': false\n });\n // Confirm iframe is correctly loaded.\n // To fallback on failure, set a timeout.\n var networkErrorTimer = setTimeout(function() {\n reject(new Error('Network Error'));\n }, fireauth.iframeclient.IframeWrapper.PING_TIMEOUT_.get());\n // Clear timer and resolve pending iframe ready promise.\n var clearTimerAndResolve = function() {\n clearTimeout(networkErrorTimer);\n resolve();\n };\n // This returns an IThenable. However the reject part does not call\n // when the iframe is not loaded.\n iframe.ping(clearTimerAndResolve).then(\n clearTimerAndResolve,\n function(error) { reject(new Error('Network Error')); });\n };\n /** @type {function():!gapi.iframes.Context} */ (\n fireauth.util.getObjectRef('gapi.iframes.getContext'))().open(\n self.getOptions_(), onOpen);\n });\n });\n};\n\n\n/**\n * @param {!fireauth.iframeclient.IframeWrapper.Message} message to send.\n * @return {!goog.Promise<?Object>} The promise that resolve when message is\n * sent.\n */\nfireauth.iframeclient.IframeWrapper.prototype.sendMessage = function(message) {\n var self = this;\n return this.onIframeOpen_.then(function() {\n return new goog.Promise(function(resolve, reject) {\n self.iframe_.send(\n message['type'],\n message,\n resolve,\n /** @type {!gapi.iframes.IframesFilter} */ (\n fireauth.util.getObjectRef(\n 'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER')));\n\n });\n });\n};\n\n\n/**\n * Registers a listener to a post message.\n * @param {string} eventName The message to register for.\n * @param {gapi.iframes.MessageHandler} handler Message handler.\n */\nfireauth.iframeclient.IframeWrapper.prototype.registerEvent =\n function(eventName, handler) {\n var self = this;\n this.onIframeOpen_.then(function() {\n self.iframe_.register(\n eventName,\n /** @type {function(this:gapi.iframes.Iframe,\n * *, gapi.iframes.Iframe): *}\n */ (handler),\n /** @type {!gapi.iframes.IframesFilter} */ (\n fireauth.util.getObjectRef(\n 'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER')));\n });\n};\n\n\n/**\n * Unregisters a listener to a post message.\n * @param {string} eventName The message to unregister.\n * @param {gapi.iframes.MessageHandler} handler Message handler.\n */\nfireauth.iframeclient.IframeWrapper.prototype.unregisterEvent =\n function(eventName, handler) {\n var self = this;\n this.onIframeOpen_.then(function() {\n self.iframe_.unregister(\n eventName,\n /** @type {(function(this:gapi.iframes.Iframe,\n * *, gapi.iframes.Iframe): *|undefined)}\n */ (handler));\n });\n};\n\n\n/** @private @const {!goog.string.Const} The GApi loader URL. */\nfireauth.iframeclient.IframeWrapper.GAPI_LOADER_SRC_ = goog.string.Const.from(\n 'https://apis.google.com/js/api.js?onload=%{onload}');\n\n\n/**\n * @private @const {!fireauth.util.Delay} The gapi.load network error timeout\n * delay with units in ms.\n */\nfireauth.iframeclient.IframeWrapper.NETWORK_TIMEOUT_ =\n new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * @private @const {!fireauth.util.Delay} The iframe ping error timeout delay\n * with units in ms.\n */\nfireauth.iframeclient.IframeWrapper.PING_TIMEOUT_ =\n new fireauth.util.Delay(5000, 15000);\n\n\n/** @private {?goog.Promise} The cached GApi loader promise. */\nfireauth.iframeclient.IframeWrapper.cachedGApiLoader_ = null;\n\n\n/** Resets the cached GApi loader. */\nfireauth.iframeclient.IframeWrapper.resetCachedGApiLoader = function() {\n fireauth.iframeclient.IframeWrapper.cachedGApiLoader_ = null;\n};\n\n\n\n/**\n * Loads the GApi client library if it is not loaded for gapi.iframes usage.\n * @return {!goog.Promise} A promise that resolves when gapi.iframes is loaded.\n * @private\n */\nfireauth.iframeclient.IframeWrapper.loadGApiJs_ = function() {\n // If already pending or resolved, return the cached promise.\n if (fireauth.iframeclient.IframeWrapper.cachedGApiLoader_) {\n return fireauth.iframeclient.IframeWrapper.cachedGApiLoader_;\n }\n // If there is no cached promise, initialize a new one.\n fireauth.iframeclient.IframeWrapper.cachedGApiLoader_ =\n new goog.Promise(function(resolve, reject) {\n // Function to run when gapi.load is ready.\n var onGapiLoad = function() {\n // The developer may have tried to previously run gapi.load and failed.\n // Run this to fix that.\n fireauth.util.resetUnloadedGapiModules();\n var loader = /** @type {function(string, !Object)} */ (\n fireauth.util.getObjectRef('gapi.load'));\n loader('gapi.iframes', {\n 'callback': resolve,\n 'ontimeout': function() {\n // The above reset may be sufficient, but having this reset after\n // failure ensures that if the developer calls gapi.load after the\n // connection is re-established and before another attempt to embed\n // the iframe, it would work and would not be broken because of our\n // failed attempt.\n // Timeout when gapi.iframes.Iframe not loaded.\n fireauth.util.resetUnloadedGapiModules();\n reject(new Error('Network Error'));\n },\n 'timeout': fireauth.iframeclient.IframeWrapper.NETWORK_TIMEOUT_.get()\n });\n };\n if (fireauth.util.getObjectRef('gapi.iframes.Iframe')) {\n // If gapi.iframes.Iframe available, resolve.\n resolve();\n } else if (fireauth.util.getObjectRef('gapi.load')) {\n // Gapi loader ready, load gapi.iframes.\n onGapiLoad();\n } else {\n // Create a new iframe callback when this is called so as not to overwrite\n // any previous defined callback. This happens if this method is called\n // multiple times in parallel and could result in the later callback\n // overwriting the previous one. This would end up with a iframe\n // timeout.\n var cbName = '__iframefcb' +\n Math.floor(Math.random() * 1000000).toString();\n // GApi loader not available, dynamically load platform.js.\n goog.global[cbName] = function() {\n // GApi loader should be ready.\n if (fireauth.util.getObjectRef('gapi.load')) {\n onGapiLoad();\n } else {\n // Gapi loader failed, throw error.\n reject(new Error('Network Error'));\n }\n };\n // Build GApi loader.\n var url = goog.html.TrustedResourceUrl.format(\n fireauth.iframeclient.IframeWrapper.GAPI_LOADER_SRC_,\n {'onload': cbName});\n // Load GApi loader.\n var result = goog.Promise.resolve(goog.net.jsloader.safeLoad(url));\n result.thenCatch(function(error) {\n // In case library fails to load, typically due to a network error,\n // reset cached loader to null to force a refresh on a retrial.\n reject(new Error('Network Error'));\n });\n }\n }).thenCatch(function(error) {\n // Reset cached promise to allow for retrial.\n fireauth.iframeclient.IframeWrapper.cachedGApiLoader_ = null;\n throw error;\n });\n return fireauth.iframeclient.IframeWrapper.cachedGApiLoader_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.AsyncStorage');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\n\n\n/**\n * AsyncStorage provides an interface to the React Native AsyncStorage API.\n * @param {!Object=} opt_asyncStorage The AsyncStorage API. If not provided\n * this method will attempt to fetch an implementation from\n * firebase.INTERNAL.reactNative.\n * @constructor\n * @implements {fireauth.storage.Storage}\n * @see https://facebook.github.io/react-native/docs/asyncstorage.html\n */\nfireauth.storage.AsyncStorage = function(opt_asyncStorage) {\n /**\n * The underlying storage instance for persistent data.\n * @private\n */\n this.storage_ =\n opt_asyncStorage || (firebase.INTERNAL['reactNative'] &&\n firebase.INTERNAL['reactNative']['AsyncStorage']);\n\n if (!this.storage_) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'The React Native compatibility library was not found.');\n }\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.ASYNC_STORAGE;\n};\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.AsyncStorage.prototype.get = function(key) {\n return goog.Promise.resolve(this.storage_['getItem'](key))\n .then(function(val) {\n return val && fireauth.util.parseJSON(val);\n });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.AsyncStorage.prototype.set = function(key, value) {\n return goog.Promise.resolve(\n this.storage_['setItem'](key, fireauth.util.stringifyJSON(value)));\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.AsyncStorage.prototype.remove = function(key) {\n return goog.Promise.resolve(this.storage_['removeItem'](key));\n};\n\n\n/**\n * Does nothing. AsyncStorage does not support storage events,\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.AsyncStorage.prototype.addStorageListener = function(\n listener) {};\n\n\n/**\n * Does nothing. AsyncStorage does not support storage events,\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.AsyncStorage.prototype.removeStorageListener = function(\n listener) {};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.Storage');\n\n\n\n/**\n * Defines a generic interface to storage APIs across platforms.\n * @interface\n */\nfireauth.storage.Storage = function() {};\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n */\nfireauth.storage.Storage.prototype.get = function(key) {};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n */\nfireauth.storage.Storage.prototype.set = function(key, value) {};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n */\nfireauth.storage.Storage.prototype.remove = function(key) {};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)|function(!Array<string>)}\n * listener The storage event listener.\n */\nfireauth.storage.Storage.prototype.addStorageListener = function(listener) {};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)|function(!Array<string>)}\n * listener The storage event listener.\n */\nfireauth.storage.Storage.prototype.removeStorageListener = function(listener) {\n};\n\n\n/** @type {string} The storage type identifier. */\nfireauth.storage.Storage.prototype.type;\n\n\n/**\n * Enum for the identifier of the type of underlying storage.\n * @enum {string}\n */\nfireauth.storage.Storage.Type = {\n ASYNC_STORAGE: 'asyncStorage',\n IN_MEMORY: 'inMemory',\n INDEXEDDB: 'indexedDB',\n LOCAL_STORAGE: 'localStorage',\n MOCK_STORAGE: 'mockStorage',\n NULL_STORAGE: 'nullStorage',\n SESSION_STORAGE: 'sessionStorage'\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the MessageChannel based wrapper for receiving\n * messages from other windows or workers.\n */\n\ngoog.provide('fireauth.messagechannel.Receiver');\n\ngoog.require('fireauth.messagechannel.Status');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n/**\n * Initializes a channel to receive specific messages from a specified event\n * target.\n * Note receivers should not be manually instantiated. Instead `getInstance()`\n * should be used instead to get a receiver instance for a specified event\n * target.\n * @param {!EventTarget} eventTarget The event target to listen to.\n * @constructor\n */\nfireauth.messagechannel.Receiver = function(eventTarget) {\n /**\n * @const @private {!EventTarget} The messageChannel event target.\n */\n this.eventTarget_ = eventTarget;\n /**\n * @const @private {!Object.<string,\n * !Array<function(string, *):!goog.Promise<?>|void>>}\n * This is the event type to handlers hash map. It is used to hold the\n * corresponding handlers for specified events.\n */\n this.eventHandlers_ = {};\n /**\n * @const @private {function(!Event)} The internal 'message' event handler\n * used to reroute the request to corresponding subscribed handlers.\n */\n this.messageEventHandler_ = goog.bind(this.handleEvent_, this);\n};\n\n\n/**\n * @param {!EventTarget} eventTarget The event target to check for.\n * @return {boolean} Whether the receiver is listening to the specified event\n * target.\n */\nfireauth.messagechannel.Receiver.prototype.isListeningTo =\n function(eventTarget) {\n return this.eventTarget_ == eventTarget;\n};\n\n\n/**\n * @const @private {!Array<!fireauth.messagechannel.Receiver>} The list of all\n * created `fireauth.messagechannel.Receiver` instances.\n */\nfireauth.messagechannel.Receiver.receivers_ = [];\n\n\n/**\n * Return a receiver instance for the specified event target. This is needed\n * since one instance can be available per event target. Otherwise receivers\n * could clobber each other.\n * @param {!EventTarget} eventTarget The event target to listen to.\n * @return {!fireauth.messagechannel.Receiver} The receiver instance for the\n * specified event target.\n */\nfireauth.messagechannel.Receiver.getInstance = function(eventTarget) {\n // The results are stored in an array since objects can't be keys for other\n // objects. In addition, setting a unique property on an event target as a\n // hash map key may not be allowed due to CORS restrictions.\n var instance;\n goog.array.forEach(\n fireauth.messagechannel.Receiver.receivers_,\n function(receiver) {\n if (receiver.isListeningTo(eventTarget)) {\n instance = receiver;\n }\n });\n if (!instance) {\n instance = new fireauth.messagechannel.Receiver(eventTarget);\n fireauth.messagechannel.Receiver.receivers_.push(instance);\n }\n return instance;\n};\n\n\n/**\n * Handles a PostMessage event based on the following protocol:\n * <ul>\n * <li>When an event is first detected, check there is a subscribed handler.\n * If not, do nothing as there could be other listeners.</li>\n * <li>If there is a subscribed event, reply with an ACK event to notify the\n * sender that the event can be handled.</li>\n * <li>Trigger the subscribed handlers.</li>\n * <li>Reply again with the combined results of all subscribed handlers and\n * return the response back.</li>\n * </ul>\n *\n * @param {!Event} event The PostMessage event to handle.\n * @private\n */\nfireauth.messagechannel.Receiver.prototype.handleEvent_ = function(event) {\n // Respond to sender first with ack reply. This will let the client\n // know that the service worker can handle this event.\n var eventType = event.data['eventType'];\n var eventId = event.data['eventId'];\n var handlers = this.eventHandlers_[eventType];\n if (handlers && handlers.length > 0) {\n // Event can be handled.\n event.ports[0].postMessage({\n 'status': fireauth.messagechannel.Status.ACK,\n 'eventId': eventId,\n 'eventType': eventType,\n 'response': null\n });\n var promises = [];\n goog.array.forEach(handlers, function(handler) {\n // Wrap in promise in case the handler doesn't return a promise.\n promises.push(goog.Promise.resolve().then(function() {\n return handler(event.origin, event.data['data']);\n }));\n });\n // allSettled is more flexible as it executes all the promises passed and\n // returns whether they succeeded or failed.\n goog.Promise.allSettled(promises)\n .then(function(result) {\n // allResponse has the format:\n // !Array<!{fulfilled: boolean, value: (*|undefined),\n // reason: (*|undefined)}>\n // Respond to sender with ack reply.\n // De-obfuscate the allSettled result.\n var allResponses = [];\n goog.array.forEach(result, function(item) {\n allResponses.push({\n 'fulfilled': item.fulfilled,\n 'value': item.value,\n // Error cannot be clone in postMessage.\n 'reason': item.reason ? item.reason.message : undefined\n });\n });\n // Remove undefined fields.\n goog.array.forEach(allResponses, function(item) {\n for (var key in item) {\n if (typeof item[key] === 'undefined') {\n delete item[key];\n }\n }\n });\n event.ports[0].postMessage({\n 'status': fireauth.messagechannel.Status.DONE,\n 'eventId': eventId,\n 'eventType': eventType,\n 'response': allResponses\n });\n });\n }\n // Let unsupported events time out, as there could be external receivers\n // that can handle them.\n};\n\n\n/**\n * Subscribes to events of the specified type.\n * @param {string} eventType The event type to listen to.\n * @param {function(string, *):!goog.Promise<?>|void} handler The async callback\n * function to run when the event is triggered.\n */\nfireauth.messagechannel.Receiver.prototype.subscribe =\n function(eventType, handler) {\n if (goog.object.isEmpty(this.eventHandlers_)) {\n this.eventTarget_.addEventListener('message', this.messageEventHandler_);\n }\n if (typeof this.eventHandlers_[eventType] === 'undefined') {\n this.eventHandlers_[eventType] = [];\n }\n this.eventHandlers_[eventType].push(handler);\n};\n\n\n/**\n * Unsubscribes the specified handler from the specified event. If no handler\n * is specified, all handlers are unsubscribed.\n * @param {string} eventType The event type to unsubscribe from.\n * @param {?function(string, *):!goog.Promise<?>|void=} opt_handler The\n * callback function to unsubscribe from the specified event type. If none\n * is specified, all handlers are unsubscribed.\n */\nfireauth.messagechannel.Receiver.prototype.unsubscribe =\n function(eventType, opt_handler) {\n if (typeof this.eventHandlers_[eventType] !== 'undefined' && opt_handler) {\n goog.array.removeAllIf(this.eventHandlers_[eventType], function(ele) {\n return ele == opt_handler;\n });\n if (this.eventHandlers_[eventType].length == 0) {\n delete this.eventHandlers_[eventType];\n }\n } else if (!opt_handler) {\n // Unsubscribe all handlers for speficied event.\n delete this.eventHandlers_[eventType];\n }\n if (goog.object.isEmpty(this.eventHandlers_)) {\n this.eventTarget_.removeEventListener('message', this.messageEventHandler_);\n }\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the MessageChannel common utilities and enums.\n */\n\ngoog.provide('fireauth.messagechannel.Error');\ngoog.provide('fireauth.messagechannel.Status');\ngoog.provide('fireauth.messagechannel.TimeoutDuration');\ngoog.provide('fireauth.messagechannel.utils');\n\n\n/**\n * Enum for the messagechannel error messages. These errors are not meant to be\n * user facing.\n * @enum {string}\n */\nfireauth.messagechannel.Error = {\n CONNECTION_CLOSED: 'connection_closed',\n CONNECTION_UNAVAILABLE: 'connection_unavailable',\n INVALID_RESPONSE: 'invalid_response',\n TIMEOUT: 'timeout',\n UNKNOWN: 'unknown_error',\n UNSUPPORTED_EVENT: 'unsupported_event'\n};\n\n\n/**\n * Enum for the message channel request status labels.\n * @enum {string}\n */\nfireauth.messagechannel.Status = {\n ACK: 'ack',\n DONE: 'done'\n};\n\n\n/**\n * Enum for the timeout durations in milliseconds for different contexts.\n * @enum {number}\n */\nfireauth.messagechannel.TimeoutDuration = {\n ACK: 50,\n COMPLETION: 3000,\n // Used when a handler is confirmed to be available on the other side.\n LONG_ACK: 800\n};\n\n\n/**\n * @param {?string=} opt_prefix An optional prefix string to prepend to ID.\n * @param {?number=} opt_digits An optional number of digits used for event ID.\n * @return {string} The generated event ID used to identify a generic event.\n */\nfireauth.messagechannel.utils.generateEventId =\n function(opt_prefix, opt_digits) {\n // 0, null and undefined will default to 20.\n var digits = opt_digits || 20;\n return opt_prefix ? opt_prefix : '' +\n Math.floor(Math.random() * Math.pow(10, digits)).toString();\n};\n\n\n/**\n * @return {?MessageChannel} The initialized MessageChannel instance if\n * supported.\n */\nfireauth.messagechannel.utils.initializeMessageChannel = function() {\n return typeof MessageChannel !== 'undefined' ? new MessageChannel() : null;\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the PostMessager interface needed for the\n * `fireauth.messagechannel.Sender`, in addition to 2 types of implementations.\n */\n\ngoog.provide('fireauth.messagechannel.PostMessager');\ngoog.provide('fireauth.messagechannel.WindowPostMessager');\ngoog.provide('fireauth.messagechannel.WorkerClientPostMessager');\n\n\n/**\n * This is the interface defining the postMessage format of a window which\n * takes an additional second parameter for target origin.\n *\n * @typedef {{\n * postMessage: function(*, string, !Array<!Transferable>)\n * }}\n */\nfireauth.messagechannel.Window;\n\n\n/**\n * This is the interface defining the postMessage format of a worker or\n * ServiceWorkerClient, etc. which just takes a message and a list of\n * Transferables.\n *\n * @typedef {{\n * postMessage: function(*, !Array<!Transferable>)\n * }}\n */\nfireauth.messagechannel.WorkerClient;\n\n\n/**\n * Defines a common interface to postMessage data to a specified PostMessager.\n * @interface\n */\nfireauth.messagechannel.PostMessager = function() {};\n\n\n/**\n * Sends a message to the specified context.\n * @param {*} message The message to send.\n * @param {!Array<!Transferable>} transfer The list of `Transferable` objects\n * that are transferred with the message. The ownsership fo these objects is\n * given to the destination side and they are no longer usable on the\n * sending side.\n */\nfireauth.messagechannel.PostMessager.prototype.postMessage =\n function(message, transfer) {};\n\n\n\n/**\n * Defines the implementation for postMessaging to a window context.\n * @param {!fireauth.messagechannel.Window} win The window PostMessager.\n * @param {?string=} opt_targetOrigin The target origin.\n * @constructor\n * @implements {fireauth.messagechannel.PostMessager}\n */\nfireauth.messagechannel.WindowPostMessager = function(win, opt_targetOrigin) {\n /**\n * @const @private {!fireauth.messagechannel.Window} The window PostMessager.\n */\n this.win_ = win;\n /** @const @private {string} The postMessage target origin. */\n this.targetOrigin_ = opt_targetOrigin || '*';\n};\n\n\n/**\n * Sends a message to the specified window context.\n * @param {*} message The message to send.\n * @param {!Array<!Transferable>} transfer The list of `Transferable` objects\n * that are transferred with the message. The ownsership fo these objects is\n * given to the destination side and they are no longer usable on the\n * sending side.\n * @override\n */\nfireauth.messagechannel.WindowPostMessager.prototype.postMessage =\n function(message, transfer) {\n this.win_.postMessage(message, this.targetOrigin_, transfer);\n};\n\n\n/**\n * Defines the implementation for postMessaging to a worker/client context.\n * @param {!fireauth.messagechannel.WorkerClient} worker The worker/client\n * PostMessager.\n * @constructor\n * @implements {fireauth.messagechannel.PostMessager}\n */\nfireauth.messagechannel.WorkerClientPostMessager = function(worker) {\n /**\n * @const @private {!fireauth.messagechannel.WorkerClient} The worker/client\n * PostMessager.\n */\n this.worker_ = worker;\n};\n\n\n/**\n * Sends a message to the specified worker/client context.\n * @param {*} message The message to send.\n * @param {!Array<!Transferable>} transfer The list of `Transferable` objects\n * that are transferred with the message. The ownsership fo these objects is\n * given to the destination side and they are no longer usable on the\n * sending side.\n * @override\n */\nfireauth.messagechannel.WorkerClientPostMessager.prototype.postMessage =\n function(message, transfer) {\n this.worker_.postMessage(message, transfer);\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the MessageChannel based wrapper for sending messages\n * to other windows or workers.\n */\n\ngoog.provide('fireauth.messagechannel.Sender');\n\ngoog.require('fireauth.messagechannel.Error');\ngoog.require('fireauth.messagechannel.PostMessager');\ngoog.require('fireauth.messagechannel.Status');\ngoog.require('fireauth.messagechannel.TimeoutDuration');\ngoog.require('fireauth.messagechannel.utils');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\n\n\n/**\n * This is the interface defining a MessageChannel/handler pair.\n *\n * @typedef {{\n * onMessage: function(!Event),\n * messageChannel: !MessageChannel\n * }}\n */\nfireauth.messagechannel.MessageHandler;\n\n\n/**\n * Helper static function to create messageChannel errors.\n * @param {!fireauth.messagechannel.Error} errorId The error identifier.\n * @param {?string=} opt_message The optional error message used for generic\n * error types.\n * @return {!Error} The constructed error to return.\n * @private\n */\nfireauth.messagechannel.createError_ = function(errorId, opt_message) {\n if (errorId != fireauth.messagechannel.Error.UNKNOWN || !opt_message) {\n return new Error(errorId);\n } else {\n return new Error(opt_message);\n }\n};\n\n\n/**\n * Initializes a channel to send specific messages to a specified PostMessage.\n * @param {!fireauth.messagechannel.PostMessager} postMessager The post messager\n * to send messages to.\n * @constructor\n */\nfireauth.messagechannel.Sender = function(postMessager) {\n /**\n * @const @private {!fireauth.messagechannel.PostMessager} The messageChannel\n * PostMessager.\n */\n this.postMessager_ = postMessager;\n /** @private {boolean} Whether the connection was closed. */\n this.closed_ = false;\n /**\n * @const @private {!Array<!fireauth.messagechannel.MessageHandler>} The list\n * of subscribed message handlers and their corresponding MessageChannels.\n */\n this.messageHandlers_ = [];\n};\n\n\n/**\n * Sends a message to the receiver. The message is identified by an event\n * type and can carry additional payload data.\n * The sender protocol works as follows:\n * <ul>\n * <li>The request is constructed and postMessaged to the receiver with the port\n * used to reply back to sender.</li>\n * <li>The operation will block until an ACK response is received. If not, it\n * will timeout and reject with an error.</li>\n * <li>If an ACK response is received, it will wait longer for the full\n * processed response.</li>\n * <li>Once the response is received, the operation will resolve with that\n * result.</li>\n * </ul>\n *\n * @param {string} eventType The event type identifying the message. This is\n * used to help the receiver handle this message.\n * @param {?Object=} opt_data The optional data to send along the message.\n * @param {?boolean=} opt_useLongTimeout Whether long timeout should be used\n * for ACK responses.\n * @return {!goog.Promise<!Array<{fulfilled: boolean,\n * value: (*|undefined),\n * reason: (*|undefined)}>>} A promise that\n * resolves with the receiver responses.\n */\nfireauth.messagechannel.Sender.prototype.send = function(\n eventType, opt_data, opt_useLongTimeout) {\n var self = this;\n var eventId;\n var data = opt_data || {};\n var onMessage;\n var ackTimer;\n var completionTimer;\n var entry = null;\n if (this.closed_) {\n return goog.Promise.reject(fireauth.messagechannel.createError_(\n fireauth.messagechannel.Error.CONNECTION_UNAVAILABLE));\n }\n var ackTimeout =\n !!opt_useLongTimeout ?\n fireauth.messagechannel.TimeoutDuration.LONG_ACK :\n fireauth.messagechannel.TimeoutDuration.ACK;\n var messageChannel =\n fireauth.messagechannel.utils.initializeMessageChannel();\n return new goog.Promise(function(resolve, reject) {\n // Send message along with port for reply\n if (messageChannel) {\n eventId = fireauth.messagechannel.utils.generateEventId();\n // Start the connection if not already started.\n messageChannel.port1.start();\n // Handler for receiving message reply from receiver.\n // Blocks promise resolution until service worker detects the change.\n ackTimer = setTimeout(function() {\n // The receiver may not be able to handle the response for various\n // reasons: library not included, or an incompatible version of\n // the library is included.\n // Timeout after some time.\n reject(fireauth.messagechannel.createError_(\n fireauth.messagechannel.Error.UNSUPPORTED_EVENT));\n }, ackTimeout);\n onMessage = function(event) {\n // Process only the expected events that match current event ID.\n if (event.data['eventId'] !== eventId) {\n return;\n }\n // This avoids adding a long wait when the receiver is unable to handle\n // the event.\n if (event.data['status'] === fireauth.messagechannel.Status.ACK) {\n clearTimeout(ackTimer);\n // Set longer timeout to allow receiver to process.\n completionTimer = setTimeout(function() {\n reject(fireauth.messagechannel.createError_(\n fireauth.messagechannel.Error.TIMEOUT));\n }, fireauth.messagechannel.TimeoutDuration.COMPLETION);\n return;\n } else if (event.data['status'] ===\n fireauth.messagechannel.Status.DONE) {\n clearTimeout(completionTimer);\n if (typeof event.data['response'] !== 'undefined') {\n resolve(event.data['response']);\n } else {\n reject(fireauth.messagechannel.createError_(\n fireauth.messagechannel.Error.UNKNOWN));\n }\n } else {\n clearTimeout(ackTimer);\n clearTimeout(completionTimer);\n reject(fireauth.messagechannel.createError_(\n fireauth.messagechannel.Error.INVALID_RESPONSE));\n }\n };\n entry = {\n 'messageChannel': messageChannel,\n 'onMessage': onMessage\n };\n self.messageHandlers_.push(entry);\n messageChannel.port1.addEventListener('message', onMessage);\n var request = {\n 'eventType': eventType,\n 'eventId': eventId,\n 'data': data\n };\n // It is possible the receiver cannot handle this result.\n // For example, the developer may not be including the library in the\n // receiver or using an outdated version.\n self.postMessager_.postMessage(\n request,\n [messageChannel.port2]);\n } else {\n // No connection available.\n reject(fireauth.messagechannel.createError_(\n fireauth.messagechannel.Error.CONNECTION_UNAVAILABLE));\n }\n }).then(function(result) {\n // On completion, remove the message handler. A new one is needed for a\n // new message.\n self.removeMessageHandler_(entry);\n return result;\n }).thenCatch(function(error) {\n // On failure, remove the message handler. A new one is needed for a new\n // message.\n self.removeMessageHandler_(entry);\n throw error;\n });\n};\n\n\n/**\n * Removes the onMessage handler for the specified messageChannel.\n * @param {?fireauth.messagechannel.MessageHandler} messageHandler\n * @private\n */\nfireauth.messagechannel.Sender.prototype.removeMessageHandler_ =\n function(messageHandler) {\n if (!messageHandler) {\n return;\n }\n var messageChannel = messageHandler['messageChannel'];\n var onMessage = messageHandler['onMessage'];\n if (messageChannel) {\n messageChannel.port1.removeEventListener('message', onMessage);\n messageChannel.port1.close();\n }\n goog.array.removeAllIf(this.messageHandlers_, function(ele) {\n return ele == messageHandler;\n });\n};\n\n\n/** Closes the underlying MessageChannel connection. */\nfireauth.messagechannel.Sender.prototype.close = function() {\n // Any pending event will timeout.\n while (this.messageHandlers_.length > 0) {\n this.removeMessageHandler_(this.messageHandlers_[0]);\n }\n this.closed_ = true;\n};\n\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines a local storage interface with an indexedDB\n * implementation to be used as a fallback with browsers that do not synchronize\n * local storage changes between different windows of the same origin.\n */\n\ngoog.provide('fireauth.storage.IndexedDB');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.messagechannel.Receiver');\ngoog.require('fireauth.messagechannel.Sender');\ngoog.require('fireauth.messagechannel.WorkerClientPostMessager');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.array');\n\n\n\n/**\n * Initialize an indexedDB local storage manager used to mimic local storage\n * using an indexedDB underlying implementation including the ability to listen\n * to storage changes by key similar to localstorage storage event.\n * @param {string} dbName The indexedDB database name where all local storage\n * data is to be stored.\n * @param {string} objectStoreName The indexedDB object store name where all\n * local storage data is to be stored.\n * @param {string} dataKeyPath The indexedDB object store index name used to key\n * all local storage data.\n * @param {string} valueKeyPath The indexedDB object store value field for each\n * entry.\n * @param {number} version The indexedDB database version number.\n * @param {?IDBFactory=} opt_indexedDB The optional IndexedDB factory object.\n * @implements {fireauth.storage.Storage}\n * @constructor\n */\nfireauth.storage.IndexedDB = function(\n dbName,\n objectStoreName,\n dataKeyPath,\n valueKeyPath,\n version,\n opt_indexedDB) {\n // indexedDB not available, fail hard.\n if (!fireauth.storage.IndexedDB.isAvailable()) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n }\n /**\n * @const @private {string} The indexedDB database name where all local\n * storage data is to be stored.\n */\n this.dbName_ = dbName;\n /**\n * @const @private {string} The indexedDB object store name where all local\n * storage data is to be stored.\n */\n this.objectStoreName_ = objectStoreName;\n /**\n * @const @private {string} The indexedDB object store index name used to key\n * all local storage data.\n */\n this.dataKeyPath_ = dataKeyPath;\n /**\n * @const @private {string} The indexedDB object store value field for each\n * entry.\n */\n this.valueKeyPath_ = valueKeyPath;\n /** @const @private {number} The indexedDB database version number. */\n this.version_ = version;\n /** @private {!Object.<string, *>} The local indexedDB map copy. */\n this.localMap_ = {};\n /**\n * @private {!Array<function(!Array<string>)>} Listeners to storage events.\n */\n this.storageListeners_ = [];\n /** @private {number} The indexedDB pending write operations tracker. */\n this.pendingOpsTracker_ = 0;\n /** @private {!IDBFactory} The indexedDB factory object. */\n this.indexedDB_ = /** @type {!IDBFactory} */ (\n opt_indexedDB || goog.global.indexedDB);\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.INDEXEDDB;\n /**\n * @private {?goog.Promise<void>} The pending polling promise for syncing\n * unprocessed indexedDB external changes.\n */\n this.poll_ = null;\n /**\n * @private {?number} The poll timer ID for syncing external indexedDB\n * changes.\n */\n this.pollTimerId_ = null;\n /**\n * @private {?fireauth.messagechannel.Receiver} The messageChannel receiver if\n * running from a serviceworker.\n */\n this.receiver_ = null;\n /**\n * @private {?fireauth.messagechannel.Sender} The messageChannel sender to\n * send keyChanged messages to the service worker from the client.\n */\n this.sender_ = null;\n /**\n * @private {boolean} Whether the service worker has a receiver for the\n * keyChanged events.\n */\n this.serviceWorkerReceiverAvailable_ = false;\n /** @private {?ServiceWorker} The current active service worker. */\n this.activeServiceWorker_ = null;\n var scope = this;\n if (fireauth.util.getWorkerGlobalScope()) {\n this.receiver_ = fireauth.messagechannel.Receiver.getInstance(\n /** @type {!WorkerGlobalScope} */ (\n fireauth.util.getWorkerGlobalScope()));\n // Listen to indexedDB changes.\n this.receiver_.subscribe('keyChanged', function(origin, request) {\n // Sync data.\n return scope.sync_().then(function(keys) {\n // Trigger listeners if unhandled changes are detected.\n if (keys.length > 0) {\n goog.array.forEach(\n scope.storageListeners_,\n function(listener) {\n listener(keys);\n });\n }\n // When this is false, it means the change was already\n // detected and processed before the notification.\n return {\n 'keyProcessed': goog.array.contains(keys, request['key'])\n };\n });\n });\n // Used to inform sender that service worker what events it supports.\n this.receiver_.subscribe('ping', function(origin, request) {\n return goog.Promise.resolve(['keyChanged']);\n });\n } else {\n // Get active service worker when its available.\n fireauth.util.getActiveServiceWorker()\n .then(function(sw) {\n scope.activeServiceWorker_ = sw;\n if (sw) {\n // Initialize the sender.\n scope.sender_ = new fireauth.messagechannel.Sender(\n new fireauth.messagechannel.WorkerClientPostMessager(sw));\n // Ping the service worker to check what events they can handle.\n // Use long timeout.\n scope.sender_.send('ping', null, true)\n .then(function(results) {\n // Check if keyChanged is supported.\n if (results[0]['fulfilled'] &&\n goog.array.contains(results[0]['value'], 'keyChanged')) {\n scope.serviceWorkerReceiverAvailable_ = true;\n }\n })\n .thenCatch(function(error) {\n // Ignore error.\n });\n }\n });\n }\n};\n\n\n\n/**\n * The indexedDB database name where all local storage data is to be stored.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.DB_NAME_ = 'firebaseLocalStorageDb';\n\n\n/**\n * The indexedDB object store name where all local storage data is to be stored.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.DATA_OBJECT_STORE_NAME_ = 'firebaseLocalStorage';\n\n\n/**\n * The indexedDB object store index name used to key all local storage data.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.DATA_KEY_PATH_ = 'fbase_key';\n\n\n/**\n * The indexedDB object store value field for each entry.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.VALUE_KEY_PATH_ = 'value';\n\n\n/**\n * The indexedDB database version number.\n * @private @const {number}\n */\nfireauth.storage.IndexedDB.VERSION_ = 1;\n\n\n/**\n * The indexedDB polling delay time in milliseconds.\n * @private @const {number}\n */\nfireauth.storage.IndexedDB.POLLING_DELAY_ = 800;\n\n\n/**\n * The indexedDB polling stop error.\n * @private @const {string}\n */\nfireauth.storage.IndexedDB.STOP_ERROR_ = 'STOP_EVENT';\n\n\n\n/**\n * @return {!fireauth.storage.IndexedDB} The Firebase Auth indexedDB\n * local storage manager.\n */\nfireauth.storage.IndexedDB.getFireauthManager = function() {\n if (!fireauth.storage.IndexedDB.managerInstance_) {\n fireauth.storage.IndexedDB.managerInstance_ =\n new fireauth.storage.IndexedDB(\n fireauth.storage.IndexedDB.DB_NAME_,\n fireauth.storage.IndexedDB.DATA_OBJECT_STORE_NAME_,\n fireauth.storage.IndexedDB.DATA_KEY_PATH_,\n fireauth.storage.IndexedDB.VALUE_KEY_PATH_,\n fireauth.storage.IndexedDB.VERSION_);\n }\n return fireauth.storage.IndexedDB.managerInstance_;\n};\n\n\n/**\n * Delete the indexedDB database.\n * @return {!goog.Promise<!IDBDatabase>} A promise that resolves on successful\n * database deletion.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.deleteDb_ = function() {\n var self = this;\n return new goog.Promise(function(resolve, reject) {\n var request = self.indexedDB_.deleteDatabase(self.dbName_);\n request.onsuccess = function(event) {\n resolve();\n };\n request.onerror = function(event) {\n reject(new Error(event.target.error));\n };\n });\n};\n\n\n/**\n * Initializes The indexedDB database, creates it if not already created and\n * opens it.\n * @return {!goog.Promise<!IDBDatabase>} A promise for the database object.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.initializeDb_ = function() {\n var self = this;\n return new goog.Promise(function(resolve, reject) {\n var request = self.indexedDB_.open(self.dbName_, self.version_);\n request.onerror = function(event) {\n // Suppress this from surfacing to browser console.\n try {\n event.preventDefault();\n } catch (e) {}\n reject(new Error(event.target.error));\n };\n request.onupgradeneeded = function(event) {\n var db = event.target.result;\n try {\n db.createObjectStore(\n self.objectStoreName_,\n {\n 'keyPath': self.dataKeyPath_\n });\n } catch (e) {\n reject(e);\n }\n };\n request.onsuccess = function(event) {\n var db = event.target.result;\n // Strange bug that occurs in Firefox when multiple tabs are opened at the\n // same time. The only way to recover seems to be deleting the database\n // and re-initializing it.\n // https://github.com/firebase/firebase-js-sdk/issues/634\n if (!db.objectStoreNames.contains(self.objectStoreName_)) {\n self.deleteDb_()\n .then(function() {\n return self.initializeDb_();\n })\n .then(function(newDb) {\n resolve(newDb);\n })\n .thenCatch(function(e) {\n reject(e);\n });\n } else {\n resolve(db);\n }\n };\n });\n};\n\n\n/**\n * Checks if indexedDB is initialized, if so, the callback is run, otherwise,\n * it waits for the db to initialize and then runs the callback function.\n * @return {!goog.Promise<!IDBDatabase>} A promise for the initialized indexedDB\n * database.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.initializeDbAndRun_ =\n function() {\n if (!this.initPromise_) {\n this.initPromise_ = this.initializeDb_();\n }\n return this.initPromise_;\n};\n\n\n/**\n * @return {boolean} Whether indexedDB is available or not.\n */\nfireauth.storage.IndexedDB.isAvailable = function() {\n try {\n return !!goog.global['indexedDB'];\n } catch (e) {\n return false;\n }\n};\n\n\n/**\n * Creates a reference for the local storage indexedDB object store and returns\n * it.\n * @param {!IDBTransaction} tx The IDB transaction instance.\n * @return {!IDBObjectStore} The indexedDB object store.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.getDataObjectStore_ =\n function(tx) {\n return tx.objectStore(this.objectStoreName_);\n};\n\n\n/**\n * Creates an IDB transaction and returns it.\n * @param {!IDBDatabase} db The indexedDB instance.\n * @param {boolean} isReadWrite Whether the current indexedDB operation is a\n * read/write operation or not.\n * @return {!IDBTransaction} The requested IDB transaction instance.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.getTransaction_ =\n function(db, isReadWrite) {\n var tx = db.transaction(\n [this.objectStoreName_],\n isReadWrite ? 'readwrite' : 'readonly');\n return tx;\n};\n\n\n/**\n * @param {!IDBRequest} request The IDB request instance.\n * @return {!goog.Promise} The promise to resolve on transaction completion.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.onIDBRequest_ =\n function(request) {\n return new goog.Promise(function(resolve, reject) {\n request.onsuccess = function(event) {\n if (event && event.target) {\n resolve(event.target.result);\n } else {\n resolve();\n }\n };\n request.onerror = function(event) {\n reject(event.target.error);\n };\n });\n};\n\n\n/**\n * Sets the item's identified by the key provided to the value passed. If the\n * item does not exist, it is created. An optional callback is run on success.\n * @param {string} key The storage key for the item to set. If the item exists,\n * it is updated, otherwise created.\n * @param {*} value The value to store for the item to set.\n * @return {!goog.Promise<void>} A promise that resolves on operation success.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.set = function(key, value) {\n var isLocked = false;\n var dbTemp;\n var self = this;\n return this.initializeDbAndRun_()\n .then(function(db) {\n dbTemp = db;\n var objectStore = self.getDataObjectStore_(\n self.getTransaction_(dbTemp, true));\n return self.onIDBRequest_(objectStore.get(key));\n })\n .then(function(data) {\n var objectStore = self.getDataObjectStore_(\n self.getTransaction_(dbTemp, true));\n if (data) {\n // Update the value(s) in the object that you want to change\n data.value = value;\n // Put this updated object back into the database.\n return self.onIDBRequest_(objectStore.put(data));\n }\n self.pendingOpsTracker_++;\n isLocked = true;\n var obj = {};\n obj[self.dataKeyPath_] = key;\n obj[self.valueKeyPath_] = value;\n return self.onIDBRequest_(objectStore.add(obj));\n })\n .then(function() {\n // Save in local copy to avoid triggering false external event.\n self.localMap_[key] = value;\n // Announce change in key to service worker.\n return self.notifySW_(key);\n })\n .thenAlways(function() {\n if (isLocked) {\n self.pendingOpsTracker_--;\n }\n });\n};\n\n\n/**\n * Notify the service worker of the indexeDB write operation.\n * Waits until the operation is processed.\n * @param {string} key The key which is changing.\n * @return {!goog.Promise<void>} A promise that resolves on delivery.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.notifySW_ = function(key) {\n // If sender is available.\n // Run some sanity check to confirm no sw change occurred.\n // For now, we support one service worker per page.\n if (this.sender_ &&\n this.activeServiceWorker_ &&\n fireauth.util.getServiceWorkerController() ===\n this.activeServiceWorker_) {\n return this.sender_.send(\n 'keyChanged',\n {'key': key},\n // Use long timeout if receiver is known to be available.\n this.serviceWorkerReceiverAvailable_)\n .then(function(responses) {\n // Return nothing.\n })\n .thenCatch(function(error) {\n // This is a best effort approach. Ignore errors.\n });\n }\n return goog.Promise.resolve();\n};\n\n\n/**\n * Retrieves a stored item identified by the key provided asynchronously.\n * The value is passed to the callback function provided.\n * @param {string} key The storage key for the item to fetch.\n * @return {!goog.Promise} A promise that resolves with the item's value, or\n * null if the item is not found.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.get = function(key) {\n var self = this;\n return this.initializeDbAndRun_()\n .then(function(db) {\n return self.onIDBRequest_(\n self.getDataObjectStore_(self.getTransaction_(db, false)).get(key));\n })\n .then(function(response) {\n return response && response.value;\n });\n};\n\n\n/**\n * Deletes the item identified by the key provided and on success, runs the\n * optional callback.\n * @param {string} key The storage key for the item to remove.\n * @return {!goog.Promise<void>} A promise that resolves on operation success.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.remove = function(key) {\n var isLocked = false;\n var self = this;\n return this.initializeDbAndRun_()\n .then(function(db) {\n isLocked = true;\n self.pendingOpsTracker_++;\n return self.onIDBRequest_(\n self.getDataObjectStore_(\n self.getTransaction_(db, true))['delete'](key));\n }).then(function() {\n // Delete from local copy to avoid triggering false external event.\n delete self.localMap_[key];\n // Announce change in key to service worker.\n return self.notifySW_(key);\n }).thenAlways(function() {\n if (isLocked) {\n self.pendingOpsTracker_--;\n }\n });\n};\n\n\n/**\n * @return {!goog.Promise<!Array<string>>} A promise that resolved with all the\n * storage keys that have changed.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.sync_ = function() {\n var self = this;\n return this.initializeDbAndRun_()\n .then(function(db) {\n var objectStore =\n self.getDataObjectStore_(self.getTransaction_(db, false));\n if (objectStore['getAll']) {\n // Get all keys and value pairs using getAll if supported.\n return self.onIDBRequest_(objectStore['getAll']());\n } else {\n // If getAll isn't supported, fallback to cursor.\n return new goog.Promise(function(resolve, reject) {\n var res = [];\n var request = objectStore.openCursor();\n request.onsuccess = function(event) {\n var cursor = event.target.result;\n if (cursor) {\n res.push(cursor.value);\n cursor['continue']();\n } else {\n resolve(res);\n }\n };\n request.onerror = function(event) {\n reject(event.target.error);\n };\n });\n }\n }).then(function(res) {\n var centralCopy = {};\n // List of keys differing from central copy.\n var diffKeys = [];\n // Build central copy (external copy).\n if (self.pendingOpsTracker_ == 0) {\n for (var i = 0; i < res.length; i++) {\n centralCopy[res[i][self.dataKeyPath_]] =\n res[i][self.valueKeyPath_];\n }\n // Get diff of central copy and local copy.\n diffKeys = fireauth.util.getKeyDiff(self.localMap_, centralCopy);\n // Update local copy.\n self.localMap_ = centralCopy;\n }\n // Return modified keys.\n return diffKeys;\n });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!Array<string>)} listener The storage event listener.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.addStorageListener =\n function(listener) {\n // First listener, start listeners.\n if (this.storageListeners_.length == 0) {\n this.startListeners_();\n }\n this.storageListeners_.push(listener);\n};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!Array<string>)} listener The storage event listener.\n * @override\n */\nfireauth.storage.IndexedDB.prototype.removeStorageListener =\n function(listener) {\n goog.array.removeAllIf(\n this.storageListeners_,\n function(ele) {\n return ele == listener;\n });\n // No more listeners, stop.\n if (this.storageListeners_.length == 0) {\n this.stopListeners_();\n }\n};\n\n\n/**\n * Removes all listeners to storage event change.\n */\nfireauth.storage.IndexedDB.prototype.removeAllStorageListeners =\n function() {\n this.storageListeners_ = [];\n // No more listeners, stop.\n this.stopListeners_();\n};\n\n\n/**\n * Starts the listener to storage events.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.startListeners_ = function() {\n var self = this;\n // Stop any previous listeners.\n this.stopListeners_();\n var repeat = function() {\n self.pollTimerId_ = setTimeout(\n function() {\n self.poll_ = self.sync_()\n .then(function(keys) {\n // If keys modified, call listeners.\n if (keys.length > 0) {\n goog.array.forEach(\n self.storageListeners_,\n function(listener) {\n listener(keys);\n });\n }\n })\n .then(function() {\n repeat();\n })\n .thenCatch(function(error) {\n if (error.message != fireauth.storage.IndexedDB.STOP_ERROR_) {\n repeat();\n }\n });\n },\n fireauth.storage.IndexedDB.POLLING_DELAY_);\n };\n repeat();\n};\n\n\n/**\n * Stops the listener to storage events.\n * @private\n */\nfireauth.storage.IndexedDB.prototype.stopListeners_ = function() {\n if (this.poll_) {\n // Cancel polling function.\n this.poll_.cancel(fireauth.storage.IndexedDB.STOP_ERROR_);\n }\n // Clear any pending polling timer.\n if (this.pollTimerId_) {\n clearTimeout(this.pollTimerId_);\n this.pollTimerId_ = null;\n }\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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\ngoog.provide('fireauth.storage.HybridIndexedDB');\n\ngoog.require('fireauth.storage.IndexedDB');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\n\n/**\n * HybridStorage provides an interface to indexedDB, the persistent Web\n * Storage API for browsers that support it. This will fallback to the provided\n * fallback storage when indexedDB is not supported which is determined\n * asynchronously.\n * @param {!fireauth.storage.Storage} fallbackStorage The storage to fallback to\n * when indexedDB is not available.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.HybridIndexedDB = function(fallbackStorage) {\n var self = this;\n var storage = null;\n /**\n * @const @private {!Array<function((!goog.events.BrowserEvent|\n * !Array<string>))>} The storage listeners.\n */\n this.storageListeners_ = [];\n // This type may change if the fallback is used.\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.INDEXEDDB;\n /**\n * @const @private {!fireauth.storage.Storage} The fallback storage when\n * indexedDB is unavailable.\n */\n this.fallbackStorage_ = fallbackStorage;\n /**\n * @const @private {!goog.Promise<!fireauth.storage.Storage>} A promise that\n * resolves with the underlying indexedDB storage or a fallback when not\n * supported.\n */\n this.underlyingStoragePromise_ = goog.Promise.resolve().then(function() {\n // Initial check shows indexedDB is available. This is not enough.\n // Try to write/read from indexedDB. If it fails, switch to fallback.\n if (fireauth.storage.IndexedDB.isAvailable()) {\n // Test write/read using a random key. This is important for the following\n // reasons:\n // 1. Double inclusion of the firebase-auth.js library.\n // 2. Multiple windows opened at the same time.\n // The above may cause collision if multiple instances try to\n // write/read/delete from the same entry.\n var randomId = fireauth.util.generateEventId();\n var randomKey = fireauth.storage.HybridIndexedDB.KEY_ + randomId;\n storage = fireauth.storage.IndexedDB.getFireauthManager();\n return storage.set(randomKey, randomId)\n .then(function() {\n return storage.get(randomKey);\n })\n .then(function(value) {\n if (value !== randomId) {\n throw new Error('indexedDB not supported!');\n }\n return storage.remove(randomKey);\n })\n .then(function() {\n return storage;\n })\n .thenCatch(function(error) {\n return self.fallbackStorage_;\n });\n } else {\n // indexedDB not available, use fallback.\n return self.fallbackStorage_;\n }\n }).then(function(storage) {\n // Update type.\n self.type = storage.type;\n // Listen to all storage changes.\n storage.addStorageListener(function(key) {\n // Trigger all attached storage listeners.\n goog.array.forEach(self.storageListeners_, function(listener) {\n listener(key);\n });\n });\n return storage;\n });\n};\n\n\n/**\n * The key used to check if the storage instance is available.\n * @private {string}\n * @const\n */\nfireauth.storage.HybridIndexedDB.KEY_ = '__sak';\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.get = function(key) {\n return this.underlyingStoragePromise_.then(function(storage) {\n return storage.get(key);\n });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.set = function(key, value) {\n return this.underlyingStoragePromise_.then(function(storage) {\n return storage.set(key, value);\n });\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.remove = function(key) {\n return this.underlyingStoragePromise_.then(function(storage) {\n return storage.remove(key);\n });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function((!goog.events.BrowserEvent|!Array<string>))} listener The\n * storage event listener.\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.addStorageListener =\n function(listener) {\n this.storageListeners_.push(listener);\n};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.HybridIndexedDB.prototype.removeStorageListener =\n function(listener) {\n goog.array.removeAllIf(this.storageListeners_, function(ele) {\n return ele == listener;\n });\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.InMemoryStorage');\n\ngoog.require('goog.Promise');\n\n\n\n/**\n * InMemoryStorage provides an implementation of Storage that will only persist\n * data in memory. This data is volatile and in a browser environment, will\n * be lost on page unload and will only be available in the current window.\n * This is a useful fallback for browsers where web storage is disabled or\n * environments where the preferred storage mechanism is not available or not\n * supported.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.InMemoryStorage = function() {\n /** @protected {!Object} The object where we store values. */\n this.storage = {};\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.IN_MEMORY;\n};\n\n\n/**\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.InMemoryStorage.prototype.get = function(key) {\n return goog.Promise.resolve(/** @type {*} */ (this.storage[key]));\n};\n\n\n/**\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.InMemoryStorage.prototype.set = function(key, value) {\n this.storage[key] = value;\n return goog.Promise.resolve();\n};\n\n\n/**\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.InMemoryStorage.prototype.remove = function(key) {\n delete this.storage[key];\n return goog.Promise.resolve();\n};\n\n\n/**\n * @param {function((!goog.events.BrowserEvent|!Array<string>))} listener The\n * storage event listener.\n * @override\n */\nfireauth.storage.InMemoryStorage.prototype.addStorageListener =\n function(listener) {\n};\n\n\n/**\n * @param {function((!goog.events.BrowserEvent|!Array<string>))} listener The\n * storage event listener.\n * @override\n */\nfireauth.storage.InMemoryStorage.prototype.removeStorageListener = function(\n listener) {};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.LocalStorage');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.events');\n\n\n\n/**\n * LocalStorage provides an interface to localStorage, the persistent Web\n * Storage API.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.LocalStorage = function() {\n // Check is localStorage available in the current environment.\n if (!fireauth.storage.LocalStorage.isAvailable()) {\n // In a Node.js environment, dom-storage module needs to be required.\n if (fireauth.util.getEnvironment() == fireauth.util.Env.NODE) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'The LocalStorage compatibility library was not found.');\n }\n throw new fireauth.AuthError(\n fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n }\n\n /**\n * The underlying storage instance for persistent data.\n * @private {!Storage}\n */\n this.storage_ = /** @type {!Storage} */ (\n fireauth.storage.LocalStorage.getGlobalStorage() ||\n firebase.INTERNAL['node']['localStorage']);\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.LOCAL_STORAGE;\n};\n\n\n/** @return {?Storage|undefined} The global localStorage instance. */\nfireauth.storage.LocalStorage.getGlobalStorage = function() {\n try {\n var storage = goog.global['localStorage'];\n // Try editing web storage. If an error is thrown, it may be disabled.\n var key = fireauth.util.generateEventId();\n if (storage) {\n storage['setItem'](key, '1');\n storage['removeItem'](key);\n }\n return storage;\n } catch (e) {\n // In some cases, browsers with web storage disabled throw an error simply\n // on access.\n return null;\n }\n};\n\n\n/**\n * The key used to check if the storage instance is available.\n * @private {string}\n * @const\n */\nfireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_ = '__sak';\n\n\n/** @return {boolean} Whether localStorage is available. */\nfireauth.storage.LocalStorage.isAvailable = function() {\n // In Node.js localStorage is polyfilled.\n var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE;\n // Either window should provide this storage mechanism or in case of Node.js,\n // firebase.INTERNAL should provide it.\n var storage = fireauth.storage.LocalStorage.getGlobalStorage() ||\n (isNode &&\n firebase.INTERNAL['node'] &&\n firebase.INTERNAL['node']['localStorage']);\n if (!storage) {\n return false;\n }\n try {\n // setItem will throw an exception if we cannot access web storage (e.g.,\n // Safari in private mode).\n storage.setItem(fireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_, '1');\n storage.removeItem(fireauth.storage.LocalStorage.STORAGE_AVAILABLE_KEY_);\n return true;\n } catch (e) {\n return false;\n }\n};\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.LocalStorage.prototype.get = function(key) {\n var self = this;\n return goog.Promise.resolve()\n .then(function() {\n var json = self.storage_.getItem(key);\n return fireauth.util.parseJSON(json);\n });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.LocalStorage.prototype.set = function(key, value) {\n var self = this;\n return goog.Promise.resolve()\n .then(function() {\n var obj = fireauth.util.stringifyJSON(value);\n if (obj === null) {\n self.remove(key);\n } else {\n self.storage_.setItem(key, obj);\n }\n });\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.LocalStorage.prototype.remove = function(key) {\n var self = this;\n return goog.Promise.resolve()\n .then(function() {\n self.storage_.removeItem(key);\n });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.LocalStorage.prototype.addStorageListener = function(\n listener) {\n if (goog.global['window']) {\n goog.events.listen(goog.global['window'], 'storage', listener);\n }\n};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.LocalStorage.prototype.removeStorageListener = function(\n listener) {\n if (goog.global['window']) {\n goog.events.unlisten(goog.global['window'], 'storage', listener);\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.NullStorage');\n\ngoog.require('fireauth.storage.Storage');\ngoog.require('goog.Promise');\n\n\n\n/**\n * NullStorage provides an implementation of Storage that does always returns\n * null. This can be used if a type of storage is unsupported on a platform.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.NullStorage = function() {\n /** @private {!Object} The object where we store values. */\n this.storage_ = {};\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.NULL_STORAGE;\n};\n\n\n/**\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.NullStorage.prototype.get = function(key) {\n return goog.Promise.resolve(/** @type {*} */ (null));\n};\n\n\n/**\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.NullStorage.prototype.set = function(key, value) {\n return goog.Promise.resolve();\n};\n\n\n/**\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.NullStorage.prototype.remove = function(key) {\n return goog.Promise.resolve();\n};\n\n\n/**\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.NullStorage.prototype.addStorageListener = function(listener) {\n};\n\n\n/**\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.NullStorage.prototype.removeStorageListener = function(\n listener) {};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.SessionStorage');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\n\n\n\n/**\n * SessionStorage provides an interface to sessionStorage, the temporary web\n * storage API.\n * @constructor\n * @implements {fireauth.storage.Storage}\n */\nfireauth.storage.SessionStorage = function() {\n // Check is sessionStorage available in the current environment.\n if (!fireauth.storage.SessionStorage.isAvailable()) {\n // In a Node.js environment, dom-storage module needs to be required.\n if (fireauth.util.getEnvironment() == fireauth.util.Env.NODE) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'The SessionStorage compatibility library was not found.');\n }\n throw new fireauth.AuthError(\n fireauth.authenum.Error.WEB_STORAGE_UNSUPPORTED);\n }\n\n /**\n * The underlying storage instance for temporary data.\n * @private {!Storage}\n */\n this.storage_ = /** @type {!Storage} */ (\n fireauth.storage.SessionStorage.getGlobalStorage() ||\n firebase.INTERNAL['node']['sessionStorage']);\n /** @public {string} The storage type identifier. */\n this.type = fireauth.storage.Storage.Type.SESSION_STORAGE;\n};\n\n\n/** @return {?Storage|undefined} The global sessionStorage instance. */\nfireauth.storage.SessionStorage.getGlobalStorage = function() {\n try {\n var storage = goog.global['sessionStorage'];\n // Try editing web storage. If an error is thrown, it may be disabled.\n var key = fireauth.util.generateEventId();\n if (storage) {\n storage['setItem'](key, '1');\n storage['removeItem'](key);\n }\n return storage;\n } catch (e) {\n // In some cases, browsers with web storage disabled throw an error simply\n // on access.\n return null;\n }\n};\n\n\n/**\n * The key used to check if the storage instance is available.\n * @private {string}\n * @const\n */\nfireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_ = '__sak';\n\n\n/** @return {boolean} Whether sessionStorage is available. */\nfireauth.storage.SessionStorage.isAvailable = function() {\n // In Node.js sessionStorage is polyfilled.\n var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE;\n // Either window should provide this storage mechanism or in case of Node.js,\n // firebase.INTERNAL should provide it.\n var storage = fireauth.storage.SessionStorage.getGlobalStorage() ||\n (isNode &&\n firebase.INTERNAL['node'] &&\n firebase.INTERNAL['node']['sessionStorage']);\n if (!storage) {\n return false;\n }\n try {\n // setItem will throw an exception if we cannot access web storage (e.g.,\n // Safari in private mode).\n storage.setItem(\n fireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_, '1');\n storage.removeItem(fireauth.storage.SessionStorage.STORAGE_AVAILABLE_KEY_);\n return true;\n } catch (e) {\n return false;\n }\n};\n\n\n/**\n * Retrieves the value stored at the key.\n * @param {string} key\n * @return {!goog.Promise<*>}\n * @override\n */\nfireauth.storage.SessionStorage.prototype.get = function(key) {\n var self = this;\n return goog.Promise.resolve()\n .then(function() {\n var json = self.storage_.getItem(key);\n return fireauth.util.parseJSON(json);\n });\n};\n\n\n/**\n * Stores the value at the specified key.\n * @param {string} key\n * @param {*} value\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.SessionStorage.prototype.set = function(key, value) {\n var self = this;\n return goog.Promise.resolve()\n .then(function() {\n var obj = fireauth.util.stringifyJSON(value);\n if (obj === null) {\n self.remove(key);\n } else {\n self.storage_.setItem(key, obj);\n }\n });\n};\n\n\n/**\n * Removes the value at the specified key.\n * @param {string} key\n * @return {!goog.Promise<void>}\n * @override\n */\nfireauth.storage.SessionStorage.prototype.remove = function(key) {\n var self = this;\n return goog.Promise.resolve()\n .then(function() {\n self.storage_.removeItem(key);\n });\n};\n\n\n/**\n * Adds a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.SessionStorage.prototype.addStorageListener = function(\n listener) {};\n\n\n/**\n * Removes a listener to storage event change.\n * @param {function(!goog.events.BrowserEvent)} listener The storage event\n * listener.\n * @override\n */\nfireauth.storage.SessionStorage.prototype.removeStorageListener = function(\n listener) {};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.storage.Factory');\ngoog.provide('fireauth.storage.Factory.EnvConfig');\n\ngoog.require('fireauth.storage.AsyncStorage');\ngoog.require('fireauth.storage.HybridIndexedDB');\ngoog.require('fireauth.storage.InMemoryStorage');\ngoog.require('fireauth.storage.LocalStorage');\ngoog.require('fireauth.storage.NullStorage');\ngoog.require('fireauth.storage.SessionStorage');\ngoog.require('fireauth.util');\n\n\n/**\n * Factory manages the storage implementations and determines the correct one\n * for the current environment.\n * @param {!fireauth.storage.Factory.EnvConfigType} env The storage\n * configuration for the current environment.\n * @constructor\n */\nfireauth.storage.Factory = function(env) {\n /** @const @private {!fireauth.storage.Factory.EnvConfigType} */\n this.env_ = env;\n};\n\n\n/**\n * Construct the singleton instance of the Factory, automatically detecting\n * the current environment.\n * @return {!fireauth.storage.Factory}\n */\nfireauth.storage.Factory.getInstance = function() {\n if (!fireauth.storage.Factory.instance_) {\n fireauth.storage.Factory.instance_ =\n new fireauth.storage.Factory(fireauth.storage.Factory.getEnvConfig());\n }\n return fireauth.storage.Factory.instance_;\n};\n\n\n/**\n * @typedef {{\n * persistent: function(new:fireauth.storage.Storage),\n * temporary: function(new:fireauth.storage.Storage)\n * }}\n */\nfireauth.storage.Factory.EnvConfigType;\n\n\n/**\n * Configurations of storage for different environments.\n * @enum {!fireauth.storage.Factory.EnvConfigType}\n */\nfireauth.storage.Factory.EnvConfig = {\n BROWSER: {\n persistent: fireauth.storage.LocalStorage,\n temporary: fireauth.storage.SessionStorage\n },\n NODE: {\n persistent: fireauth.storage.LocalStorage,\n temporary: fireauth.storage.SessionStorage\n },\n REACT_NATIVE: {\n persistent: fireauth.storage.AsyncStorage,\n temporary: fireauth.storage.NullStorage\n },\n WORKER: {\n persistent: fireauth.storage.LocalStorage,\n temporary: fireauth.storage.NullStorage\n }\n};\n\n\n/**\n * Detects the current environment and returns the appropriate environment\n * configuration.\n * @return {!fireauth.storage.Factory.EnvConfigType}\n */\nfireauth.storage.Factory.getEnvConfig = function() {\n var envMap = {};\n envMap[fireauth.util.Env.BROWSER] =\n fireauth.storage.Factory.EnvConfig.BROWSER;\n envMap[fireauth.util.Env.NODE] =\n fireauth.storage.Factory.EnvConfig.NODE;\n envMap[fireauth.util.Env.REACT_NATIVE] =\n fireauth.storage.Factory.EnvConfig.REACT_NATIVE;\n envMap[fireauth.util.Env.WORKER] =\n fireauth.storage.Factory.EnvConfig.WORKER; \n return envMap[fireauth.util.getEnvironment()];\n};\n\n\n/**\n * @return {!fireauth.storage.Storage} The persistent storage instance.\n */\nfireauth.storage.Factory.prototype.makePersistentStorage = function() {\n if (fireauth.util.persistsStorageWithIndexedDB()) {\n // If persistent storage is implemented using indexedDB, use indexedDB.\n // Use HybridIndexedDB instead of indexedDB directly since this will\n // fallback to a fallback storage when indexedDB is not supported (private\n // browsing mode, etc).\n return new fireauth.storage.HybridIndexedDB(\n fireauth.util.isWorker() ?\n new fireauth.storage.InMemoryStorage() : new this.env_.persistent());\n }\n return new this.env_.persistent();\n};\n\n\n/**\n * @return {!fireauth.storage.Storage} The temporary storage instance.\n */\nfireauth.storage.Factory.prototype.makeTemporaryStorage = function() {\n return new this.env_.temporary();\n};\n\n\n/**\n * @return {!fireauth.storage.Storage} An in memory storage instance.\n */\nfireauth.storage.Factory.prototype.makeInMemoryStorage = function() {\n return new fireauth.storage.InMemoryStorage();\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 * @fileoverview Defines utilities for session management.\n */\n\ngoog.provide('fireauth.authStorage');\ngoog.provide('fireauth.authStorage.Key');\ngoog.provide('fireauth.authStorage.Manager');\ngoog.provide('fireauth.authStorage.Persistence');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.storage.Factory');\ngoog.require('fireauth.storage.IndexedDB');\ngoog.require('fireauth.storage.Storage');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.events');\ngoog.require('goog.object');\n\n\n\n/**\n * The namespace for Firebase Auth storage.\n * @private @const {string}\n */\nfireauth.authStorage.NAMESPACE_ = 'firebase';\n\n\n/**\n * The separator for Firebase Auth storage with App ID key.\n * @private @const {string}\n */\nfireauth.authStorage.SEPARATOR_ = ':';\n\n\n/**\n * @const {number} The IE 10 localStorage cross tab synchronization delay in\n * milliseconds.\n */\nfireauth.authStorage.IE10_LOCAL_STORAGE_SYNC_DELAY = 10;\n\n\n/**\n * Enums for Auth state persistence.\n * @enum {string}\n */\nfireauth.authStorage.Persistence = {\n // State will persist even when the browser window is closed or the activity\n // is destroyed in react-native.\n LOCAL: 'local',\n // State is only stored in memory and will be cleared when the window or\n // activity is refreshed.\n NONE: 'none',\n // State will only persist in current session/tab, relevant to web only, and\n // will be cleared when the tab is closed.\n SESSION: 'session'\n};\n\n\n/**\n * Validates that an argument is a valid persistence value. If an invalid type\n * is specified, an error is thrown synchronously.\n * @param {*} arg The argument to validate.\n */\nfireauth.authStorage.validatePersistenceArgument =\n function(arg) {\n // Invalid type error.\n var invalidTypeError = new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_PERSISTENCE);\n // Unsupported type error.\n var unsupportedTypeError = new fireauth.AuthError(\n fireauth.authenum.Error.UNSUPPORTED_PERSISTENCE);\n // Check if the persistence type is a valid one.\n // Throw invalid type error if not valid.\n if (!goog.object.containsValue(fireauth.authStorage.Persistence, arg) ||\n // goog.object.containsValue(fireauth.authStorage.Persistence, ['none'])\n // returns true.\n typeof arg !== 'string') {\n throw invalidTypeError;\n }\n // Validate if the specified type is supported in the current environment.\n switch (fireauth.util.getEnvironment()) {\n case fireauth.util.Env.REACT_NATIVE:\n // This is only supported in a browser.\n if (arg === fireauth.authStorage.Persistence.SESSION) {\n throw unsupportedTypeError;\n }\n break;\n case fireauth.util.Env.NODE:\n // Only none is supported in Node.js.\n if (arg !== fireauth.authStorage.Persistence.NONE) {\n throw unsupportedTypeError;\n }\n break;\n case fireauth.util.Env.WORKER:\n // In a worker environment, either LOCAL or NONE are supported.\n // If indexedDB not supported and LOCAL provided, throw an error.\n if (arg === fireauth.authStorage.Persistence.SESSION ||\n (!fireauth.storage.IndexedDB.isAvailable() &&\n arg !== fireauth.authStorage.Persistence.NONE)) {\n throw unsupportedTypeError;\n }\n break;\n case fireauth.util.Env.BROWSER:\n default:\n // This is restricted by what the browser supports.\n if (!fireauth.util.isWebStorageSupported() &&\n arg !== fireauth.authStorage.Persistence.NONE) {\n throw unsupportedTypeError;\n }\n break;\n }\n};\n\n\n/**\n * Storage key metadata.\n * @typedef {{name: string, persistent: !fireauth.authStorage.Persistence}}\n */\nfireauth.authStorage.Key;\n\n\n/**\n * Storage manager.\n * @param {string} namespace The optional namespace.\n * @param {string} separator The optional separator.\n * @param {boolean} safariLocalStorageNotSynced Whether browser has Safari\n * iframe restriction with storage event triggering but storage not updated.\n * @param {boolean} runsInBackground Whether browser can detect storage event\n * when it had already been pushed to the background. This may happen in\n * some mobile browsers. A localStorage change in the foreground window\n * will not be detected in the background window via the storage event.\n * This was detected in iOS 7.x mobile browsers.\n * @param {boolean} webStorageSupported Whether browser web storage is\n * supported.\n * @constructor @struct @final\n */\nfireauth.authStorage.Manager = function(\n namespace,\n separator,\n safariLocalStorageNotSynced,\n runsInBackground,\n webStorageSupported) {\n /** @const @private {string} Storage namespace. */\n this.namespace_ = namespace;\n /** @const @private {string} Storage namespace key separator. */\n this.separator_ = separator;\n /**\n * @const @private {boolean} Whether browser has Safari iframe restriction\n * with storage event triggering but storage not updated.\n */\n this.safariLocalStorageNotSynced_ = safariLocalStorageNotSynced;\n /**\n * @private {boolean} Whether browser can detect storage event when it\n * had already been pushed to the background. This may happen in some\n * mobile browsers.\n */\n this.runsInBackground_ = runsInBackground;\n /** @const @private {boolean} Whether browser web storage is supported. */\n this.webStorageSupported_ = webStorageSupported;\n\n /**\n * @const @private {!Object.<string, !Array<function()>>} The storage event\n * key to listeners map.\n */\n this.listeners_ = {};\n\n var storageFactory = fireauth.storage.Factory.getInstance();\n try {\n /**\n * @private {!fireauth.storage.Storage} Persistence storage.\n */\n this.persistentStorage_ = storageFactory.makePersistentStorage();\n } catch (e) {\n // Default to in memory storage if the preferred persistent storage is not\n // supported.\n this.persistentStorage_ = storageFactory.makeInMemoryStorage();\n // Do not use indexedDB fallback.\n this.localStorageNotSynchronized_ = false;\n // Do not set polling functions on window.localStorage.\n this.runsInBackground_ = true;\n }\n try {\n /**\n * @private {!fireauth.storage.Storage} Temporary session storage.\n */\n this.temporaryStorage_ = storageFactory.makeTemporaryStorage();\n } catch (e) {\n // Default to in memory storage if the preferred temporary storage is not\n // supported. This should be a different in memory instance as the\n // persistent storage, since the same key could be available for both types\n // of storage.\n this.temporaryStorage_ = storageFactory.makeInMemoryStorage();\n }\n /**\n * @private {!fireauth.storage.Storage} In memory storage.\n */\n this.inMemoryStorage_ = storageFactory.makeInMemoryStorage();\n\n /**\n * @const @private {function(!goog.events.BrowserEvent)|\n * function(!Array<string>)} Storage change handler.\n */\n this.storageChangeEventHandler_ = goog.bind(this.storageChangeEvent_, this);\n /** @private {!Object.<string, *>} Local map for localStorage. */\n this.localMap_ = {};\n};\n\n\n/**\n * @return {!fireauth.authStorage.Manager} The default Auth storage manager\n * instance.\n */\nfireauth.authStorage.Manager.getInstance = function() {\n // Creates the default instance for Auth storage maanger.\n if (!fireauth.authStorage.Manager.instance_) {\n /**\n * @private {?fireauth.authStorage.Manager} The default storage manager\n * instance.\n */\n fireauth.authStorage.Manager.instance_ = new fireauth.authStorage.Manager(\n fireauth.authStorage.NAMESPACE_,\n fireauth.authStorage.SEPARATOR_,\n fireauth.util.isSafariLocalStorageNotSynced(),\n fireauth.util.runsInBackground(),\n fireauth.util.isWebStorageSupported());\n }\n return fireauth.authStorage.Manager.instance_;\n};\n\n\n/** Clears storage manager instances. This is used for testing. */\nfireauth.authStorage.Manager.clear = function() {\n fireauth.authStorage.Manager.instance_ = null;\n};\n\n\n/**\n * Returns the storage corresponding to the specified persistence.\n * @param {!fireauth.authStorage.Persistence} persistent The type of storage\n * persistence.\n * @return {!fireauth.storage.Storage} The corresponding storage instance.\n * @private\n */\nfireauth.authStorage.Manager.prototype.getStorage_ = function(persistent) {\n switch (persistent) {\n case fireauth.authStorage.Persistence.SESSION:\n return this.temporaryStorage_;\n case fireauth.authStorage.Persistence.NONE:\n return this.inMemoryStorage_;\n case fireauth.authStorage.Persistence.LOCAL:\n default:\n return this.persistentStorage_;\n }\n};\n\n\n/**\n * Constructs the corresponding storage key name.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n * stored.\n * @param {?string=} opt_id This ID associates storage values with specific\n * apps.\n * @return {string} The corresponding key name with namespace prefixed.\n * @private\n */\nfireauth.authStorage.Manager.prototype.getKeyName_ = function(dataKey, opt_id) {\n return this.namespace_ + this.separator_ + dataKey.name +\n (opt_id ? this.separator_ + opt_id : '');\n};\n\n\n/**\n * Migrates window.localStorage to the provided persistent storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the persistent\n * value is supposed to be stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n * associates storage values with specific apps.\n * @return {!goog.Promise<void>} A promise that resolves when the data stored\n * in window.localStorage is migrated to the provided persistent storage\n * identified by the provided data key.\n */\nfireauth.authStorage.Manager.prototype.migrateFromLocalStorage =\n function(dataKey, opt_id) {\n var self = this;\n var key = this.getKeyName_(dataKey, opt_id);\n var storage = this.getStorage_(dataKey.persistent);\n // Get data stored in the default persistent storage identified by dataKey.\n return this.get(dataKey, opt_id).then(function(response) {\n // Get the stored value in window.localStorage if available.\n var oldStorageValue = null;\n try {\n oldStorageValue = fireauth.util.parseJSON(\n goog.global['localStorage']['getItem'](key));\n } catch (e) {\n // Set value as null. This will resolve the promise immediately.\n }\n // If data is stored in window.localStorage but no data is available in\n // default persistent storage, migrate data from window.localStorage to\n // default persistent storage.\n if (oldStorageValue && !response) {\n // This condition may fail in situations where a user opens a tab with\n // an old version while using a tab with a new version, or when a\n // developer switches back and forth between and old and new version of\n // the library.\n goog.global['localStorage']['removeItem'](key);\n // Migrate the value to new default persistent storage.\n return self.set(dataKey, oldStorageValue, opt_id);\n } else if (oldStorageValue &&\n response &&\n storage.type != fireauth.storage.Storage.Type.LOCAL_STORAGE) {\n // Data stored in both localStorage and new persistent storage (eg.\n // indexedDB) for some reason.\n // This could happen if the developer is migrating back and forth.\n // The new default persistent storage (eg. indexedDB) takes precedence.\n goog.global['localStorage']['removeItem'](key);\n }\n });\n};\n\n\n/**\n * Gets the stored value from the corresponding storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n * stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n * associates storage values with specific apps.\n * @return {!goog.Promise} A Promise that resolves with the stored value.\n */\nfireauth.authStorage.Manager.prototype.get = function(dataKey, opt_id) {\n var keyName = this.getKeyName_(dataKey, opt_id);\n return this.getStorage_(dataKey.persistent).get(keyName);\n};\n\n\n/**\n * Removes the stored value from the corresponding storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n * stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n * associates storage values with specific apps.\n * @return {!goog.Promise<void>} A Promise that resolves when the operation is\n * completed.\n */\nfireauth.authStorage.Manager.prototype.remove = function(dataKey, opt_id) {\n var keyName = this.getKeyName_(dataKey, opt_id);\n // Keep local map up to date for requested key if persistent storage is used.\n if (dataKey.persistent == fireauth.authStorage.Persistence.LOCAL) {\n this.localMap_[keyName] = null;\n }\n return this.getStorage_(dataKey.persistent).remove(keyName);\n};\n\n\n/**\n * Stores the value in the corresponding storage.\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n * stored.\n * @param {*} value The value to be stored.\n * @param {?string=} opt_id When operating in multiple app mode, this ID\n * associates storage values with specific apps.\n * @return {!goog.Promise<void>} A Promise that resolves when the operation is\n * completed.\n */\nfireauth.authStorage.Manager.prototype.set = function(dataKey, value, opt_id) {\n var keyName = this.getKeyName_(dataKey, opt_id);\n var self = this;\n var storage = this.getStorage_(dataKey.persistent);\n return storage.set(keyName, value)\n .then(function() {\n return storage.get(keyName);\n })\n .then(function(serializedValue) {\n // Keep local map up to date for requested key if persistent storage is\n // used.\n if (dataKey.persistent == fireauth.authStorage.Persistence.LOCAL) {\n self.localMap_[keyName] = serializedValue;\n }\n });\n};\n\n\n/**\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n * stored.\n * @param {?string} id When operating in multiple app mode, this ID associates\n * storage values with specific apps.\n * @param {function()} listener The callback listener to run on storage event\n * related to key.\n */\nfireauth.authStorage.Manager.prototype.addListener =\n function(dataKey, id, listener) {\n var key = this.getKeyName_(dataKey, id);\n // Initialize local map for current key if web storage is supported.\n if (this.webStorageSupported_) {\n this.localMap_[key] = goog.global['localStorage']['getItem'](key);\n }\n if (goog.object.isEmpty(this.listeners_)) {\n // Start listeners.\n this.startListeners_();\n }\n if (!this.listeners_[key]) {\n this.listeners_[key] = [];\n }\n this.listeners_[key].push(listener);\n};\n\n\n/**\n * @param {fireauth.authStorage.Key} dataKey The key under which the value is\n * stored.\n * @param {?string} id When operating in multiple app mode, this ID associates\n * storage values with specific apps.\n * @param {function()} listener The listener to remove.\n */\nfireauth.authStorage.Manager.prototype.removeListener =\n function(dataKey, id, listener) {\n var key = this.getKeyName_(dataKey, id);\n if (this.listeners_[key]) {\n goog.array.removeAllIf(\n this.listeners_[key],\n function(ele) {\n return ele == listener;\n });\n if (this.listeners_[key].length == 0) {\n delete this.listeners_[key];\n }\n }\n if (goog.object.isEmpty(this.listeners_)) {\n // Stop listeners.\n this.stopListeners_();\n }\n};\n\n\n/**\n * The delay to wait between continuous checks of localStorage on browsers where\n * tabs do not run in the background. After each interval wait, we check for\n * external changes in localStorage that were not detected in the current tab.\n * @const {number}\n * @private\n */\nfireauth.authStorage.Manager.LOCAL_STORAGE_POLLING_TIMER_ = 1000;\n\n\n/**\n * Starts all storage event listeners.\n * @private\n */\nfireauth.authStorage.Manager.prototype.startListeners_ = function() {\n this.getStorage_(fireauth.authStorage.Persistence.LOCAL)\n .addStorageListener(this.storageChangeEventHandler_);\n // TODO: refactor this implementation to be handled by the underlying\n // storage mechanism.\n if (!this.runsInBackground_ &&\n // Add an exception for browsers that persist storage with indexedDB, we\n // should stick with indexedDB listener implementation in that case.\n !fireauth.util.persistsStorageWithIndexedDB() &&\n // Confirm browser web storage is supported as polling relies on it.\n this.webStorageSupported_) {\n this.startManualListeners_();\n }\n};\n\n/**\n * Starts manual polling function to detect storage event changes.\n * @private\n */\nfireauth.authStorage.Manager.prototype.startManualListeners_ = function() {\n var self = this;\n this.stopManualListeners_();\n /** @private {?number} The interval timer for manual storage checking. */\n this.manualListenerTimer_ = setInterval(function() {\n // Check all keys with listeners on them.\n for (var key in self.listeners_) {\n // Get value from localStorage.\n var currentValue = goog.global['localStorage']['getItem'](key);\n var oldValue = self.localMap_[key];\n // If local map value does not match, trigger listener with storage event.\n if (currentValue != oldValue) {\n self.localMap_[key] = currentValue;\n var event = new goog.events.BrowserEvent(/** @type {!Event} */ ({\n type: 'storage',\n key: key,\n target: window,\n oldValue: oldValue,\n newValue: currentValue,\n // Differentiate this simulated event from the real storage event.\n poll: true\n }));\n self.storageChangeEvent_(event);\n }\n }\n }, fireauth.authStorage.Manager.LOCAL_STORAGE_POLLING_TIMER_);\n};\n\n\n/**\n * Stops manual polling function to detect storage event changes.\n * @private\n */\nfireauth.authStorage.Manager.prototype.stopManualListeners_ = function() {\n if (this.manualListenerTimer_) {\n clearInterval(this.manualListenerTimer_);\n this.manualListenerTimer_ = null;\n }\n};\n\n\n/**\n * Stops all storage event listeners.\n * @private\n */\nfireauth.authStorage.Manager.prototype.stopListeners_ = function() {\n this.getStorage_(fireauth.authStorage.Persistence.LOCAL)\n .removeStorageListener(this.storageChangeEventHandler_);\n this.stopManualListeners_();\n};\n\n\n/**\n * @param {!goog.events.BrowserEvent|!Array<string>} data The storage event\n * triggered or the array of keys modified.\n * @private\n */\nfireauth.authStorage.Manager.prototype.storageChangeEvent_ = function(data) {\n if (data && data.getBrowserEvent) {\n var event = /** @type {!goog.events.BrowserEvent} */ (data);\n var key = event.getBrowserEvent().key;\n // Key would be null in some situations, like when localStorage is cleared\n // from the browser developer tools.\n if (key == null) {\n // For all keys of interest.\n for (var keyName in this.listeners_) {\n // Check if something changed in this key's real value.\n var storedValue = this.localMap_[keyName];\n // localStorage returns null when a field is not found.\n if (typeof storedValue === 'undefined') {\n storedValue = null;\n }\n var realValue = goog.global['localStorage']['getItem'](keyName);\n if (realValue !== storedValue) {\n // Update local map with real value.\n this.localMap_[keyName] = realValue;\n // Trigger that key's listener.\n this.callListeners_(keyName);\n }\n }\n return;\n }\n // Check if the key is Firebase Auth related, otherwise ignore.\n if (key.indexOf(this.namespace_ + this.separator_) != 0 ||\n // Ignore keys that have no listeners.\n !this.listeners_[key]) {\n return;\n }\n // Check the mechanism how this event was detected.\n // The first event will dictate the mechanism to be used.\n // Do not use hasOwnProperty('poll') as poll gets obfuscated.\n if (typeof event.getBrowserEvent().poll !== 'undefined') {\n // Environment detects storage changes via polling.\n // Remove storage event listener to prevent possible event duplication.\n this.getStorage_(fireauth.authStorage.Persistence.LOCAL)\n .removeStorageListener(this.storageChangeEventHandler_);\n } else {\n // Environment detects storage changes via storage event listener.\n // Remove polling listener to prevent possible event duplication.\n this.stopManualListeners_();\n }\n // Safari embedded iframe. Storage event will trigger with the delta changes\n // but no changes will be applied to the iframe localStorage.\n if (this.safariLocalStorageNotSynced_) {\n // Get current iframe page value, old value and new value.\n var currentValue = goog.global['localStorage']['getItem'](key);\n var newValue = event.getBrowserEvent().newValue;\n // Value not synchronized, synchronize manually.\n if (newValue !== currentValue) {\n if (newValue !== null) {\n // Value changed from current value.\n goog.global['localStorage']['setItem'](key, newValue);\n } else {\n // Current value deleted.\n goog.global['localStorage']['removeItem'](key);\n }\n } else {\n // Already detected and processed, do not trigger listeners again.\n if (this.localMap_[key] === newValue &&\n // Real storage event.\n typeof event.getBrowserEvent().poll === 'undefined') {\n return;\n }\n }\n }\n var self = this;\n var triggerListeners = function() {\n // Keep local map up to date in case storage event is triggered before\n // poll.\n if (typeof event.getBrowserEvent().poll === 'undefined' &&\n self.localMap_[key] === goog.global['localStorage']['getItem'](key)) {\n // Real storage event which has already been detected, do nothing.\n // This seems to trigger in some IE browsers for some reason.\n return;\n }\n self.localMap_[key] = goog.global['localStorage']['getItem'](key);\n self.callListeners_(key);\n };\n if (fireauth.util.isIe10() &&\n goog.global['localStorage']['getItem'](key) !==\n event.getBrowserEvent().newValue &&\n event.getBrowserEvent().newValue !== event.getBrowserEvent().oldValue) {\n // IE 10 has this weird bug where a storage event would trigger with the\n // correct key, oldValue and newValue but localStorage.getItem(key) does\n // not yield the updated value until a few milliseconds. This ensures this\n // recovers from that situation.\n setTimeout(\n triggerListeners, fireauth.authStorage.IE10_LOCAL_STORAGE_SYNC_DELAY);\n } else {\n triggerListeners();\n }\n } else {\n var keys = /** @type {!Array<string>} */ (data);\n goog.array.forEach(keys, goog.bind(this.callListeners_, this));\n }\n};\n\n\n/**\n * Calls all listeners for specified storage event key.\n * @param {string} key The storage event key whose listeners are to be run.\n * @private\n */\nfireauth.authStorage.Manager.prototype.callListeners_ = function(key) {\n if (this.listeners_[key]) {\n goog.array.forEach(\n this.listeners_[key],\n function(listener) {\n listener();\n });\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the fireauth.storage.AuthEventManager class used by\n * the iframe to retrieve and delete Auth events triggered through an OAuth\n * flow.\n */\n\ngoog.provide('fireauth.storage.AuthEventManager');\ngoog.provide('fireauth.storage.AuthEventManager.Keys');\n\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.authStorage');\n\n\n/**\n * Defines the Auth event storage manager. It provides methods to\n * load and delete Auth events as well as listen to external OAuth changes on\n * them.\n * @param {string} appId The Auth event's application ID.\n * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage\n * manager to use. If none is provided, the default global instance is used.\n * @constructor @struct @final\n */\nfireauth.storage.AuthEventManager = function(appId, opt_manager) {\n /** @const @private{string} appId The Auth event's application ID. */\n this.appId_ = appId;\n /**\n * @const @private{!fireauth.authStorage.Manager} The underlying storage\n * manager.\n */\n this.manager_ = opt_manager || fireauth.authStorage.Manager.getInstance();\n};\n\n\n/**\n * Valid keys for Auth event manager data.\n * @enum {!fireauth.authStorage.Key}\n */\nfireauth.storage.AuthEventManager.Keys = {\n AUTH_EVENT: {\n name: 'authEvent',\n persistent: fireauth.authStorage.Persistence.LOCAL\n },\n REDIRECT_EVENT: {\n name: 'redirectEvent',\n persistent: fireauth.authStorage.Persistence.SESSION\n }\n};\n\n\n/**\n * @return {!goog.Promise<?fireauth.AuthEvent>} A promise that resolves on\n * success with the stored Auth event.\n */\nfireauth.storage.AuthEventManager.prototype.getAuthEvent = function() {\n return this.manager_.get(\n fireauth.storage.AuthEventManager.Keys.AUTH_EVENT, this.appId_)\n .then(function(response) {\n return fireauth.AuthEvent.fromPlainObject(response);\n });\n};\n\n\n/**\n * Removes the identifier's Auth event if it exists.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.AuthEventManager.prototype.removeAuthEvent = function() {\n return this.manager_.remove(\n fireauth.storage.AuthEventManager.Keys.AUTH_EVENT, this.appId_);\n};\n\n\n/**\n * Adds a listener to Auth event for App ID provided.\n * @param {!function()} listener The listener to run on Auth event.\n */\nfireauth.storage.AuthEventManager.prototype.addAuthEventListener =\n function(listener) {\n this.manager_.addListener(\n fireauth.storage.AuthEventManager.Keys.AUTH_EVENT, this.appId_, listener);\n};\n\n\n/**\n * Removes a listener to Auth event for App ID provided.\n * @param {!function()} listener The listener to run on Auth event.\n */\nfireauth.storage.AuthEventManager.prototype.removeAuthEventListener =\n function(listener) {\n this.manager_.removeListener(\n fireauth.storage.AuthEventManager.Keys.AUTH_EVENT, this.appId_, listener);\n};\n\n\n/**\n * @return {!goog.Promise<?fireauth.AuthEvent>} A promise that resolves on\n * success with the stored redirect Auth event.\n */\nfireauth.storage.AuthEventManager.prototype.getRedirectEvent =\n function() {\n return this.manager_.get(\n fireauth.storage.AuthEventManager.Keys.REDIRECT_EVENT,\n this.appId_).then(function(response) {\n return fireauth.AuthEvent.fromPlainObject(response);\n });\n};\n\n\n/**\n * Removes the identifier's redirect Auth event if it exists.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.AuthEventManager.prototype.removeRedirectEvent = function() {\n return this.manager_.remove(\n fireauth.storage.AuthEventManager.Keys.REDIRECT_EVENT, this.appId_);\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the fireauth.storage.OAuthHandlerManager class which\n * provides utilities to the OAuth handler widget to set Auth events after an\n * IDP sign in attempt and to store state during the OAuth handshake with IDP.\n */\n\ngoog.provide('fireauth.storage.OAuthHandlerManager');\n\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.OAuthHelperState');\ngoog.require('fireauth.authStorage');\ngoog.require('fireauth.storage.AuthEventManager.Keys');\n\n\n/**\n * Defines the OAuth handler storage manager. It provides methods to\n * store, load and delete OAuth handler widget state, properties and setting\n * Auth events.\n * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage\n * manager to use. If none is provided, the default global instance is used.\n * @constructor @struct @final\n */\nfireauth.storage.OAuthHandlerManager = function(opt_manager) {\n /**\n * @const @private{!fireauth.authStorage.Manager} The underlying storage\n * manager.\n */\n this.manager_ = opt_manager || fireauth.authStorage.Manager.getInstance();\n};\n\n\n/**\n * Valid keys for OAuth handler manager data.\n * @private @enum {!fireauth.authStorage.Key}\n */\nfireauth.storage.OAuthHandlerManager.Keys_ = {\n OAUTH_HELPER_STATE: {\n name: 'oauthHelperState',\n persistent: fireauth.authStorage.Persistence.SESSION\n },\n SESSION_ID: {\n name: 'sessionId',\n persistent: fireauth.authStorage.Persistence.SESSION\n }\n};\n\n\n/**\n * @param {string} appId The Auth state's application ID.\n * @return {!goog.Promise<?string|undefined>} A promise that resolves on success\n * with the stored session ID.\n */\nfireauth.storage.OAuthHandlerManager.prototype.getSessionId = function(appId) {\n return this.manager_.get(\n fireauth.storage.OAuthHandlerManager.Keys_.SESSION_ID, appId);\n};\n\n\n/**\n * Removes the session ID string if it exists.\n * @param {string} appId The Auth state's application ID.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.OAuthHandlerManager.prototype.removeSessionId =\n function(appId) {\n return this.manager_.remove(\n fireauth.storage.OAuthHandlerManager.Keys_.SESSION_ID, appId);\n};\n\n\n/**\n * Stores the session ID string.\n * @param {string} appId The Auth state's application ID.\n * @param {string} sessionId The session ID string to store.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.OAuthHandlerManager.prototype.setSessionId =\n function(appId, sessionId) {\n return this.manager_.set(\n fireauth.storage.OAuthHandlerManager.Keys_.SESSION_ID, sessionId, appId);\n};\n\n\n/**\n * @return {!goog.Promise<?fireauth.OAuthHelperState>} A promise that resolves\n * on success with the stored OAuth helper state.\n */\nfireauth.storage.OAuthHandlerManager.prototype.getOAuthHelperState =\n function() {\n return this.manager_.get(\n fireauth.storage.OAuthHandlerManager.Keys_.OAUTH_HELPER_STATE)\n .then(function(response) {\n return fireauth.OAuthHelperState.fromPlainObject(response);\n });\n};\n\n\n/**\n * Removes the current OAuth helper state if it exists.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.OAuthHandlerManager.prototype.removeOAuthHelperState =\n function() {\n return this.manager_.remove(\n fireauth.storage.OAuthHandlerManager.Keys_.OAUTH_HELPER_STATE);\n};\n\n\n/**\n * Stores the current OAuth helper state.\n * @param {!fireauth.OAuthHelperState} state The OAuth helper state.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.OAuthHandlerManager.prototype.setOAuthHelperState =\n function(state) {\n return this.manager_.set(\n fireauth.storage.OAuthHandlerManager.Keys_.OAUTH_HELPER_STATE,\n state.toPlainObject());\n};\n\n\n/**\n * Stores the Auth event for specified identifier.\n * @param {string} appId The Auth state's application ID.\n * @param {!fireauth.AuthEvent} authEvent The Auth event.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.OAuthHandlerManager.prototype.setAuthEvent =\n function(appId, authEvent) {\n return this.manager_.set(\n fireauth.storage.AuthEventManager.Keys.AUTH_EVENT,\n authEvent.toPlainObject(),\n appId);\n};\n\n\n/**\n * Stores the redirect Auth event for specified identifier.\n * @param {string} appId The Auth state's application ID.\n * @param {!fireauth.AuthEvent} authEvent The redirect Auth event.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.OAuthHandlerManager.prototype.setRedirectEvent =\n function(appId, authEvent) {\n return this.manager_.set(\n fireauth.storage.AuthEventManager.Keys.REDIRECT_EVENT,\n authEvent.toPlainObject(),\n appId);\n};\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 /**\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 Base class for SHA-2 cryptographic hash.\n *\n * Variable names follow the notation in FIPS PUB 180-3:\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\n *\n * Some code similar to SHA1 are borrowed from sha1.js written by mschilder@.\n */\n\ngoog.provide('goog.crypt.Sha2');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.crypt.Hash');\n\n\n\n/**\n * SHA-2 cryptographic hash constructor.\n * This constructor should not be used directly to create the object. Rather,\n * one should use the constructor of the sub-classes.\n * @param {number} numHashBlocks The size of output in 16-byte blocks.\n * @param {!Array<number>} initHashBlocks The hash-specific initialization\n * @constructor\n * @extends {goog.crypt.Hash}\n * @struct\n */\ngoog.crypt.Sha2 = function(numHashBlocks, initHashBlocks) {\n goog.crypt.Sha2.base(this, 'constructor');\n\n this.blockSize = goog.crypt.Sha2.BLOCKSIZE_;\n\n /**\n * A chunk holding the currently processed message bytes. Once the chunk has\n * 64 bytes, we feed it into computeChunk_ function and reset this.chunk_.\n * @private {!Array<number>|!Uint8Array}\n */\n this.chunk_ = goog.global['Uint8Array'] ? new Uint8Array(this.blockSize) :\n new Array(this.blockSize);\n\n /**\n * Current number of bytes in this.chunk_.\n * @private {number}\n */\n this.inChunk_ = 0;\n\n /**\n * Total number of bytes in currently processed message.\n * @private {number}\n */\n this.total_ = 0;\n\n\n /**\n * Holds the previous values of accumulated hash a-h in the computeChunk_\n * function.\n * @private {!Array<number>|!Int32Array}\n */\n this.hash_ = [];\n\n /**\n * The number of output hash blocks (each block is 4 bytes long).\n * @private {number}\n */\n this.numHashBlocks_ = numHashBlocks;\n\n /**\n * @private {!Array<number>} initHashBlocks\n */\n this.initHashBlocks_ = initHashBlocks;\n\n /**\n * Temporary array used in chunk computation. Allocate here as a\n * member rather than as a local within computeChunk_() as a\n * performance optimization to reduce the number of allocations and\n * reduce garbage collection.\n * @private {!Int32Array|!Array<number>}\n */\n this.w_ = goog.global['Int32Array'] ? new Int32Array(64) : new Array(64);\n\n if (goog.crypt.Sha2.Kx_ === undefined) {\n // This is the first time this constructor has been called.\n if (goog.global['Int32Array']) {\n // Typed arrays exist\n goog.crypt.Sha2.Kx_ = new Int32Array(goog.crypt.Sha2.K_);\n } else {\n // Typed arrays do not exist\n goog.crypt.Sha2.Kx_ = goog.crypt.Sha2.K_;\n }\n }\n\n this.reset();\n};\ngoog.inherits(goog.crypt.Sha2, goog.crypt.Hash);\n\n\n/**\n * The block size\n * @private {number}\n */\ngoog.crypt.Sha2.BLOCKSIZE_ = 512 / 8;\n\n\n/**\n * Contains data needed to pad messages less than BLOCK_SIZE_ bytes.\n * @private {!Array<number>}\n */\ngoog.crypt.Sha2.PADDING_ = goog.array.concat(\n 128, goog.array.repeat(0, goog.crypt.Sha2.BLOCKSIZE_ - 1));\n\n\n/** @override */\ngoog.crypt.Sha2.prototype.reset = function() {\n this.inChunk_ = 0;\n this.total_ = 0;\n this.hash_ = goog.global['Int32Array'] ?\n new Int32Array(this.initHashBlocks_) :\n goog.array.clone(this.initHashBlocks_);\n};\n\n\n/**\n * Helper function to compute the hashes for a given 512-bit message chunk.\n * @private\n */\ngoog.crypt.Sha2.prototype.computeChunk_ = function() {\n var chunk = this.chunk_;\n goog.asserts.assert(chunk.length == this.blockSize);\n var rounds = 64;\n\n // Divide the chunk into 16 32-bit-words.\n var w = this.w_;\n var index = 0;\n var offset = 0;\n while (offset < chunk.length) {\n w[index++] = (chunk[offset] << 24) | (chunk[offset + 1] << 16) |\n (chunk[offset + 2] << 8) | (chunk[offset + 3]);\n offset = index * 4;\n }\n\n // Extend the w[] array to be the number of rounds.\n for (var i = 16; i < rounds; i++) {\n var w_15 = w[i - 15] | 0;\n var s0 = ((w_15 >>> 7) | (w_15 << 25)) ^ ((w_15 >>> 18) | (w_15 << 14)) ^\n (w_15 >>> 3);\n var w_2 = w[i - 2] | 0;\n var s1 = ((w_2 >>> 17) | (w_2 << 15)) ^ ((w_2 >>> 19) | (w_2 << 13)) ^\n (w_2 >>> 10);\n\n // As a performance optimization, construct the sum a pair at a time\n // with casting to integer (bitwise OR) to eliminate unnecessary\n // double<->integer conversions.\n var partialSum1 = ((w[i - 16] | 0) + s0) | 0;\n var partialSum2 = ((w[i - 7] | 0) + s1) | 0;\n w[i] = (partialSum1 + partialSum2) | 0;\n }\n\n var a = this.hash_[0] | 0;\n var b = this.hash_[1] | 0;\n var c = this.hash_[2] | 0;\n var d = this.hash_[3] | 0;\n var e = this.hash_[4] | 0;\n var f = this.hash_[5] | 0;\n var g = this.hash_[6] | 0;\n var h = this.hash_[7] | 0;\n for (var i = 0; i < rounds; i++) {\n var S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^\n ((a >>> 22) | (a << 10));\n var maj = ((a & b) ^ (a & c) ^ (b & c));\n var t2 = (S0 + maj) | 0;\n var S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^\n ((e >>> 25) | (e << 7));\n var ch = ((e & f) ^ ((~e) & g));\n\n // As a performance optimization, construct the sum a pair at a time\n // with casting to integer (bitwise OR) to eliminate unnecessary\n // double<->integer conversions.\n var partialSum1 = (h + S1) | 0;\n var partialSum2 = (ch + (goog.crypt.Sha2.Kx_[i] | 0)) | 0;\n var partialSum3 = (partialSum2 + (w[i] | 0)) | 0;\n var t1 = (partialSum1 + partialSum3) | 0;\n\n h = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n\n this.hash_[0] = (this.hash_[0] + a) | 0;\n this.hash_[1] = (this.hash_[1] + b) | 0;\n this.hash_[2] = (this.hash_[2] + c) | 0;\n this.hash_[3] = (this.hash_[3] + d) | 0;\n this.hash_[4] = (this.hash_[4] + e) | 0;\n this.hash_[5] = (this.hash_[5] + f) | 0;\n this.hash_[6] = (this.hash_[6] + g) | 0;\n this.hash_[7] = (this.hash_[7] + h) | 0;\n};\n\n\n/** @override */\ngoog.crypt.Sha2.prototype.update = function(message, opt_length) {\n if (opt_length === undefined) {\n opt_length = message.length;\n }\n // Process the message from left to right up to |opt_length| bytes.\n // When we get a 512-bit chunk, compute the hash of it and reset\n // this.chunk_. The message might not be multiple of 512 bits so we\n // might end up with a chunk that is less than 512 bits. We store\n // such partial chunk in this.chunk_ and it will be filled up later\n // in digest().\n var n = 0;\n var inChunk = this.inChunk_;\n\n // The input message could be either byte array of string.\n if (typeof message === 'string') {\n while (n < opt_length) {\n this.chunk_[inChunk++] = message.charCodeAt(n++);\n if (inChunk == this.blockSize) {\n this.computeChunk_();\n inChunk = 0;\n }\n }\n } else if (goog.isArrayLike(message)) {\n while (n < opt_length) {\n var b = message[n++];\n if (!('number' == typeof b && 0 <= b && 255 >= b && b == (b | 0))) {\n throw new Error('message must be a byte array');\n }\n this.chunk_[inChunk++] = b;\n if (inChunk == this.blockSize) {\n this.computeChunk_();\n inChunk = 0;\n }\n }\n } else {\n throw new Error('message must be string or array');\n }\n\n // Record the current bytes in chunk to support partial update.\n this.inChunk_ = inChunk;\n\n // Record total message bytes we have processed so far.\n this.total_ += opt_length;\n};\n\n\n/** @override */\ngoog.crypt.Sha2.prototype.digest = function() {\n var digest = [];\n var totalBits = this.total_ * 8;\n\n // Append pad 0x80 0x00*.\n if (this.inChunk_ < 56) {\n this.update(goog.crypt.Sha2.PADDING_, 56 - this.inChunk_);\n } else {\n this.update(\n goog.crypt.Sha2.PADDING_, this.blockSize - (this.inChunk_ - 56));\n }\n\n // Append # bits in the 64-bit big-endian format.\n for (var i = 63; i >= 56; i--) {\n this.chunk_[i] = totalBits & 255;\n totalBits /= 256; // Don't use bit-shifting here!\n }\n this.computeChunk_();\n\n // Finally, output the result digest.\n var n = 0;\n for (var i = 0; i < this.numHashBlocks_; i++) {\n for (var j = 24; j >= 0; j -= 8) {\n digest[n++] = ((this.hash_[i] >> j) & 255);\n }\n }\n return digest;\n};\n\n\n/**\n * Constants used in SHA-2.\n * @const\n * @private {!Array<number>}\n */\ngoog.crypt.Sha2.K_ = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\n\n/**\n * Sha2.K as an Int32Array if this JS supports typed arrays; otherwise,\n * the same array as Sha2.K.\n *\n * The compiler cannot remove an Int32Array, even if it is not needed\n * (There are certain cases where creating an Int32Array is not\n * side-effect free). Instead, the first time we construct a Sha2\n * instance, we convert or assign Sha2.K as appropriate.\n * @private {undefined|!Array<number>|!Int32Array}\n */\ngoog.crypt.Sha2.Kx_;\n","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview SHA-256 cryptographic hash.\n *\n * Usage:\n * var sha256 = new goog.crypt.Sha256();\n * sha256.update(bytes);\n * var hash = sha256.digest();\n */\n\ngoog.provide('goog.crypt.Sha256');\n\ngoog.require('goog.crypt.Sha2');\n\n\n\n/**\n * SHA-256 cryptographic hash constructor.\n *\n * @constructor\n * @extends {goog.crypt.Sha2}\n * @final\n * @struct\n */\ngoog.crypt.Sha256 = function() {\n goog.crypt.Sha256.base(\n this, 'constructor', 8, goog.crypt.Sha256.INIT_HASH_BLOCK_);\n};\ngoog.inherits(goog.crypt.Sha256, goog.crypt.Sha2);\n\n\n/** @private {!Array<number>} */\ngoog.crypt.Sha256.INIT_HASH_BLOCK_ = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n 0x1f83d9ab, 0x5be0cd19\n];\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines Cordova utility and helper functions.\n * The following plugins must be installed:\n * cordova plugin add cordova-plugin-buildinfo\n * cordova plugin add cordova-universal-links-plugin-fix\n * cordova plugin add cordova-plugin-browsertab\n * cordova plugin add cordova-plugin-inappbrowser\n * iOS custom scheme support:\n * cordova plugin add cordova-plugin-customurlscheme --variable \\\n * URL_SCHEME=com.firebase.example\n * Console logging in iOS:\n * cordova plugin add cordova-plugin-console\n */\n\ngoog.provide('fireauth.CordovaHandler');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.DynamicLink');\ngoog.require('fireauth.OAuthSignInHandler');\ngoog.require('fireauth.UniversalLinkSubscriber');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.storage.AuthEventManager');\ngoog.require('fireauth.storage.OAuthHandlerManager');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.Uri');\ngoog.require('goog.array');\ngoog.require('goog.crypt');\ngoog.require('goog.crypt.Sha256');\n\n\n/**\n * Cordova environment utility and helper functions.\n * @param {string} authDomain The application authDomain.\n * @param {string} apiKey The API key.\n * @param {string} appName The App name.\n * @param {?string=} opt_clientVersion The optional client version string.\n * @param {number=} opt_initialTimeout Initial Auth event timeout.\n * @param {number=} opt_redirectTimeout Redirect result timeout.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @constructor\n * @implements {fireauth.OAuthSignInHandler}\n */\nfireauth.CordovaHandler = function(authDomain, apiKey, appName,\n opt_clientVersion, opt_initialTimeout, opt_redirectTimeout,\n opt_endpointId) {\n /** @private {string} The application authDomain. */\n this.authDomain_ = authDomain;\n /** @private {string} The application API key. */\n this.apiKey_ = apiKey;\n /** @private {string} The application name. */\n this.appName_ = appName;\n /** @private {?string} The client version */\n this.clientVersion_ = opt_clientVersion || null;\n /** @private {?string} The Auth endpoint ID. */\n this.endpointId_ = opt_endpointId || null;\n /** @private {string} The storage key. */\n this.storageKey_ = fireauth.util.createStorageKey(apiKey, appName);\n /**\n * @private {!fireauth.storage.OAuthHandlerManager} The OAuth handler\n * storage manager reference, used to save a partial Auth event when\n * redirect operation is triggered.\n */\n this.savePartialEventManager_ = new fireauth.storage.OAuthHandlerManager();\n /**\n * @private {!fireauth.storage.AuthEventManager} The Auth event storage\n * manager reference. This is used to get back the saved partial Auth\n * event and then delete on successful handling.\n */\n this.getAndDeletePartialEventManager_ =\n new fireauth.storage.AuthEventManager(this.storageKey_);\n /**\n * @private {?goog.Promise<!fireauth.AuthEvent>} A promise that resolves with\n * the OAuth redirect URL response.\n */\n this.initialAuthEvent_ = null;\n /**\n * @private {!Array<!function(?fireauth.AuthEvent)>} The Auth event\n * listeners.\n */\n this.authEventListeners_ = [];\n /** @private {number} The initial Auth event timeout. */\n this.initialTimeout_ = opt_initialTimeout ||\n fireauth.CordovaHandler.INITIAL_TIMEOUT_MS_;\n /** @private {number} The return to app after redirect timeout. */\n this.redirectTimeout_ = opt_redirectTimeout ||\n fireauth.CordovaHandler.REDIRECT_TIMEOUT_MS_;\n /**\n * @private {?goog.Promise} The last pending redirect promise. This is null if\n * already completed.\n */\n this.pendingRedirect_ = null;\n /**\n * @private {?Object} The inAppBrowser reference window if available. This is\n * relevant to iOS 7 and 8 embedded webviews.\n */\n this.inAppBrowserRef_ = null;\n};\n\n\n/**\n * The total number of chars used to generate the session ID string.\n * @const {number}\n * @private\n */\nfireauth.CordovaHandler.SESSION_ID_TOTAL_CHARS_ = 20;\n\n\n/**\n * The default initial Auth event timeout in ms.\n * @const {number}\n * @private\n */\nfireauth.CordovaHandler.INITIAL_TIMEOUT_MS_ = 500;\n\n\n/**\n * The default timeout in milliseconds for a pending redirect operation after\n * returning to the app.\n * @const {number}\n * @private\n */\nfireauth.CordovaHandler.REDIRECT_TIMEOUT_MS_ = 2000;\n\n\n/**\n * Constructs a Cordova configuration error message.\n * @param {?string=} opt_message The optional error message to be used. This\n * will override the existing default one.\n * @return {!fireauth.AuthError} The Cordova invalid configuration error with\n * the custom message provided. If no message is provided, the default\n * message is used.\n * @private\n */\nfireauth.CordovaHandler.getError_ = function(opt_message) {\n return new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION,\n opt_message);\n};\n\n\n/**\n * Initializes the Cordova environment and waits for it to be ready.\n * @return {!goog.Promise} A promise that resolves if the current environment is\n * a Cordova environment.\n * @override\n */\nfireauth.CordovaHandler.prototype.initializeAndWait = function() {\n if (this.isReady_) {\n return this.isReady_;\n }\n this.isReady_ = fireauth.util.checkIfCordova().then(function() {\n // Check all dependencies installed.\n // Note that cordova-universal-links-plugin has been abandoned.\n // A fork with latest fixes is available at:\n // https://www.npmjs.com/package/cordova-universal-links-plugin-fix\n var subscribe = fireauth.util.getObjectRef(\n 'universalLinks.subscribe', goog.global);\n if (typeof subscribe !== 'function') {\n throw fireauth.CordovaHandler.getError_(\n 'cordova-universal-links-plugin-fix is not installed');\n }\n // https://www.npmjs.com/package/cordova-plugin-buildinfo\n var appIdentifier =\n fireauth.util.getObjectRef('BuildInfo.packageName', goog.global);\n if (typeof appIdentifier === 'undefined') {\n throw fireauth.CordovaHandler.getError_(\n 'cordova-plugin-buildinfo is not installed');\n }\n // https://github.com/google/cordova-plugin-browsertab\n var openUrl = fireauth.util.getObjectRef(\n 'cordova.plugins.browsertab.openUrl', goog.global);\n if (typeof openUrl !== 'function') {\n throw fireauth.CordovaHandler.getError_(\n 'cordova-plugin-browsertab is not installed');\n }\n // https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/\n var openInAppBrowser = fireauth.util.getObjectRef(\n 'cordova.InAppBrowser.open', goog.global);\n if (typeof openInAppBrowser !== 'function') {\n throw fireauth.CordovaHandler.getError_(\n 'cordova-plugin-inappbrowser is not installed');\n }\n }, function(error) {\n // If not supported.\n throw new fireauth.AuthError(fireauth.authenum.Error.CORDOVA_NOT_READY);\n });\n return this.isReady_;\n};\n\n\n/**\n * Generates a session ID. Used to prevent session fixation attacks.\n * @param {number} numOfChars The number of characters to generate.\n * @return {string} The generated session ID.\n * @private\n */\nfireauth.CordovaHandler.prototype.generateSessionId_ = function(numOfChars) {\n var chars = [];\n var allowedChars =\n '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n while (numOfChars > 0) {\n var index = Math.floor(Math.random() * allowedChars.length);\n chars.push(allowedChars.charAt(index));\n numOfChars--;\n }\n return chars.join('');\n};\n\n\n/**\n * Computes the sha256 hash of a session ID.\n * @param {string} str The string to hash.\n * @return {string} The hashed string.\n * @private\n */\nfireauth.CordovaHandler.prototype.computeSecureHash_ = function(str) {\n // sha256 the sessionId. This will be passed to the OAuth backend.\n // When exchanging the Auth code with a firebase ID token, the raw session ID\n // needs to be provided.\n var sha256 = new goog.crypt.Sha256();\n sha256.update(str);\n return goog.crypt.byteArrayToHex(sha256.digest());\n};\n\n\n/**\n * Waits for popup window to close and time out if the result is unhandled.\n * This is not supported in Cordova.\n * @param {!Window} popupWin The popup window.\n * @param {!function(!fireauth.AuthError)} onError The on error callback.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.CordovaHandler.prototype.startPopupTimeout =\n function(popupWin, onError, timeoutDuration) {\n // Not supported operation, check processPopup for details.\n onError(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n return goog.Promise.resolve();\n};\n\n\n/**\n * Processes the popup request. This is not supported in Cordova.\n * @param {?Window} popupWin The popup window reference.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function()} onInitialize The function to call on initialization.\n * @param {function(*)} onError The function to call on error.\n * @param {string=} opt_eventId The optional event ID.\n * @param {boolean=} opt_alreadyRedirected Whether popup is already redirected\n * to final destination.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise} The popup window promise.\n * @override\n */\nfireauth.CordovaHandler.prototype.processPopup = function(\n popupWin,\n mode,\n provider,\n onInitialize,\n onError,\n opt_eventId,\n opt_alreadyRedirected,\n opt_tenantId) {\n // Popups not supported in Cordova as the activity could be destroyed in\n // some cases. Redirect works better as getRedirectResult can be used as a\n // fallback to get the result when the activity is detroyed.\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n};\n\n\n/**\n * @return {boolean} Whether the handler will unload the current page on\n * redirect operations.\n * @override\n */\nfireauth.CordovaHandler.prototype.unloadsOnRedirect = function() {\n // Does not necessarily unload the page on redirect.\n return false;\n};\n\n\n/**\n * @return {boolean} Whether the handler should be initialized early.\n * @override\n */\nfireauth.CordovaHandler.prototype.shouldBeInitializedEarly = function() {\n // Initialize early to detect incoming link. This is not an expensive\n // operation, unlike embedding an iframe.\n return true;\n};\n\n\n/**\n * @return {boolean} Whether the sign-in handler in the current environment\n * has volatile session storage.\n * @override\n */\nfireauth.CordovaHandler.prototype.hasVolatileStorage = function() {\n // An activity can be destroyed and thereby sessionStorage wiped out.\n return true;\n};\n\n\n/**\n * Processes the OAuth redirect request. Will resolve when the OAuth response\n * is detected in the incoming link and the corresponding Auth event is\n * triggered.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {?string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n * @override\n */\nfireauth.CordovaHandler.prototype.processRedirect = function(\n mode,\n provider,\n opt_eventId,\n opt_tenantId) {\n // If there is already a pending redirect, throw an error.\n if (this.pendingRedirect_) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.REDIRECT_OPERATION_PENDING));\n }\n var self = this;\n var doc = goog.global.document;\n // On close timer promise.\n var onClose = null;\n // Auth event detection callback;\n var authEventCallback = null;\n // On resume (return from the redirect operation).\n var onResume = null;\n // On visibility change used to detect return to app in certain versions,\n // currently iOS.\n var onVisibilityChange = null;\n // When the processRedirect promise completes, clean up any remaining\n // temporary listeners and timers.\n var cleanup = function() {\n // Remove current resume listener.\n if (onResume) {\n doc.removeEventListener('resume', onResume, false);\n }\n // Remove visibility change listener.\n if (onVisibilityChange) {\n doc.removeEventListener('visibilitychange', onVisibilityChange, false);\n }\n // Cancel onClose promise if not already cancelled.\n if (onClose) {\n onClose.cancel();\n }\n // Remove Auth event callback.\n if (authEventCallback) {\n self.removeAuthEventListener(authEventCallback);\n }\n // Clear any pending redirect now that it is completed.\n self.pendingRedirect_ = null;\n };\n // Save the pending redirect promise and clear it on completion.\n this.pendingRedirect_ = goog.Promise.resolve().then(function() {\n // Validate provider.\n // Fail fast in this case.\n fireauth.AuthProvider.checkIfOAuthSupported(provider);\n return self.getInitialAuthEvent_();\n }).then(function() {\n return self.processRedirectInternal_(\n mode, provider, opt_eventId, opt_tenantId);\n }).then(function() {\n // Wait for result (universal link) before resolving this operation.\n // This ensures that if the activity is not destroyed, we can still\n // return the result of this operation.\n return new goog.Promise(function(resolve, reject) {\n /**\n * @param {?fireauth.AuthEvent} event The Auth event detected.\n * @return {boolean}\n */\n authEventCallback = function(event) {\n // Auth event detected, resolve promise.\n // Close SFSVC if still open.\n var closeBrowsertab = fireauth.util.getObjectRef(\n 'cordova.plugins.browsertab.close', goog.global);\n resolve();\n // Close the SFSVC if it is still open (iOS 9+).\n if (typeof closeBrowsertab === 'function') {\n closeBrowsertab();\n }\n // Close inappbrowser emebedded webview in iOS7 and 8 case if still\n // open.\n if (self.inAppBrowserRef_ &&\n typeof self.inAppBrowserRef_['close'] === 'function') {\n self.inAppBrowserRef_['close']();\n // Reset reference.\n self.inAppBrowserRef_ = null;\n }\n return false;\n };\n // Wait and listen for the operation to complete (Auth event would\n // trigger).\n self.addAuthEventListener(authEventCallback);\n // On resume (return from the redirect operation).\n onResume = function() {\n // Already resumed. Do not run again.\n if (onClose) {\n return;\n }\n // Wait for some time before throwing the error that the flow was\n // cancelled by the user.\n onClose = goog.Timer.promise(self.redirectTimeout_).then(function() {\n // Throw the redirect cancelled by user error.\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.REDIRECT_CANCELLED_BY_USER));\n });\n };\n onVisibilityChange = function() {\n // If app is visible, run onResume. Otherwise, ignore.\n if (fireauth.util.isAppVisible()) {\n onResume();\n }\n };\n // Listen to resume event (will trigger when the user returns to the app).\n doc.addEventListener('resume', onResume, false);\n // Listen to visibility change. This is used for iOS Cordova Safari 7+.\n // Does not work in Android stock browser versions older than 4.4.\n // We rely on resume event in Android as it works reliably in all\n // versions.\n if (!fireauth.util.isAndroid()) {\n doc.addEventListener('visibilitychange', onVisibilityChange, false);\n }\n }).thenCatch(function(error) {\n // Remove any pending partial event.\n return self.getPartialStoredEvent_().then(function() {\n throw error;\n });\n });\n }).thenAlways(cleanup);\n // Return the pending redirect promise.\n return this.pendingRedirect_;\n};\n\n/**\n * Processes the OAuth redirect request.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {?string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n * @private\n */\nfireauth.CordovaHandler.prototype.processRedirectInternal_ = function(\n mode,\n provider,\n opt_eventId,\n opt_tenantId) {\n var self = this;\n // https://github.com/google/cordova-plugin-browsertab\n // Opens chrome custom tab in Android if chrome is installed,\n // SFSafariViewController in iOS if supported.\n // If the above are not supported, opens the system browser.\n // Opening a system browser could result in an app being rejected in the App\n // Store. The only solution here is to use an insecure embedded UIWebView.\n // This applies to older iOS versions 8 and under.\n // Generate a random session ID.\n var sessionId = this.generateSessionId_(\n fireauth.CordovaHandler.SESSION_ID_TOTAL_CHARS_);\n // Create the partial Auth event.\n var event = new fireauth.AuthEvent(\n mode,\n opt_eventId,\n null,\n sessionId,\n new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT),\n null,\n opt_tenantId);\n // Use buildinfo package to get app metadata.\n // https://www.npmjs.com/package/cordova-plugin-buildinfo\n // Get app identifier.\n var appIdentifier =\n fireauth.util.getObjectRef('BuildInfo.packageName', goog.global);\n // initializeAndWait will ensure this does not happen.\n if (typeof appIdentifier !== 'string') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n }\n // Get app display name.\n var appDisplayName =\n fireauth.util.getObjectRef('BuildInfo.displayName', goog.global);\n // Construct additional params to pass to OAuth handler.\n var additionalParams = {};\n // Append app identifier.\n if (fireauth.util.isIOS()) {\n // iOS app.\n additionalParams['ibi'] = appIdentifier;\n } else if (fireauth.util.isAndroid()) {\n // Android app.\n additionalParams['apn'] = appIdentifier;\n } else {\n // This should not happen as Cordova handler should not even be used in this\n // case.\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n }\n // Pass app display name.\n if (appDisplayName) {\n additionalParams['appDisplayName'] = appDisplayName;\n }\n // Hash the session ID and pass it to additional params.\n var hashedSessionId = this.computeSecureHash_(sessionId);\n // Append session ID.\n additionalParams['sessionId'] = hashedSessionId;\n // Construct OAuth handler URL.\n var oauthHelperWidgetUrl =\n fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n this.authDomain_,\n this.apiKey_,\n this.appName_,\n mode,\n provider,\n null,\n opt_eventId,\n this.clientVersion_,\n additionalParams,\n this.endpointId_,\n opt_tenantId);\n // Make sure handler initialized and ready.\n // This should also ensure all plugins are installed.\n return this.initializeAndWait().then(function() {\n // Save partial Auth event.\n return self.savePartialEventManager_.setAuthEvent(self.storageKey_, event);\n }).then(function() {\n // initializeAndWait will ensure this plugin is installed.\n var isAvailable = /** @type {!function(!function(*))} */ (\n fireauth.util.getObjectRef(\n 'cordova.plugins.browsertab.isAvailable', goog.global));\n if (typeof isAvailable !== 'function') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n }\n var openUrl = null;\n // Check if browsertab is supported.\n isAvailable(function(result) {\n if (result) {\n // browsertab supported.\n openUrl = /** @type {!function(string, ...*)} */ (\n fireauth.util.getObjectRef(\n 'cordova.plugins.browsertab.openUrl', goog.global));\n if (typeof openUrl !== 'function') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n }\n // Open OAuth handler.\n openUrl(oauthHelperWidgetUrl);\n } else {\n // browsertab not supported, switch to inappbrowser.\n openUrl = /** @type {!function(string, string, string=)} */ (\n fireauth.util.getObjectRef(\n 'cordova.InAppBrowser.open', goog.global));\n if (typeof openUrl !== 'function') {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INVALID_CORDOVA_CONFIGURATION);\n }\n // Open in embedded webview for iOS 7 and 8 as Apple rejects apps that\n // switch context.\n // _blank opens an embedded webview.\n // _system opens the system browser.\n // _system (opens a system browser) is used as a fallback when\n // browsertab plugin is unable to open a chromecustomtab or SFSVC.\n // This has to exclude all iOS older versions where switching to a\n // browser is frowned upon by Apple and embedding a UIWebView is the\n // only option but is insecure and deprecated by Google for OAuth\n // sign-in. This will be applicable in old versions of Android.\n self.inAppBrowserRef_ = openUrl(\n oauthHelperWidgetUrl,\n fireauth.util.isIOS7Or8() ? '_blank' : '_system',\n 'location=yes');\n }\n });\n });\n};\n\n\n/**\n * Dispatches the detected Auth event to all subscribed listeners.\n * @param {!fireauth.AuthEvent} event A detected Auth event.\n * @private\n */\nfireauth.CordovaHandler.prototype.dispatchEvent_ = function(event) {\n for (var i = 0; i < this.authEventListeners_.length; i++) {\n try {\n this.authEventListeners_[i](event);\n } catch (e) {\n // If any handler fails, ignore and run next handler.\n }\n }\n};\n\n\n/**\n * Resolves the first redirect Auth event and caches it.\n * @return {!goog.Promise<!fireauth.AuthEvent>} A promise that resolves with the\n * initial Auth event response from a redirect operation. Initializes the\n * internal Auth event listener which will dispatch Auth events to all\n * subscribed listeners.\n * @private\n */\nfireauth.CordovaHandler.prototype.getInitialAuthEvent_ = function() {\n var self = this;\n if (!this.initialAuthEvent_) {\n // Cache this result so on next call, it is not triggered again.\n this.initialAuthEvent_ = this.initializeAndWait().then(function() {\n return new goog.Promise(function(resolve, reject) {\n /**\n * @param {?fireauth.AuthEvent} event The Auth event detected.\n * @return {boolean}\n */\n var authEventCallback = function(event) {\n resolve(event);\n // Remove on completion.\n self.removeAuthEventListener(authEventCallback);\n return false;\n };\n // Listen to Auth events. If resolved, resolve promise.\n self.addAuthEventListener(authEventCallback);\n // This should succeed as initializeAndWait should guarantee plugins are\n // ready.\n self.setAuthEventListener_();\n });\n });\n }\n return this.initialAuthEvent_;\n};\n\n\n/**\n * Gets and deletes the current stored partial event from storage.\n * @return {!goog.Promise<?fireauth.AuthEvent>} A promise that resolves with the\n * stored Auth event.\n * @private\n */\nfireauth.CordovaHandler.prototype.getPartialStoredEvent_ = function() {\n var event = null;\n var self = this;\n // Get any saved partial Auth event.\n return this.getAndDeletePartialEventManager_.getAuthEvent()\n .then(function(authEvent) {\n // Save partial event locally.\n event = authEvent;\n // Delete partial event.\n return self.getAndDeletePartialEventManager_.removeAuthEvent();\n }).then(function() {\n // Return the locally saved partial event.\n return event;\n });\n};\n\n\n/**\n * Extracts the Auth event pertaining to the incoming URL.\n * @param {!fireauth.AuthEvent} partialEvent The partial Auth event.\n * @param {string} url The incoming universal link.\n * @return {?fireauth.AuthEvent} The resolved Auth event corresponding to the\n * callback URL. This is null if no event is found.\n * @private\n */\nfireauth.CordovaHandler.prototype.extractAuthEventFromUrl_ =\n function(partialEvent, url) {\n // Default no redirect event result.\n var authEvent = null;\n // Parse the deep link within the dynamic link URL.\n var callbackUrl = fireauth.DynamicLink.parseDeepLink(url);\n // Confirm it is actually a callback URL.\n // Currently the universal link will be of this format:\n // https://<AUTH_DOMAIN>/__/auth/callback<OAUTH_RESPONSE>\n // This is a fake URL but is not intended to take the user anywhere\n // and just redirect to the app.\n if (callbackUrl.indexOf('/__/auth/callback') != -1) {\n // Check if there is an error in the URL.\n // This mechanism is also used to pass errors back to the app:\n // https://<AUTH_DOMAIN>/__/auth/callback?firebaseError=<STRINGIFIED_ERROR>\n var uri = goog.Uri.parse(callbackUrl);\n // Get the error object corresponding to the stringified error if found.\n var errorObject = fireauth.util.parseJSON(\n uri.getParameterValue('firebaseError') || null);\n var error = typeof errorObject === 'object' ?\n fireauth.AuthError.fromPlainObject(\n /** @type {?Object} */ (errorObject)) :\n null;\n if (error) {\n // Construct the full failed Auth event.\n authEvent = new fireauth.AuthEvent(\n partialEvent.getType(),\n partialEvent.getEventId(),\n null,\n null,\n error,\n null,\n partialEvent.getTenantId());\n } else {\n // Construct the full successful Auth event.\n authEvent = new fireauth.AuthEvent(\n partialEvent.getType(),\n partialEvent.getEventId(),\n callbackUrl,\n partialEvent.getSessionId(),\n null,\n null,\n partialEvent.getTenantId());\n }\n }\n return authEvent;\n};\n\n\n/**\n * Sets the internal Auth event listener. This listens to incoming universal\n * links and on detection, repackages them into an Auth event and then\n * dispatches the events in all event listeners.\n * @private\n */\nfireauth.CordovaHandler.prototype.setAuthEventListener_ = function() {\n // https://github.com/nordnet/cordova-universal-links-plugin-fix\n var self = this;\n // Default no redirect event result.\n var noEvent = new fireauth.AuthEvent(\n fireauth.AuthEvent.Type.UNKNOWN,\n null,\n null,\n null,\n new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT));\n var initialResolve = false;\n // On initialization, if no incoming universal link detected, trigger\n // no Auth event (no redirect operation previously called) after waiting\n // for a short period of time.\n var noEventTimer = goog.Timer.promise(this.initialTimeout_).then(function() {\n // Delete any pending unhandled event.\n return self.getPartialStoredEvent_().then(function(event) {\n // On timeout trigger noEvent if not already resolved in link\n // subscriber.\n if (!initialResolve) {\n self.dispatchEvent_(noEvent);\n }\n });\n });\n // No event name needed, subscribe to all incoming universal links.\n var universalLinkCb = function(eventData) {\n initialResolve = true;\n // Cancel no event timer.\n if (noEventTimer) {\n noEventTimer.cancel();\n }\n // Incoming link detected.\n // Check for any stored partial event.\n self.getPartialStoredEvent_().then(function(event) {\n // Initialize to an unknown event.\n var authEvent = noEvent;\n // Confirm OAuth response included.\n if (event && eventData && eventData['url']) {\n // Construct complete event. Default to unknown event if none found.\n authEvent = self.extractAuthEventFromUrl_(event, eventData['url']) ||\n noEvent;\n }\n // Dispatch Auth event.\n self.dispatchEvent_(authEvent);\n });\n };\n // iOS 7 or 8 custom URL schemes.\n // This is also the current default behavior for iOS 9+.\n // For this to work, cordova-plugin-customurlscheme needs to be installed.\n // https://github.com/EddyVerbruggen/Custom-URL-scheme\n // Do not overwrite the existing developer's URL handler.\n var existingHandlerOpenURL = goog.global['handleOpenURL'];\n goog.global['handleOpenURL'] = function(url) {\n var appIdentifier =\n fireauth.util.getObjectRef('BuildInfo.packageName', goog.global);\n // Apply case insensitive match. While bundle IDs are case sensitive,\n // when creating a new app, Apple verifies the Bundle ID using\n // case-insensitive search. So it is not possible that an app in the app\n // store try to impersonate another one by lower/upper casing characters.\n if (url.toLowerCase().indexOf(appIdentifier.toLowerCase() + '://') == 0) {\n universalLinkCb({\n 'url': url\n });\n }\n // Call the developer's handler if it is present.\n if (typeof existingHandlerOpenURL === 'function') {\n try {\n existingHandlerOpenURL(url);\n } catch(e) {\n // This doesn't swallow the error but also does not interrupt the flow.\n console.error(e);\n }\n }\n };\n fireauth.UniversalLinkSubscriber.getInstance().subscribe(universalLinkCb);\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n * listener to add.\n * @override\n */\nfireauth.CordovaHandler.prototype.addAuthEventListener = function(listener) {\n // TODO: consider creating an abstract base class that OAuth handlers\n // extend with add, remove Auth event listeners and dispatcher methods.\n this.authEventListeners_.push(listener);\n // Set internal listener to Auth events. This will be ignored on subsequent\n // calls.\n this.getInitialAuthEvent_().thenCatch(function(error) {\n // Suppress this error as it should be caught through other actionable\n // public methods.\n // This would typically happen on invalid Cordova setup, when the OAuth\n // plugins are not installed. This should still trigger the Auth event\n // as developers are not forced to use OAuth sign-in in their Cordova app.\n // This is needed for onAuthStateChanged listener to trigger initially.\n if (error.code === 'auth/invalid-cordova-configuration') {\n var noEvent = new fireauth.AuthEvent(\n fireauth.AuthEvent.Type.UNKNOWN,\n null,\n null,\n null,\n new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT));\n listener(noEvent);\n }\n });\n};\n\n\n/**\n * @param {!function(?fireauth.AuthEvent):boolean} listener The Auth event\n * listener to remove.\n * @override\n */\nfireauth.CordovaHandler.prototype.removeAuthEventListener = function(listener) {\n goog.array.removeAllIf(this.authEventListeners_, function(ele) {\n return ele == listener;\n });\n};\n\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the fireauth.storage.PendingRedirectManager class which\n * provides utilities to store, retrieve and delete the state of whether there\n * is a pending redirect operation previously triggered.\n */\n\ngoog.provide('fireauth.storage.PendingRedirectManager');\n\ngoog.require('fireauth.authStorage');\n\n\n/**\n * Defines the pending redirect storage manager. It provides methods\n * to store, retrieve and delete the state of whether there is a pending\n * redirect operation previously triggered.\n * @param {string} appId The Auth state's application ID.\n * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage\n * manager to use. If none is provided, the default global instance is used.\n * @constructor @struct @final\n */\nfireauth.storage.PendingRedirectManager = function(appId, opt_manager) {\n /** @const @private{string} appId The Auth state's application ID. */\n this.appId_ = appId;\n /**\n * @const @private{!fireauth.authStorage.Manager} The underlying storage\n * manager.\n */\n this.manager_ = opt_manager || fireauth.authStorage.Manager.getInstance();\n};\n\n\n/**\n * @const @private{!string} The pending redirect flag.\n */\nfireauth.storage.PendingRedirectManager.PENDING_FLAG_ = 'pending';\n\n\n/**\n * @const @private{!fireauth.authStorage.Key} The pending redirect status\n * storage identifier key.\n */\nfireauth.storage.PendingRedirectManager.PENDING_REDIRECT_KEY_ = {\n name: 'pendingRedirect',\n persistent: fireauth.authStorage.Persistence.SESSION\n};\n\n\n/**\n * Stores the pending redirect operation for the provided application ID.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.PendingRedirectManager.prototype.setPendingStatus =\n function() {\n return this.manager_.set(\n fireauth.storage.PendingRedirectManager.PENDING_REDIRECT_KEY_,\n fireauth.storage.PendingRedirectManager.PENDING_FLAG_,\n this.appId_);\n};\n\n\n/**\n * Removes the stored pending redirect operation for provided app ID.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.PendingRedirectManager.prototype.removePendingStatus =\n function() {\n return this.manager_.remove(\n fireauth.storage.PendingRedirectManager.PENDING_REDIRECT_KEY_,\n this.appId_);\n};\n\n\n/**\n * @return {!goog.Promise<boolean>} A promise that resolves with a boolean\n * whether there is a pending redirect operaiton for the provided app ID.\n */\nfireauth.storage.PendingRedirectManager.prototype.getPendingStatus =\n function() {\n return this.manager_.get(\n fireauth.storage.PendingRedirectManager.PENDING_REDIRECT_KEY_,\n this.appId_).then(function(response) {\n return response ==\n fireauth.storage.PendingRedirectManager.PENDING_FLAG_;\n });\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the Auth event manager instance.\n */\n\ngoog.provide('fireauth.AuthEventHandler');\ngoog.provide('fireauth.AuthEventManager');\ngoog.provide('fireauth.AuthEventManager.Result');\ngoog.provide('fireauth.PopupAuthEventProcessor');\ngoog.provide('fireauth.RedirectAuthEventProcessor');\n\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.CordovaHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.storage.PendingRedirectManager');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\ngoog.require('goog.array');\n\n\n/**\n * Initializes the Auth event manager which provides the mechanism to connect\n * external Auth events to their corresponding listeners.\n * @param {string} authDomain The Firebase authDomain used to determine the\n * OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n * request.\n * @constructor\n */\nfireauth.AuthEventManager = function(authDomain, apiKey, appName) {\n /**\n * @private {!Object<string, boolean>} The map of processed auth event IDs.\n */\n this.processedEvents_ = {};\n /** @private {number} The last saved processed event time in milliseconds. */\n this.lastProcessedEventTime_ = 0;\n /** @private {string} The Auth domain. */\n this.authDomain_ = authDomain;\n /** @private {string} The browser API key. */\n this.apiKey_ = apiKey;\n /** @private {string} The App name. */\n this.appName_ = appName;\n /**\n * @private {!Array<!fireauth.AuthEventHandler>} List of subscribed handlers.\n */\n this.subscribedHandlers_ = [];\n /**\n * @private {boolean} Whether the Auth event manager instance is initialized.\n */\n this.initialized_ = false;\n /** @private {function(?fireauth.AuthEvent)} The Auth event handler. */\n this.authEventHandler_ = goog.bind(this.handleAuthEvent_, this);\n /** @private {!fireauth.RedirectAuthEventProcessor} The redirect event\n * processor. */\n this.redirectAuthEventProcessor_ =\n new fireauth.RedirectAuthEventProcessor(this);\n /** @private {!fireauth.PopupAuthEventProcessor} The popup event processor. */\n this.popupAuthEventProcessor_ = new fireauth.PopupAuthEventProcessor(this);\n /**\n * @private {!fireauth.storage.PendingRedirectManager} The pending redirect\n * storage manager instance.\n */\n this.pendingRedirectStorageManager_ =\n new fireauth.storage.PendingRedirectManager(\n fireauth.AuthEventManager.getKey_(this.apiKey_, this.appName_));\n\n /**\n * @private {!Object.<!fireauth.AuthEvent.Type, !fireauth.AuthEventProcessor>}\n * Map containing Firebase event processor instances keyed by event type.\n */\n this.typeToManager_ = {};\n this.typeToManager_[fireauth.AuthEvent.Type.UNKNOWN] =\n this.redirectAuthEventProcessor_;\n this.typeToManager_[fireauth.AuthEvent.Type.SIGN_IN_VIA_REDIRECT] =\n this.redirectAuthEventProcessor_;\n this.typeToManager_[fireauth.AuthEvent.Type.LINK_VIA_REDIRECT] =\n this.redirectAuthEventProcessor_;\n this.typeToManager_[fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT] =\n this.redirectAuthEventProcessor_;\n this.typeToManager_[fireauth.AuthEvent.Type.SIGN_IN_VIA_POPUP] =\n this.popupAuthEventProcessor_;\n this.typeToManager_[fireauth.AuthEvent.Type.LINK_VIA_POPUP] =\n this.popupAuthEventProcessor_;\n this.typeToManager_[fireauth.AuthEvent.Type.REAUTH_VIA_POPUP] =\n this.popupAuthEventProcessor_;\n /**\n * @private {!fireauth.OAuthSignInHandler} The OAuth sign in handler depending\n * on the current environment.\n */\n this.oauthSignInHandler_ =\n fireauth.AuthEventManager.instantiateOAuthSignInHandler(\n this.authDomain_, this.apiKey_, this.appName_,\n firebase.SDK_VERSION || null,\n fireauth.constants.clientEndpoint);\n};\n\n\n/**\n * @const {number} The number of milliseconds since the last processed\n * event before the event duplication cache is cleared. This is currently\n * 10 minutes.\n */\nfireauth.AuthEventManager.EVENT_DUPLICATION_CACHE_DURATION = 10 * 60 * 1000;\n\n\n/**\n * @return {!fireauth.RedirectAuthEventProcessor} The redirect event processor.\n */\nfireauth.AuthEventManager.prototype.getRedirectAuthEventProcessor = function() {\n return this.redirectAuthEventProcessor_;\n};\n\n\n/** @return {!fireauth.PopupAuthEventProcessor} The popup event processor. */\nfireauth.AuthEventManager.prototype.getPopupAuthEventProcessor = function() {\n return this.popupAuthEventProcessor_;\n};\n\n\n/**\n * Instantiates an OAuth sign-in handler depending on the current environment\n * and returns it.\n * @param {string} authDomain The Firebase authDomain used to determine the\n * OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The App ID for the Auth instance that triggered this\n * request.\n * @param {?string} version The SDK client version.\n * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc).\n * @return {!fireauth.OAuthSignInHandler} The OAuth sign in handler depending\n * on the current environment.\n */\nfireauth.AuthEventManager.instantiateOAuthSignInHandler =\n function(authDomain, apiKey, appName, version, opt_endpointId) {\n // This assumes that android/iOS file environment must be a Cordova\n // environment which is not true. This is the best way currently available\n // to instantiate this synchronously without waiting for checkIfCordova to\n // resolve. If it is determined that the Cordova was falsely detected, it will\n // be caught via actionable public popup and redirect methods.\n return fireauth.util.isAndroidOrIosCordovaScheme() ?\n new fireauth.CordovaHandler(\n authDomain, apiKey, appName, version, undefined, undefined,\n opt_endpointId) :\n new fireauth.iframeclient.IfcHandler(\n authDomain, apiKey, appName, version, opt_endpointId);\n};\n\n\n/** Reset iframe. This will require reinitializing it.*/\nfireauth.AuthEventManager.prototype.reset = function() {\n // Reset initialized status. This will force a popup request to re-initialize\n // the iframe.\n this.initialized_ = false;\n // Remove any previous existing Auth event listener.\n this.oauthSignInHandler_.removeAuthEventListener(this.authEventHandler_);\n // Construct a new instance of OAuth sign in handler.\n\n this.oauthSignInHandler_ =\n fireauth.AuthEventManager.instantiateOAuthSignInHandler(\n this.authDomain_, this.apiKey_, this.appName_,\n firebase.SDK_VERSION || null);\n this.processedEvents_ = {};\n};\n\n\n/**\n * Clears the cached redirect result as long as there is no pending redirect\n * result being processed. Unrecoverable errors will not be cleared.\n */\nfireauth.AuthEventManager.prototype.clearRedirectResult = function() {\n this.redirectAuthEventProcessor_.clearRedirectResult();\n};\n\n\n/**\n * @typedef {{\n * user: (?fireauth.AuthUser|undefined),\n * credential: (?fireauth.AuthCredential|undefined),\n * operationType: (?string|undefined),\n * additionalUserInfo: (?fireauth.AdditionalUserInfo|undefined)\n * }}\n */\nfireauth.AuthEventManager.Result;\n\n\n/**\n * Whether to enable Auth event manager subscription.\n * @const {boolean}\n */\nfireauth.AuthEventManager.ENABLED = true;\n\n\n/**\n * Initializes the ifchandler and add Auth event listener on it.\n * @return {!goog.Promise} The promise that resolves when the iframe is ready.\n */\nfireauth.AuthEventManager.prototype.initialize = function() {\n var self = this;\n // Initialize once.\n if (!this.initialized_) {\n this.initialized_ = true;\n // Listen to Auth events on iframe.\n this.oauthSignInHandler_.addAuthEventListener(this.authEventHandler_);\n }\n var previousOauthSignInHandler = this.oauthSignInHandler_;\n // This should initialize ifchandler underneath.\n // Return on OAuth handler ready promise.\n // Check for error in ifcHandler used to embed the iframe.\n return this.oauthSignInHandler_.initializeAndWait()\n .thenCatch(function(error) {\n // Force ifchandler to reinitialize on retrial.\n if (self.oauthSignInHandler_ == previousOauthSignInHandler) {\n // If a new OAuth sign in handler was already created, do not reset.\n self.reset();\n }\n throw error;\n });\n};\n\n\n/**\n * Called after it is determined that there is no pending redirect result.\n * Will populate the redirect result if it is guaranteed to be null and will\n * force an early initialization of the OAuth sign in handler if the\n * environment requires it.\n * @private\n */\nfireauth.AuthEventManager.prototype.initializeWithNoPendingRedirectResult_ =\n function() {\n var self = this;\n // Check if the OAuth sign in handler should be initialized early in all\n // cases.\n if (this.oauthSignInHandler_.shouldBeInitializedEarly()) {\n this.initialize().thenCatch(function(error) {\n // Current environment was falsely detected as Cordova, trigger a fake\n // Auth event to notify getRedirectResult that operation is not supported.\n var notSupportedEvent = new fireauth.AuthEvent(\n fireauth.AuthEvent.Type.UNKNOWN,\n null,\n null,\n null,\n new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n if (fireauth.AuthEventManager.isCordovaFalsePositive_(\n /** @type {?fireauth.AuthError} */ (error))) {\n self.handleAuthEvent_(notSupportedEvent);\n }\n });\n }\n // For environments where storage is volatile, we can't determine that\n // there is no pending redirect response. This is true in Cordova\n // where an activity would be destroyed in some cases and the\n // sessionStorage is lost.\n if (!this.oauthSignInHandler_.hasVolatileStorage()) {\n // Since there is no redirect result, it is safe to default to empty\n // redirect result instead of blocking on this.\n // The downside here is that on iOS devices, calling signInWithPopup\n // after getRedirectResult resolves and the iframe does not finish\n // loading, the popup event propagating to the iframe would not be\n // detected. This is because in iOS devices, storage events only trigger\n // in iframes but are not actually saved in web storage. The iframe must\n // be embedded and ready before the storage event propagates. Otherwise\n // it won't be detected.\n this.redirectAuthEventProcessor_.defaultToEmptyResponse();\n }\n};\n\n\n/**\n * Subscribes an Auth event handler to list of handlers.\n * @param {!fireauth.AuthEventHandler} handler The instance to subscribe.\n */\nfireauth.AuthEventManager.prototype.subscribe = function(handler) {\n if (!goog.array.contains(this.subscribedHandlers_, handler)) {\n this.subscribedHandlers_.push(handler);\n }\n if (this.initialized_) {\n return;\n }\n var self = this;\n // Check pending redirect status.\n this.pendingRedirectStorageManager_.getPendingStatus()\n .then(function(status) {\n // Pending redirect detected.\n if (status) {\n // Remove pending status and initialize.\n self.pendingRedirectStorageManager_.removePendingStatus()\n .then(function() {\n self.initialize().thenCatch(function(error) {\n // Current environment was falsely detected as Cordova, trigger a\n // fake Auth event to notify getRedirectResult that operation is\n // not supported.\n var notSupportedEvent = new fireauth.AuthEvent(\n fireauth.AuthEvent.Type.UNKNOWN,\n null,\n null,\n null,\n new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n if (fireauth.AuthEventManager.isCordovaFalsePositive_(\n /** @type {?fireauth.AuthError} */ (error))) {\n self.handleAuthEvent_(notSupportedEvent);\n }\n });\n });\n } else {\n // No previous redirect, default to empty response.\n self.initializeWithNoPendingRedirectResult_();\n }\n }).thenCatch(function(error) {\n // Error checking pending status, default to empty response.\n self.initializeWithNoPendingRedirectResult_();\n });\n};\n\n\n/**\n * @param {!fireauth.AuthEventHandler} handler The possible subscriber.\n * @return {boolean} Whether the handle is subscribed.\n */\nfireauth.AuthEventManager.prototype.isSubscribed = function(handler) {\n return goog.array.contains(this.subscribedHandlers_, handler);\n};\n\n\n/**\n * Unsubscribes an Auth event handler to list of handlers.\n * @param {!fireauth.AuthEventHandler} handler The instance to unsubscribe.\n */\nfireauth.AuthEventManager.prototype.unsubscribe = function(handler) {\n goog.array.removeAllIf(this.subscribedHandlers_, function(ele) {\n return ele == handler;\n });\n};\n\n\n/**\n * @param {?fireauth.AuthEvent} authEvent External Auth event to check.\n * @return {boolean} Whether the event was previously processed.\n * @private\n */\nfireauth.AuthEventManager.prototype.hasProcessedAuthEvent_ =\n function(authEvent) {\n // Prevent duplicate event tracker from growing too large.\n if (goog.now() - this.lastProcessedEventTime_ >=\n fireauth.AuthEventManager.EVENT_DUPLICATION_CACHE_DURATION) {\n this.processedEvents_ = {};\n this.lastProcessedEventTime_ = 0;\n }\n if (authEvent && authEvent.getUid() &&\n this.processedEvents_.hasOwnProperty(authEvent.getUid())) {\n // If event is already processed, ignore it.\n return true;\n }\n return false;\n};\n\n\n/**\n * Saves the provided event uid to prevent processing duplication.\n * @param {?fireauth.AuthEvent} authEvent External Auth event to track in\n * processed list of events.\n * @private\n */\nfireauth.AuthEventManager.prototype.saveProcessedAuthEvent_ =\n function(authEvent) {\n if (authEvent &&\n (authEvent.getSessionId() || authEvent.getEventId())) {\n // Save processed event ID. We keep the cache for 10 minutes to prevent it\n // from growing too large.\n this.processedEvents_[\n /** @type {string} */ (authEvent.getUid())] = true;\n // Save last processing time.\n this.lastProcessedEventTime_ = goog.now();\n }\n};\n\n\n/**\n * Handles external Auth event detected by the OAuth sign-in handler.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @return {boolean} Whether the event found an appropriate owner that can\n * handle it. This signals to the OAuth helper iframe that the event is safe\n * to delete.\n * @private\n */\nfireauth.AuthEventManager.prototype.handleAuthEvent_ = function(authEvent) {\n // This should not happen as fireauth.iframe.AuthRelay will not send null\n // events.\n if (!authEvent) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT);\n }\n if (this.hasProcessedAuthEvent_(authEvent)) {\n // If event is already processed, ignore it.\n return false;\n }\n // Initialize event processed status to false. When set to false, the event is\n // not clear to delete in the OAuth helper iframe as the owner of this event\n // could be a user in another tab.\n var processed = false;\n // Lookup a potential handler for this event.\n for (var i = 0; i < this.subscribedHandlers_.length; i++) {\n var potentialHandler = this.subscribedHandlers_[i];\n if (potentialHandler.canHandleAuthEvent(\n authEvent.getType(), authEvent.getEventId())) {\n var eventManager = this.typeToManager_[authEvent.getType()];\n if (eventManager) {\n eventManager.processAuthEvent(authEvent, potentialHandler);\n // Prevent events with event IDs or session IDs from duplicate\n // processing.\n this.saveProcessedAuthEvent_(authEvent);\n }\n // Event has been processed, free to clear in OAuth helper.\n processed = true;\n break;\n }\n }\n // If no redirect response ready yet, default to an empty response.\n this.redirectAuthEventProcessor_.defaultToEmptyResponse();\n // Notify iframe of processed status.\n return processed;\n};\n\n\n/**\n * The popup promise timeout delay with units in ms between the time the iframe\n * is ready (successfully embedded on the page) and the time the popup Auth\n * event is detected in the parent container.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.AuthEventManager.POPUP_TIMEOUT_MS_ =\n new fireauth.util.Delay(2000, 10000);\n\n\n/**\n * The redirect promise timeout delay with units in ms. Unlike the popup\n * timeout, this covers the entire duration from start to getRedirectResult\n * resolution.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.AuthEventManager.REDIRECT_TIMEOUT_MS_ =\n new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * Returns the redirect result. If coming back from a successful redirect sign\n * in, will resolve to the signed in user. If coming back from an unsuccessful\n * redirect sign, will reject with the proper error. If no redirect operation\n * called, resolves with null.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthEventManager.prototype.getRedirectResult = function() {\n return this.redirectAuthEventProcessor_.getRedirectResult();\n};\n\n\n/**\n * Processes the popup request. The popup instance must be provided externally\n * and on error, the requestor must close the window.\n * @param {?Window} popupWin The popup window reference.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {string=} opt_eventId The optional event ID.\n * @param {boolean=} opt_alreadyRedirected Whether popup is already redirected\n * to final destination.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise} The popup window promise.\n */\nfireauth.AuthEventManager.prototype.processPopup =\n function(popupWin, mode, provider, opt_eventId, opt_alreadyRedirected,\n opt_tenantId) {\n var self = this;\n return this.oauthSignInHandler_.processPopup(\n popupWin,\n mode,\n provider,\n // On initialization, add Auth event listener if not already added.\n function() {\n if (!self.initialized_) {\n self.initialized_ = true;\n // Listen to Auth events on iframe.\n self.oauthSignInHandler_.addAuthEventListener(self.authEventHandler_);\n }\n },\n // On error, reset to force re-initialization on retrial.\n function(error) {\n self.reset();\n },\n opt_eventId,\n opt_alreadyRedirected,\n opt_tenantId);\n};\n\n\n/**\n * @param {?fireauth.AuthError} error The error to check for Cordova false\n * positive.\n * @return {boolean} Whether the current environment was falsely identified as\n * Cordova.\n * @private\n */\nfireauth.AuthEventManager.isCordovaFalsePositive_ = function(error) {\n if (error && error['code'] == 'auth/cordova-not-ready') {\n return true;\n }\n return false;\n};\n\n\n/**\n * Processes the redirect request.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {string=} opt_eventId The optional event ID.\n * @param {?string=} opt_tenantId The optional tenant ID.\n * @return {!goog.Promise}\n */\nfireauth.AuthEventManager.prototype.processRedirect =\n function(mode, provider, opt_eventId, opt_tenantId) {\n var self = this;\n var error;\n // Save pending status first.\n return this.pendingRedirectStorageManager_.setPendingStatus()\n .then(function() {\n // Try to redirect.\n return self.oauthSignInHandler_.processRedirect(\n mode, provider, opt_eventId, opt_tenantId)\n .thenCatch(function(e) {\n if (fireauth.AuthEventManager.isCordovaFalsePositive_(\n /** @type {?fireauth.AuthError} */ (e))) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED);\n }\n // On failure, remove pending status and rethrow the error.\n error = e;\n return self.pendingRedirectStorageManager_.removePendingStatus()\n .then(function() {\n throw error;\n });\n })\n .then(function() {\n // Resolve, if the OAuth handler unloads the page on redirect.\n if (!self.oauthSignInHandler_.unloadsOnRedirect()) {\n // Relevant to Cordova case, will not matter in web case where\n // browser redirects.\n // In Cordova, the activity could still be running in the background\n // so we need to wait for getRedirectResult to resolve before\n // resolving this current promise.\n // Otherwise, if the activity is destroyed, getRedirectResult would\n // be used.\n // At this point, authEvent should have been triggered.\n // When this promise resolves, the developer should be able to\n // call getRedirectResult to get the result of this operation.\n // Remove pending status as result should be resolved.\n return self.pendingRedirectStorageManager_.removePendingStatus()\n .then(function() {\n // Ensure redirect result ready before resolving.\n return self.getRedirectResult();\n }).then(function(result) {\n // Do nothing. Developer expected to call getRedirectResult to\n // get result.\n }).thenCatch(function(error) {\n // Do nothing. Developer expected to call getRedirectResult to\n // get result.\n });\n } else {\n // For environments that will unload the page on redirect, keep\n // the promise pending on success. This makes it easier to reuse\n // the same code for Cordova environment and browser environment.\n // The developer can always add getRedirectResult on promise\n // resolution and expect that when it runs, the redirect operation\n // was completed.\n return new goog.Promise(function(resolve, reject) {\n // Keep this pending.\n });\n }\n });\n });\n};\n\n\n/**\n * Waits for popup window to close. When closed start timeout listener for popup\n * pending promise. If in the process, it was detected that the iframe does not\n * support web storage, the popup is closed and the web storage unsupported\n * error is thrown.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @param {!fireauth.AuthEvent.Type} mode The Auth event type.\n * @param {!Window} popupWin The popup window.\n * @param {?string=} opt_eventId The event ID.\n * @return {!goog.Promise}\n */\nfireauth.AuthEventManager.prototype.startPopupTimeout =\n function(owner, mode, popupWin, opt_eventId) {\n return this.oauthSignInHandler_.startPopupTimeout(\n popupWin,\n // On popup error such as popup closed by user or web storage not\n // supported.\n function(error) {\n // Notify owner of the error.\n owner.resolvePendingPopupEvent(mode, null, error, opt_eventId);\n },\n fireauth.AuthEventManager.POPUP_TIMEOUT_MS_.get());\n};\n\n\n\n/**\n * @private {!Object.<string, !fireauth.AuthEventManager>} Map containing\n * Firebase event manager instances keyed by Auth event manager ID.\n */\nfireauth.AuthEventManager.manager_ = {};\n\n\n/**\n * The separator for manager keys to concatenate app name and apiKey.\n * @const {string}\n * @private\n */\nfireauth.AuthEventManager.KEY_SEPARATOR_ = ':';\n\n\n/**\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The Auth instance that initiated the Auth event.\n * @return {string} The key identifying the Auth event manager instance.\n * @private\n */\nfireauth.AuthEventManager.getKey_ = function(apiKey, appName) {\n return apiKey + fireauth.AuthEventManager.KEY_SEPARATOR_ + appName;\n};\n\n\n/**\n * @param {string} authDomain The Firebase authDomain used to determine the\n * OAuth helper page domain.\n * @param {string} apiKey The API key for sending backend Auth requests.\n * @param {string} appName The Auth instance that initiated the Auth event\n * manager.\n * @return {!fireauth.AuthEventManager} the requested manager instance.\n */\nfireauth.AuthEventManager.getManager = function(authDomain, apiKey, appName) {\n // Construct storage key.\n var key = fireauth.AuthEventManager.getKey_(apiKey, appName);\n if (!fireauth.AuthEventManager.manager_[key]) {\n fireauth.AuthEventManager.manager_[key] =\n new fireauth.AuthEventManager(authDomain, apiKey, appName);\n }\n return fireauth.AuthEventManager.manager_[key];\n};\n\n\n\n/**\n * The interface that represents a specific type of Auth event processor.\n * @interface\n */\nfireauth.AuthEventProcessor = function() {};\n\n\n/**\n * Completes the processing of an external Auth event detected by the embedded\n * iframe.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n */\nfireauth.AuthEventProcessor.prototype.processAuthEvent =\n function(authEvent, owner) {};\n\n\n\n/**\n * Redirect Auth event manager.\n * @param {!fireauth.AuthEventManager} manager The parent Auth event manager.\n * @constructor\n * @implements {fireauth.AuthEventProcessor}\n */\nfireauth.RedirectAuthEventProcessor = function(manager) {\n this.manager_ = manager;\n // Only one redirect result can be tracked on first load.\n /**\n * @private {?function():!goog.Promise<!fireauth.AuthEventManager.Result>}\n * Redirect result resolver. This will be used to resolve the\n * getRedirectResult promise. When the redirect result is obtained, this\n * field will be set.\n */\n this.redirectedUserPromise_ = null;\n /**\n * @private {!Array<function(!fireauth.AuthEventManager.Result)>} Pending\n * promise redirect resolver. When the redirect result is obtained and the\n * user is detected, this will be called.\n */\n this.redirectResolve_ = [];\n /**\n * @private {!Array<function(*)>} Pending Promise redirect rejecter. When the\n * redirect result is obtained and an error is detected, this will be\n * called.\n */\n this.redirectReject_ = [];\n /** @private {?goog.Promise} Pending timeout promise for redirect. */\n this.redirectTimeoutPromise_ = null;\n /**\n * @private {boolean} Whether redirect result is resolved. This is true\n * when a valid Auth event has been triggered.\n */\n this.redirectResultResolved_ = false;\n /**\n * @private {boolean} Whether an unrecoverable error was detected. This\n * includes web storage unsupported or operation not allowed errors.\n */\n this.unrecoverableErrorDetected_ = false;\n};\n\n\n/** Reset any previous redirect result. */\nfireauth.RedirectAuthEventProcessor.prototype.reset = function() {\n // Reset to allow override getRedirectResult. This is relevant for Cordova\n // environment where redirect events do not necessarily unload the current\n // page.\n this.redirectedUserPromise_ = null;\n if (this.redirectTimeoutPromise_) {\n this.redirectTimeoutPromise_.cancel();\n this.redirectTimeoutPromise_ = null;\n }\n};\n\n\n/**\n * Completes the processing of an external Auth event detected by the embedded\n * iframe.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @override\n */\nfireauth.RedirectAuthEventProcessor.prototype.processAuthEvent =\n function(authEvent, owner) {\n // This should not happen as fireauth.iframe.AuthRelay will not send null\n // events.\n if (!authEvent) {\n return goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n }\n // Reset any pending redirect result. This event will overwrite it.\n this.reset();\n this.redirectResultResolved_ = true;\n var mode = authEvent.getType();\n var eventId = authEvent.getEventId();\n // Check if web storage is not supported in the iframe.\n var isWebStorageNotSupported =\n authEvent.getError() &&\n authEvent.getError()['code'] == 'auth/web-storage-unsupported';\n /// Check if operation is supported in this environment.\n var isOperationNotSupported =\n authEvent.getError() &&\n authEvent.getError()['code'] == 'auth/operation-not-supported-in-this-' +\n 'environment';\n this.unrecoverableErrorDetected_ =\n !!(isWebStorageNotSupported || isOperationNotSupported);\n // UNKNOWN mode is always triggered on load by iframe when no popup/redirect\n // data is available. If web storage unsupported error is thrown, process as\n // error and not as unknown event. If the operation is not supported in this\n // environment, also treat as an error and not as an unknown event.\n if (mode == fireauth.AuthEvent.Type.UNKNOWN &&\n !isWebStorageNotSupported &&\n !isOperationNotSupported) {\n return this.processUnknownEvent_();\n } else if (authEvent.hasError()) {\n return this.processErrorEvent_(authEvent, owner);\n } else if (owner.getAuthEventHandlerFinisher(mode, eventId)) {\n return this.processSuccessEvent_(authEvent, owner);\n } else {\n return goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n }\n};\n\n\n/**\n * Sets an empty redirect result response when no redirect result is available.\n */\nfireauth.RedirectAuthEventProcessor.prototype.defaultToEmptyResponse =\n function() {\n // If the first event does not resolve redirectResult and no subscriber can\n // handle it, set redirect result to null.\n // An example of this scenario would be a link via redirect that was triggered\n // by a user that was not logged in. canHandleAuthEvent will be false for all\n // subscribers. So make sure getRedirectResult when called will resolve to a\n // null user.\n if (!this.redirectResultResolved_) {\n this.redirectResultResolved_ = true;\n // No Auth event available, getRedirectResult should resolve with null.\n this.setRedirectResult_(false, null, null);\n }\n};\n\n\n/**\n * Clears the cached redirect result as long as there is no pending redirect\n * result being processed. Unrecoverable errors will not be cleared.\n */\nfireauth.RedirectAuthEventProcessor.prototype.clearRedirectResult = function() {\n // Clear the result if it is already resolved and no unrecoverable errors are\n // detected.\n if (this.redirectResultResolved_ && !this.unrecoverableErrorDetected_) {\n this.setRedirectResult_(false, null, null);\n }\n};\n\n\n/**\n * Processes the unknown event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.processUnknownEvent_ =\n function() {\n // No Auth event available, getRedirectResult should resolve with null.\n this.setRedirectResult_(false, null, null);\n return goog.Promise.resolve();\n};\n\n\n/**\n * Processes an error event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.processErrorEvent_ =\n function(authEvent, owner) {\n // Set redirect result to resolve with null if event is not a redirect or\n // reject with error if event is an error.\n this.setRedirectResult_(true, null, authEvent.getError());\n return goog.Promise.resolve();\n};\n\n\n/**\n * Processes a successful event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.processSuccessEvent_ =\n function(authEvent, owner) {\n var self = this;\n var eventId = authEvent.getEventId();\n var mode = authEvent.getType();\n var handler = owner.getAuthEventHandlerFinisher(mode, eventId);\n var requestUri = /** @type {string} */ (authEvent.getUrlResponse());\n var sessionId = /** @type {string} */ (authEvent.getSessionId());\n var postBody = /** @type {?string} */ (authEvent.getPostBody());\n var tenantId = /** @type {?string} */ (authEvent.getTenantId());\n var isRedirect = fireauth.AuthEvent.isRedirect(authEvent);\n // Complete sign in or link account operation and then pass result to\n // relevant pending popup promise.\n return handler(requestUri, sessionId, tenantId, postBody)\n .then(function(popupRedirectResponse) {\n // Flow completed.\n // For a redirect operation resolve with the popupRedirectResponse,\n // otherwise resolve with null.\n self.setRedirectResult_(isRedirect, popupRedirectResponse, null);\n }).thenCatch(function(error) {\n // Flow not completed due to error.\n // For a redirect operation reject with the error, otherwise resolve\n // with null.\n self.setRedirectResult_(\n isRedirect, null, /** @type {!fireauth.AuthError} */ (error));\n // Always resolve.\n return;\n });\n};\n\n\n/**\n * Sets redirect error result.\n * @param {!fireauth.AuthError} error The redirect operation error.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.setRedirectReject_ =\n function(error) {\n // If a redirect error detected, reject getRedirectResult with that error.\n this.redirectedUserPromise_ = function() {\n return goog.Promise.reject(error);\n };\n // Reject all pending getRedirectResult promises.\n if (this.redirectReject_.length) {\n for (var i = 0; i < this.redirectReject_.length; i++) {\n this.redirectReject_[i](error);\n }\n }\n};\n\n\n/**\n * Sets redirect success result.\n * @param {!fireauth.AuthEventManager.Result} popupRedirectResult The\n * resolved user for a successful or null user redirect.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.setRedirectResolve_ =\n function(popupRedirectResult) {\n // If a redirect user detected, resolve getRedirectResult with the\n // popupRedirectResult.\n // Result should not be null in this case.\n this.redirectedUserPromise_ = function() {\n return goog.Promise.resolve(\n /** @type {!fireauth.AuthEventManager.Result} */ (popupRedirectResult));\n };\n // Resolve all pending getRedirectResult promises.\n if (this.redirectResolve_.length) {\n for (var i = 0; i < this.redirectResolve_.length; i++) {\n this.redirectResolve_[i](\n /** @type {!fireauth.AuthEventManager.Result} */ (\n popupRedirectResult));\n }\n }\n};\n\n\n/**\n * @param {boolean} isRedirect Whether Auth event is a redirect event.\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The\n * resolved user for a successful redirect. This user is null if no redirect\n * operation run.\n * @param {?fireauth.AuthError} error The redirect operation error.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.setRedirectResult_ =\n function(isRedirect, popupRedirectResult, error) {\n if (isRedirect) {\n // This is a redirect operation, either resolves with user or error.\n if (error) {\n // If a redirect error detected, reject getRedirectResult with that error.\n this.setRedirectReject_(error);\n } else {\n // If a redirect user detected, resolve getRedirectResult with the\n // popupRedirectResult.\n // Result should not be null in this case.\n this.setRedirectResolve_(\n /** @type {!fireauth.AuthEventManager.Result} */ (\n popupRedirectResult));\n }\n } else {\n // Not a redirect, set redirectUser_ to return null.\n this.setRedirectResolve_({\n 'user': null\n });\n }\n // Reset all pending promises.\n this.redirectResolve_ = [];\n this.redirectReject_ = [];\n};\n\n\n/**\n * Returns the redirect result. If coming back from a successful redirect sign\n * in, will resolve to the signed in user. If coming back from an unsuccessful\n * redirect sign, will reject with the proper error. If no redirect operation\n * called, resolves with null.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.RedirectAuthEventProcessor.prototype.getRedirectResult = function() {\n var self = this;\n // Initial result could be overridden in the case of Cordova.\n // Auth domain must be included for this to resolve.\n // If still pending just return the pending promise.\n var p = new goog.Promise(function(resolve, reject) {\n // The following logic works if this method was called before Auth event\n // is triggered.\n if (!self.redirectedUserPromise_) {\n // Save resolves and rejects of pending promise for redirect operation.\n self.redirectResolve_.push(resolve);\n self.redirectReject_.push(reject);\n // Start timeout listener to getRedirectResult pending promise.\n // Call this only when redirectedUserPromise_ is not determined.\n self.startRedirectTimeout_();\n } else {\n // Called after Auth event is triggered.\n self.redirectedUserPromise_().then(resolve, reject);\n }\n });\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (p);\n};\n\n\n/**\n * Starts timeout listener for getRedirectResult pending promise. This method\n * should not be called again after getRedirectResult's redirectedUserPromise_\n * is determined.\n * @private\n */\nfireauth.RedirectAuthEventProcessor.prototype.startRedirectTimeout_ =\n function() {\n // Expire pending timeout promise for popup operation.\n var self = this;\n var error = new fireauth.AuthError(\n fireauth.authenum.Error.TIMEOUT);\n if (this.redirectTimeoutPromise_) {\n this.redirectTimeoutPromise_.cancel();\n }\n // For redirect mode.\n this.redirectTimeoutPromise_ =\n goog.Timer.promise(fireauth.AuthEventManager.REDIRECT_TIMEOUT_MS_.get())\n .then(function() {\n // If not resolved yet, reject with timeout error.\n if (!self.redirectedUserPromise_) {\n // Consider redirect result resolved.\n self.redirectResultResolved_ = true;\n self.setRedirectResult_(true, null, error);\n }\n });\n\n};\n\n\n\n/**\n * Popup Auth event manager.\n * @param {!fireauth.AuthEventManager} manager The parent Auth event manager.\n * @constructor\n * @implements {fireauth.AuthEventProcessor}\n */\nfireauth.PopupAuthEventProcessor = function(manager) {\n this.manager_ = manager;\n};\n\n\n/**\n * Completes the processing of an external Auth event detected by the embedded\n * iframe.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @override\n */\nfireauth.PopupAuthEventProcessor.prototype.processAuthEvent =\n function(authEvent, owner) {\n // This should not happen as fireauth.iframe.AuthRelay will not send null\n // events.\n if (!authEvent) {\n return goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n }\n var mode = authEvent.getType();\n var eventId = authEvent.getEventId();\n if (authEvent.hasError()) {\n return this.processErrorEvent_(authEvent, owner);\n } else if (owner.getAuthEventHandlerFinisher(mode, eventId)) {\n return this.processSuccessEvent_(authEvent, owner);\n } else {\n return goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.INVALID_AUTH_EVENT));\n }\n};\n\n\n/**\n * Processes an error event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.PopupAuthEventProcessor.prototype.processErrorEvent_ =\n function(authEvent, owner) {\n var eventId = authEvent.getEventId();\n var mode = authEvent.getType();\n // For pending popup promises trigger rejects with the error.\n owner.resolvePendingPopupEvent(mode, null, authEvent.getError(), eventId);\n return goog.Promise.resolve();\n};\n\n\n/**\n * Processes a successful event.\n * @param {?fireauth.AuthEvent} authEvent External Auth event detected by\n * iframe.\n * @param {!fireauth.AuthEventHandler} owner The owner of the event.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.PopupAuthEventProcessor.prototype.processSuccessEvent_ =\n function(authEvent, owner) {\n var eventId = authEvent.getEventId();\n var mode = authEvent.getType();\n var handler = owner.getAuthEventHandlerFinisher(mode, eventId);\n // Successful operation, complete the exchange for an ID token.\n var requestUri = /** @type {string} */ (authEvent.getUrlResponse());\n var sessionId = /** @type {string} */ (authEvent.getSessionId());\n var postBody = /** @type {?string} */ (authEvent.getPostBody());\n var tenantId = /** @type {?string} */ (authEvent.getTenantId());\n // Complete sign in or link account operation and then pass result to\n // relevant pending popup promise.\n return handler(requestUri, sessionId, tenantId, postBody)\n .then(function(popupRedirectResponse) {\n // Flow completed.\n // Resolve pending popup promise if it exists.\n owner.resolvePendingPopupEvent(mode, popupRedirectResponse, null, eventId);\n }).thenCatch(function(error) {\n // Flow not completed due to error.\n // Resolve pending promise if it exists.\n owner.resolvePendingPopupEvent(\n mode, null, /** @type {!fireauth.AuthError} */ (error), eventId);\n // Always resolve.\n return;\n });\n};\n\n\n\n/**\n * The interface that represents an Auth event handler. It provides the\n * ability for the Auth event manager to determine the owner of an Auth event,\n * the ability to resolve a pending popup event and the appropriate handler for\n * an event.\n * @interface\n */\nfireauth.AuthEventHandler = function() {};\n\n\n/**\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The event ID.\n * @return {boolean} Whether the Auth event handler can handler the provided\n * event.\n */\nfireauth.AuthEventHandler.prototype.canHandleAuthEvent =\n function(mode, opt_eventId) {};\n\n\n/**\n * Completes the pending popup operation. If error is not null, rejects with the\n * error. Otherwise, it resolves with the popup redirect result.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The result\n * to resolve with when no error supplied.\n * @param {?fireauth.AuthError} error When supplied, the promise will reject.\n * @param {?string=} opt_eventId The event ID.\n */\nfireauth.AuthEventHandler.prototype.resolvePendingPopupEvent =\n function(mode, popupRedirectResult, error, opt_eventId) {};\n\n\n/**\n * Returns the handler's appropriate popup and redirect sign in operation\n * finisher.\n * @param {!fireauth.AuthEvent.Type} mode The Auth type mode.\n * @param {?string=} opt_eventId The optional event ID.\n * @return {?function(string, string, ?string,\n * ?string=):!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthEventHandler.prototype.getAuthEventHandlerFinisher =\n function(mode, opt_eventId) {};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the firebase.auth.AuthSettings structure.\n */\n\ngoog.provide('fireauth.AuthSettings');\n\n\n/**\n * The class used to initialize an Auth settings object currently used to\n * enable or disable app verification for testing.\n * @constructor\n */\nfireauth.AuthSettings = function() {\n this.appVerificationDisabledForTesting_ = false;\n Object.defineProperty(\n /** @type {!Object} */ (this),\n 'appVerificationDisabled',\n {\n /**\n * @this {!Object}\n * @return {boolean} The current status.\n */\n get: function() {\n return this.getAppVerificationDisabledForTesting();\n },\n /**\n * @this {!Object}\n * @param {boolean} value The new status.\n */\n set: function(value) {\n this.setAppVerificationDisabledForTesting(value);\n },\n enumerable: false\n });\n};\n\n\n/**\n * Sets whether app verification is disable for testing.\n * @param {boolean} status App verification status for testing.\n */\nfireauth.AuthSettings.prototype.setAppVerificationDisabledForTesting =\n function(status) {\n this.appVerificationDisabledForTesting_ = status;\n};\n\n\n/**\n * @return {boolean} Whether app verification is enabled or disabled for\n * testing.\n */\nfireauth.AuthSettings.prototype.getAppVerificationDisabledForTesting =\n function() {\n return this.appVerificationDisabledForTesting_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the firebase.auth.ConfirmationResult. This is needed\n * to provide first class support for phone Auth API: signInWithPhoneNumber,\n * linkWithPhoneNumber and reauthenticateWithPhoneNumber.\n */\n\ngoog.provide('fireauth.ConfirmationResult');\n\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.object');\ngoog.require('goog.Promise');\n\n\n/**\n * The confirmation result class. This takes in the verification ID returned\n * from the phone Auth provider and the credential resolver to run when\n * confirming with a verification code.\n * @param {string} verificationId The verification ID returned from the Phone\n * Auth provider after sending the verification code.\n * @param {!function(!fireauth.AuthCredential):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} credentialResolver a\n * function that takes in an AuthCredential and returns a promise that\n * resolves with a UserCredential object.\n * @constructor\n */\nfireauth.ConfirmationResult = function(verificationId, credentialResolver) {\n /**\n * @const @private {!function(!fireauth.AuthCredential):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} A function that takes\n * in an AuthCredential and returns a promise that resolves with a\n * UserCredential object.\n */\n this.credentialResolver_ = credentialResolver;\n // Set verificationId as read-only property.\n fireauth.object.setReadonlyProperty(this, 'verificationId', verificationId);\n};\n\n\n/**\n * Confirms the verification code and returns a promise that resolves with the\n * User Credential object.\n * @param {string} verificationCode The phone Auth verification code to use to\n * complete the Auth flow.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.ConfirmationResult.prototype.confirm = function(verificationCode) {\n // Initialize a phone Auth credential with the verification ID and code.\n var credential = fireauth.PhoneAuthProvider.credential(\n this['verificationId'], verificationCode);\n // Run the credential resolver with the phone Auth credential and return its\n // result.\n return this.credentialResolver_(credential);\n};\n\n\n/**\n * Initializes a ConfirmationResult using the provided phone number, app\n * verifier and returns it asynchronously. On code confirmation, the result will\n * resolve using the credential resolver provided.\n * @param {!fireauth.Auth} auth The corresponding Auth instance.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n * verifier.\n * @param {!function(!fireauth.AuthCredential):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} credentialResolver a\n * function that takes in an AuthCredential and returns a promise that\n * resolves with a UserCredential object.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.ConfirmationResult.initialize =\n function(auth, phoneNumber, appVerifier, credentialResolver) {\n // Initialize a phone Auth provider instance using the provided Auth\n // instance.\n var phoneAuthProvider = new fireauth.PhoneAuthProvider(auth);\n // Verify the phone number.\n return phoneAuthProvider.verifyPhoneNumber(phoneNumber, appVerifier)\n .then(function(verificationId) {\n // When code is sent and verification ID is returned, initialize a\n // ConfirmationResult with the returned verification ID and credential\n // resolver, and return that instance.\n return new fireauth.ConfirmationResult(\n verificationId, credentialResolver);\n });\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the firebase.auth.IdTokenResult class that is obtained\n * from getIdTokenResult. It contains the ID token JWT string and other helper\n * properties for getting different data associated with the token as well as\n * all the decoded payload claims.\n */\n\ngoog.provide('fireauth.IdTokenResult');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\n\n\n\n/**\n * This is the ID token result object obtained from getIdTokenResult. It\n * contains the ID token JWT string and other helper properties for getting\n * different data associated with the token as well as all the decoded payload\n * claims.\n * @param {string} tokenString The JWT token.\n * @constructor\n */\nfireauth.IdTokenResult = function(tokenString) {\n var idToken = fireauth.IdToken.parseIdTokenClaims(tokenString);\n if (!idToken || !idToken['exp'] || !idToken['auth_time'] || !idToken['iat']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'An internal error occurred. The token obtained by Firebase appears ' +\n 'to be malformed. Please retry the operation.');\n }\n fireauth.object.setReadonlyProperties(this, {\n 'token': tokenString,\n 'expirationTime': fireauth.util.utcTimestampToDateString(\n idToken['exp'] * 1000),\n 'authTime': fireauth.util.utcTimestampToDateString(\n idToken['auth_time'] * 1000),\n 'issuedAtTime': fireauth.util.utcTimestampToDateString(\n idToken['iat'] * 1000),\n 'signInProvider': (idToken['firebase'] &&\n idToken['firebase']['sign_in_provider']) ?\n idToken['firebase']['sign_in_provider'] : null,\n 'signInSecondFactor': (idToken['firebase'] &&\n idToken['firebase']['sign_in_second_factor']) ?\n idToken['firebase']['sign_in_second_factor'] : null,\n 'claims': idToken\n });\n};\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the multi-factor resolver class used to facilitate\n * recovery when a multi-factor user tries to sign-in with a first factor.\n */\n\ngoog.provide('fireauth.MultiFactorResolver');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.MultiFactorInfo');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('goog.array');\ngoog.require('goog.object');\n\n\n/**\n * Initializes a `MultiFactorResolver` instance. This is used when a\n * multi-factor user signs in with the first factor but is required to provide\n * a second factor assertion before completing sign-in.\n *\n * @param {!fireauth.Auth} auth The Auth instance.\n * @param {!fireauth.MultiFactorResolver.ErrorResponse} errorResponse The server\n * error response containing the pending multi-factor credential.\n * @param {function({idToken: string, refreshToken: string}):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} onIdTokenResolver\n * A function that takes the assertion token response and any previous\n * information returned with the error and completes sign in with a\n * `UserCredential`.\n * @constructor\n */\nfireauth.MultiFactorResolver = function(\n auth, errorResponse, onIdTokenResolver) {\n var pendingCredential = errorResponse && errorResponse[\n fireauth.MultiFactorResolver.SignInResponseField.MFA_PENDING_CREDENTIAL];\n if (!pendingCredential) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n 'Internal assert: Invalid MultiFactorResolver');\n }\n /** @const @private {!fireauth.Auth} The Auth instance. */\n this.auth_ = auth;\n /**\n * @const @private {!fireauth.MultiFactorResolver.ErrorResponse} The server\n * error response with the pending credential.\n */\n this.errorResponse_ = goog.object.clone(errorResponse);\n /**\n * @const @private {function({idToken: string, refreshToken: string}):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} The ID\n * token resolver.\n */\n this.onIdTokenResolver_ = onIdTokenResolver;\n /**\n * @const @private {!fireauth.MultiFactorSession} The corresponding\n * multi-factor session.\n */\n this.session_ = new fireauth.MultiFactorSession(\n null,\n pendingCredential);\n /**\n * @const @private {!Array<!fireauth.MultiFactorInfo>} The list of\n * multi-factor hints corresponding to the current user session.\n */\n this.hints_ = [];\n var enrollmentList = errorResponse[\n fireauth.MultiFactorResolver.SignInResponseField.MFA_INFO] || [];\n var self = this;\n goog.array.forEach(enrollmentList, function(mfaEnrollment) {\n var info = fireauth.MultiFactorInfo.fromServerResponse(mfaEnrollment);\n if (info) {\n self.hints_.push(info);\n }\n });\n fireauth.object.setReadonlyProperty(this, 'auth', this.auth_);\n fireauth.object.setReadonlyProperty(this, 'session', this.session_);\n fireauth.object.setReadonlyProperty(\n this, 'hints', this.hints_);\n};\n\n\n/**\n * The server side error response on multi-factor sign-in.\n * @typedef {{\n * mfaInfo: (?Array<!Object>|undefined),\n * mfaPendingCredential: (?string|undefined)\n * }}\n */\nfireauth.MultiFactorResolver.ErrorResponse;\n\n/**\n * Sign in response fields for multi-factor sign-in.\n * @enum {string}\n */\nfireauth.MultiFactorResolver.SignInResponseField = {\n MFA_INFO: 'mfaInfo',\n MFA_PENDING_CREDENTIAL: 'mfaPendingCredential'\n};\n\n\n/**\n * Completes the second factor sign-in with the multi-factor assertion provided\n * and returns a promise that resolves with the `UserCredential` object.\n *\n * @param {!fireauth.MultiFactorAssertion} assertion The multi-factor assertion\n * to resolve sign-in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>} A promise that\n * resolves with the `UserCredential` after ID token processing.\n */\nfireauth.MultiFactorResolver.prototype.resolveSignIn = function(assertion) {\n var self = this;\n return assertion.process(this.auth_.getRpcHandler(), this.session_)\n .then(function(result) {\n var newSignInResponse = goog.object.clone(self.errorResponse_);\n // These fields are no longer needed.\n delete newSignInResponse[\n fireauth.MultiFactorResolver.SignInResponseField.MFA_INFO];\n delete newSignInResponse[fireauth.MultiFactorResolver\n .SignInResponseField.MFA_PENDING_CREDENTIAL];\n goog.object.extend(newSignInResponse, result);\n // Return ID token/refresh token result and the original error response.\n // This is needed as the original server response may contain additional\n // data such as OAuth credentials, raw user info, etc that needs to be\n // returned to the developer on successful sign-in.\n return self.onIdTokenResolver_(\n /** @type {{idToken: string, refreshToken: string}} */ (\n newSignInResponse));\n });\n};\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the MultiFactorError class, a subclass of\n * fireauth.AuthError.\n */\n\n\ngoog.provide('fireauth.MultiFactorError');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.MultiFactorResolver');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\ngoog.require('goog.object');\n\n\n/**\n * Multi-factor error with resolver, used to resolve sign-in after a two-factor\n * user signs in with a first factor and is required to prove ownership of the\n * second factor.\n * @param {!fireauth.Auth} auth The Auth instance.\n * @param {!fireauth.MultiFactorResolver.ErrorResponse} errorResponse The server\n * error response containing the pending multi-factor credential.\n * @param {function({idToken: string, refreshToken: string}):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} onIdTokenResolver\n * A function that takes the assertion token response and any previous\n * information returned with the error and completes sign in with a\n * `UserCredential`.\n * @param {string=} message The optional custom human-readable message. If not\n * provided, a default message will be used.\n * @constructor\n * @extends {fireauth.AuthError}\n */\nfireauth.MultiFactorError = function(\n auth, errorResponse, onIdTokenResolver, message) {\n fireauth.MultiFactorError.base(\n this,\n 'constructor',\n fireauth.authenum.Error.MFA_REQUIRED,\n message,\n errorResponse);\n this.serverResponse_ = goog.object.clone(errorResponse);\n /**\n * @const @private {!fireauth.MultiFactorResolver} The multi-factor resolver\n * instance.\n */\n this.resolver_ =\n new fireauth.MultiFactorResolver(auth, errorResponse, onIdTokenResolver);\n fireauth.object.setReadonlyProperty(this, 'resolver', this.resolver_);\n};\ngoog.inherits(fireauth.MultiFactorError, fireauth.AuthError);\n\n\n/**\n * Initializes a `MultiFactorError` from the plain object provided. If the\n * object is not a valid `MultiFactorError`, null is returned.\n * @param {?Object|undefined} response The object response to convert to a\n * fireauth.MultiFactorError.\n * @param {!fireauth.Auth} auth The Auth instance.\n * @param {function({idToken: string, refreshToken: string}):\n * !goog.Promise<!fireauth.AuthEventManager.Result>} onIdTokenResolver\n * A function that takes the assertion token response and any previous\n * information returned with the error and completes sign in with a\n * `UserCredential`.\n * @return {?fireauth.MultiFactorError} The `MultiFactorError` error\n * representation of the response. null is returned if the response is not\n * a valid MultiFactorError plain object representation.\n */\nfireauth.MultiFactorError.fromPlainObject =\n function(response, auth, onIdTokenResolver) {\n if (response &&\n goog.isObject(response['serverResponse']) &&\n response['code'] === 'auth/' + fireauth.authenum.Error.MFA_REQUIRED) {\n try {\n return new fireauth.MultiFactorError(\n auth,\n /** @type {!fireauth.MultiFactorResolver.ErrorResponse} */ (\n response['serverResponse']),\n onIdTokenResolver,\n response['message']);\n } catch (e) {\n return null;\n }\n }\n return null;\n};\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the `firebase.auth.MultiFactorAssertion` abstract class\n * and all its subclasses, such as PhoneMultiFactorAssertion.\n */\n\ngoog.provide('fireauth.AuthCredentialMultiFactorAssertion');\ngoog.provide('fireauth.MultiFactorAssertion');\ngoog.provide('fireauth.PhoneMultiFactorAssertion');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.MultiFactorAuthCredential');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.object');\n\n\n/**\n * Abstract class representing a `firebase.auth.MultiFactorAssertion` interface.\n * This is used to facilitate enrollment of a second factor on an existing user\n * or sign-in of a user who already verified the first factor.\n * @abstract\n * @constructor\n */\nfireauth.MultiFactorAssertion = function() {};\n\n\n/**\n * Finalizes the 2nd factor enrollment flow with the current\n * MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorEnrollmentRequestIdentifier} enrollmentRequest\n * The enrollment request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the updated ID and refresh tokens.\n * @protected\n */\nfireauth.MultiFactorAssertion.prototype.finalizeEnrollmentWithVerificationInfo =\n goog.abstractMethod;\n\n\n/**\n * Finalizes the 2nd factor sign-in flow with the current MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSignInRequestIdentifier} signInRequest\n * The sign-in request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the signed in user's ID and refresh tokens.\n * @protected\n */\nfireauth.MultiFactorAssertion.prototype.finalizeSignInWithVerificationInfo =\n goog.abstractMethod;\n\n\n/**\n * Processes the `MultiFactorAssertion` instance using the `MultiFactorSession`\n * provided and optional display name for enrollment flows.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSession} session The multi-factor session\n * instance.\n * @param {?string=} displayName The optional display name for a multi-factor\n * enrollment.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the signed in or enrolled user's ID and refresh\n * tokens.\n */\nfireauth.MultiFactorAssertion.prototype.process =\n function(rpcHandler, session, displayName) {\n // Session obtained from user in enroll.\n // It is obtained from error in resolver.\n if (session.type == fireauth.MultiFactorSession.Type.ENROLL) {\n return this.finalizeMfaEnrollment_(rpcHandler, session, displayName);\n } else {\n return this.finalizeMfaSignIn_(rpcHandler, session);\n }\n};\n\n\n/**\n * Finalizes the multi-factor enrollment.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSession} session The multi-factor session for\n * the current signed in user.\n * @param {?string=} displayName The optional display name for a multi-factor\n * enrollment.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the enrolled user's ID and refresh tokens.\n * @private\n */\nfireauth.MultiFactorAssertion.prototype.finalizeMfaEnrollment_ =\n function(rpcHandler, session, displayName) {\n var self = this;\n return session.getRawSession().then(function(rawSession) {\n var request = {\n 'idToken': rawSession\n };\n if (typeof displayName !== 'undefined') {\n request['displayName'] = displayName;\n }\n return self.finalizeEnrollmentWithVerificationInfo(rpcHandler, request);\n });\n};\n\n\n/**\n * Finalizes the multi-factor sign-in.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSession} session The multi-factor session for\n * the multi-factor enrolled user trying to sign-in.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the signed in user's ID and refresh tokens.\n * @private\n */\nfireauth.MultiFactorAssertion.prototype.finalizeMfaSignIn_ =\n function(rpcHandler, session) {\n var self = this;\n return session.getRawSession().then(function(rawSession) {\n var request = {\n 'mfaPendingCredential': rawSession,\n };\n return self.finalizeSignInWithVerificationInfo(rpcHandler, request);\n });\n};\n\n\n/**\n * Defines a class for handling MultiFactorAssertions based on\n * `MultiFactorAuthCredentials`.\n * @param {!fireauth.MultiFactorAuthCredential} multiFactorAuthCredential The\n * multi-factor AuthCredential.\n * @constructor\n * @extends {fireauth.MultiFactorAssertion}\n */\nfireauth.AuthCredentialMultiFactorAssertion =\n function(multiFactorAuthCredential) {\n // This assumes the factor ID matches the credential providerId.\n // If this is ever not true, the subclass can overwrite that.\n fireauth.object.setReadonlyProperty(\n this, 'factorId', multiFactorAuthCredential.providerId);\n /**\n * @protected {!fireauth.MultiFactorAuthCredential} The underlying\n * multi-factor AuthCredential.\n */\n this.multiFactorAuthCredential = multiFactorAuthCredential;\n};\ngoog.inherits(\n fireauth.AuthCredentialMultiFactorAssertion, fireauth.MultiFactorAssertion);\n\n\n/**\n * Finalizes the 2nd factor enrollment flow with the current\n * MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorEnrollmentRequestIdentifier} enrollmentRequest\n * The enrollment request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the updated ID and refresh tokens.\n * @protected\n * @override\n */\nfireauth.AuthCredentialMultiFactorAssertion.prototype\n .finalizeEnrollmentWithVerificationInfo = function(rpcHandler,\n enrollmentRequest) {\n return this.multiFactorAuthCredential.finalizeMfaEnrollment(\n rpcHandler, enrollmentRequest);\n};\n\n\n/**\n * Finalizes the 2nd factor sign-in flow with the current MultiFactorAssertion.\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler instance.\n * @param {!fireauth.MultiFactorSignInRequestIdentifier} signInRequest\n * The sign-in request identifying the user.\n * @return {!goog.Promise<{idToken: string, refreshToken: string}>} A promise\n * that resolves with the signed in user's ID and refresh tokens.\n * @protected\n * @override\n */\nfireauth.AuthCredentialMultiFactorAssertion.prototype\n .finalizeSignInWithVerificationInfo = function(rpcHandler,\n signInRequest) {\n return this.multiFactorAuthCredential.finalizeMfaSignIn(\n rpcHandler, signInRequest);\n};\n\n\n/**\n * Defines a class for handling MultiFactorAssertions based on\n * PhoneAuthCredentials. This class extends `AuthCredentialMultiFactorAssertion`\n * but for `PhoneAuthCredentials` only.\n * @param {!fireauth.PhoneAuthCredential} phoneAuthCredential\n * @constructor\n * @extends {fireauth.AuthCredentialMultiFactorAssertion}\n */\nfireauth.PhoneMultiFactorAssertion = function(phoneAuthCredential) {\n fireauth.PhoneMultiFactorAssertion.base(\n this, 'constructor', phoneAuthCredential);\n // This class supports phone credentials only.\n if (this.multiFactorAuthCredential.providerId !=\n fireauth.PhoneAuthProvider['PROVIDER_ID']) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n 'firebase.auth.PhoneMultiFactorAssertion requires a valid ' +\n 'firebase.auth.PhoneAuthCredential');\n }\n};\ngoog.inherits(\n fireauth.PhoneMultiFactorAssertion,\n fireauth.AuthCredentialMultiFactorAssertion);\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines fireauth.UserEvent and fireauth.UserEventType.\n */\n\ngoog.provide('fireauth.UserEvent');\ngoog.provide('fireauth.UserEventType');\n\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\n\n\n/**\n * User custom event.\n * @param {string} type The event type.\n * @param {?Object=} properties The optional properties to set to the custom\n * event using same keys as object provided.\n * @constructor\n * @extends {goog.events.Event}\n */\nfireauth.UserEvent = function(type, properties) {\n goog.events.Event.call(this, type);\n // If optional properties provided.\n // Add each property to custom event.\n for (var key in properties) {\n this[key] = properties[key];\n }\n};\ngoog.inherits(fireauth.UserEvent, goog.events.Event);\n\n\n/**\n * Events dispatched by the user.\n * @enum {string}\n */\nfireauth.UserEventType = {\n /** Dispatched when token is changed due to Auth event. */\n TOKEN_CHANGED: 'tokenChanged',\n\n /** Dispatched when user is deleted. */\n USER_DELETED: 'userDeleted',\n\n /**\n * Dispatched when user session is invalidated. This could happen when the\n * following errors occur: user-disabled or user-token-expired.\n */\n USER_INVALIDATED: 'userInvalidated',\n\n /** Dispatched when the user is reloaded. */\n USER_RELOADED: 'userReloaded'\n};\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the `MultiFactorUser` class used to retrieve the\n * enrolled second factors on a user and to facilitate enrollment and\n * unenrollment of second factors.\n */\n\ngoog.provide('fireauth.MultiFactorUser');\n\ngoog.require('fireauth.MultiFactorAssertion');\ngoog.require('fireauth.MultiFactorInfo');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.UserEventType');\ngoog.require('fireauth.object');\ngoog.require('goog.array');\ngoog.require('goog.events');\n\n\n/**\n * Initializes the multi-factor instance corresponding to a signed in user.\n * This provides the ability to retrieve the enrolled second factors for that\n * user, as well as the ability to enroll new second factors or unenroll\n * existing ones.\n * @param {!fireauth.AuthUser} user The user the multi-factor instance\n * represents.\n * @param {?fireauth.AuthUser.AccountInfo=} accountInfo The optional user\n * account info.\n * @constructor\n */\nfireauth.MultiFactorUser = function(user, accountInfo) {\n /**\n * @private {!fireauth.AuthUser} The user this multi-factor instance\n * represents.\n */\n this.user_ = user;\n /** @private {!Array<!fireauth.MultiFactorInfo>} The enrolled factors. */\n this.enrolledFactors_ = [];\n /**\n * @const @private {function({userServerResponse: !Object})} The handler for\n * user reload events.\n */\n this.userReloadedListener_ = goog.bind(this.handleUserReload_, this);\n goog.events.listen(\n this.user_,\n fireauth.UserEventType.USER_RELOADED,\n this.userReloadedListener_);\n var enrolledFactors = [];\n // AccountInfo is typically loaded from storage where it is stored in plain\n // object format. Otherwise, the enrolled factors will be loaded from\n // getAccountInfo response triggered by user reload event.\n if (accountInfo &&\n accountInfo['multiFactor'] &&\n accountInfo['multiFactor']['enrolledFactors']) {\n var enrolledFactorsPlainObject =\n accountInfo['multiFactor']['enrolledFactors'];\n goog.array.forEach(enrolledFactorsPlainObject, function(mfaEnrollment) {\n var info = fireauth.MultiFactorInfo.fromPlainObject(mfaEnrollment);\n if (info) {\n enrolledFactors.push(info);\n }\n });\n }\n this.updateEnrolledFactors_(enrolledFactors);\n};\n\n\n/**\n * @const @private {string} The key for the list of second factor enrollments in\n * the GetAccountInfo server response.\n */\nfireauth.MultiFactorUser.GET_ACCOUNT_INFO_MFA_INFO_ = 'mfaInfo';\n\n\n/** @return {!fireauth.AuthUser} The corresponding user. */\nfireauth.MultiFactorUser.prototype.getUser = function() {\n return this.user_;\n};\n\n\n/**\n * Extracts the enrolled factors from getAccountInfo response and returns an\n * array of corresponding multi-factor info data.\n * @param {!Object} resp The GetAccountInfo response object.\n * @return {!Array<!fireauth.MultiFactorInfo>} The enrolled factors.\n * @private\n */\nfireauth.MultiFactorUser.extractEnrolledFactors_ = function(resp) {\n // Parse MFA enrollments.\n var mfaInfo = resp[fireauth.MultiFactorUser.GET_ACCOUNT_INFO_MFA_INFO_] || [];\n var enrolledFactors = [];\n goog.array.forEach(mfaInfo, function(mfaEnrollment) {\n var info = fireauth.MultiFactorInfo.fromServerResponse(mfaEnrollment);\n if (info) {\n enrolledFactors.push(info);\n }\n });\n return enrolledFactors;\n};\n\n\n/**\n * Handles user reload event. This will parse the enrollments from the\n * response and update them on the current multi-factor instance.\n * @param {{userServerResponse: !Object}} event The user reload event.\n * @private\n */\nfireauth.MultiFactorUser.prototype.handleUserReload_ = function(event) {\n this.updateEnrolledFactors_(fireauth.MultiFactorUser.extractEnrolledFactors_(\n event.userServerResponse));\n};\n\n\n/**\n * Updates the enrolledFactors property.\n * @param {!Array<!fireauth.MultiFactorInfo>} enrolledFactors The new list of\n * `MultiFactorInfo` objects on the user.\n * @private\n */\nfireauth.MultiFactorUser.prototype.updateEnrolledFactors_ =\n function(enrolledFactors) {\n this.enrolledFactors_ = enrolledFactors;\n fireauth.object.setReadonlyProperty(\n this, 'enrolledFactors', enrolledFactors);\n};\n\n\n/**\n * Copies the list of enrolled factors on the user. This facilitates copying a\n * user to another user. The underlying user reference is not updated.\n * @param {!fireauth.MultiFactorUser} multiFactorUser The instance to copy.\n */\nfireauth.MultiFactorUser.prototype.copy = function(multiFactorUser) {\n this.updateEnrolledFactors_(multiFactorUser.enrolledFactors_);\n};\n\n\n/**\n * Provides a multi-factor session used to start a multi-factor enrollment flow.\n * @return {!goog.Promise<!fireauth.MultiFactorSession>} A promise that resolves\n * with a multi-factor session.\n */\nfireauth.MultiFactorUser.prototype.getSession = function() {\n return this.user_.getIdToken()\n .then(function(idToken) {\n return new fireauth.MultiFactorSession(idToken, null);\n });\n};\n\n\n/**\n * Enrolls a second factor as identified by the multi-factor assertion for\n * the current user.\n * @param {!fireauth.MultiFactorAssertion} assertion The multi-factor assertion.\n * @param {?string=} displayName The optional display name used to identify\n * the 2nd factor to the end user.\n * @return {!goog.Promise<void>} A promise that resolves when the second factor\n * is enrolled.\n */\nfireauth.MultiFactorUser.prototype.enroll = function(assertion, displayName) {\n var self = this;\n var rpcHandler = this.user_.getRpcHandler();\n return this.getSession().then(function(session) {\n return assertion.process(rpcHandler, session, displayName);\n }).then(function(tokenResponse) {\n // New tokens will be issued after enrollment of the new second factors.\n // They need to be updated on the user.\n self.user_.updateTokensIfPresent(tokenResponse);\n // The user needs to be reloaded to get the new multi-factor information\n // from server. USER_RELOADED event will be triggered and `enrolledFactors`\n // will be updated.\n return self.user_.reload();\n });\n};\n\n\n/**\n * Removes a second factor from the current user. The factor to be removed can\n * either be identified with the corresponding MultiFactorInfo object or with\n * the second factor's uid string.\n *\n * As part of the unenrollment process, the backend may decide to log the user\n * out. If so, this will still succeed and invalidate the user's state.\n * @param {!fireauth.MultiFactorInfo|string} target The second factor to remove.\n * @return {!goog.Promise<void>}\n */\nfireauth.MultiFactorUser.prototype.unenroll = function(target) {\n var self = this;\n var uid = typeof target === 'string' ? target : target['uid'];\n var rpcHandler = this.user_.getRpcHandler();\n return this.user_.getIdToken().then(function(idToken) {\n return rpcHandler.withdrawMfa(idToken, uid);\n }).then(function(tokenResponse) {\n // Remove the second factor from the user's list.\n var enrolledFactors = goog.array.filter(self.enrolledFactors_,\n function(info) {\n return info['uid'] != uid;\n });\n self.updateEnrolledFactors_(enrolledFactors);\n // Depending on whether the backend decided to revoke the user's session,\n // the tokenResponse may be empty. If the tokens were not updated (and they\n // are now invalid), reloading the user will discover this and invalidate\n // the user's state accordingly.\n self.user_.updateTokensIfPresent(tokenResponse);\n return self.user_.reload().thenCatch(function(error) {\n if (error['code'] != 'auth/user-token-expired') {\n throw error;\n }\n });\n });\n};\n\n\n/**\n * @return {!Object} The plain object representation of the `MultiFactorUser`.\n */\nfireauth.MultiFactorUser.prototype.toPlainObject = function() {\n return {\n 'multiFactor': {\n 'enrolledFactors': goog.array.map(this.enrolledFactors_, function(info) {\n return info.toPlainObject();\n })\n }\n };\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the user info pertaining to an identity provider and\n * the Firebase user object.\n */\n\ngoog.provide('fireauth.AuthUser');\ngoog.provide('fireauth.AuthUser.AccountInfo');\ngoog.provide('fireauth.AuthUserInfo');\ngoog.provide('fireauth.TokenRefreshTime');\ngoog.provide('fireauth.UserMetadata');\n\ngoog.require('fireauth.ActionCodeSettings');\ngoog.require('fireauth.AdditionalUserInfo');\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthEvent');\ngoog.require('fireauth.AuthEventHandler');\ngoog.require('fireauth.AuthEventManager');\ngoog.require('fireauth.AuthProvider');\ngoog.require('fireauth.ConfirmationResult');\ngoog.require('fireauth.IdTokenResult');\ngoog.require('fireauth.MultiFactorError');\ngoog.require('fireauth.MultiFactorUser');\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.ProactiveRefresh');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.StsTokenManager');\ngoog.require('fireauth.UserEvent');\ngoog.require('fireauth.UserEventType');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.constants.AuthEventType');\ngoog.require('fireauth.deprecation');\ngoog.require('fireauth.idp');\ngoog.require('fireauth.iframeclient.IfcHandler');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.events');\ngoog.require('goog.events.Event');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.object');\n\n\n\n/**\n * Initializes an instance of a user metadata object.\n * @param {?string=} opt_createdAt The optional creation date UTC timestamp.\n * @param {?string=} opt_lastLoginAt The optional last login date UTC timestamp.\n * @constructor\n */\nfireauth.UserMetadata = function(opt_createdAt, opt_lastLoginAt) {\n /** @private {?string} The created at UTC timestamp. */\n this.createdAt_ = opt_createdAt || null;\n /** @private {?string} The last login at UTC timestamp. */\n this.lastLoginAt_ = opt_lastLoginAt || null;\n fireauth.object.setReadonlyProperties(this, {\n 'lastSignInTime': fireauth.util.utcTimestampToDateString(\n opt_lastLoginAt || null),\n 'creationTime': fireauth.util.utcTimestampToDateString(\n opt_createdAt || null),\n });\n};\n\n\n/**\n * @return {!fireauth.UserMetadata} A clone of the current user metadata object.\n */\nfireauth.UserMetadata.prototype.clone = function() {\n return new fireauth.UserMetadata(this.createdAt_, this.lastLoginAt_);\n};\n\n\n/**\n * @return {!Object} The object representation of the user metadata instance.\n */\nfireauth.UserMetadata.prototype.toPlainObject = function() {\n return {\n 'lastLoginAt': this.lastLoginAt_,\n 'createdAt': this.createdAt_\n };\n};\n\n\n/**\n * Initializes an instance of the user info for an identity provider.\n * @param {string} uid The user ID.\n * @param {!fireauth.idp.ProviderId} providerId The provider ID.\n * @param {?string=} opt_email The optional user email.\n * @param {?string=} opt_displayName The optional display name.\n * @param {?string=} opt_photoURL The optional photo URL.\n * @param {?string=} opt_phoneNumber The optional phone number.\n * @constructor\n */\nfireauth.AuthUserInfo = function(\n uid,\n providerId,\n opt_email,\n opt_displayName,\n opt_photoURL,\n opt_phoneNumber) {\n fireauth.object.setReadonlyProperties(this, {\n 'uid': uid,\n 'displayName': opt_displayName || null,\n 'photoURL': opt_photoURL || null,\n 'email': opt_email || null,\n 'phoneNumber': opt_phoneNumber || null,\n 'providerId': providerId\n });\n};\n\n\n/**\n * Defines the proactive token refresh time constraints in milliseconds.\n * @enum {number}\n */\nfireauth.TokenRefreshTime = {\n /**\n * The offset time before token natural expiration to run the refresh.\n * This is currently 5 minutes.\n */\n OFFSET_DURATION: 5 * 60 * 1000,\n /**\n * This is the first retrial wait after an error. This is currently\n * 30 seconds.\n */\n RETRIAL_MIN_WAIT: 30 * 1000,\n /**\n * This is the maximum retrial wait, currently 16 minutes.\n */\n RETRIAL_MAX_WAIT: 16 * 60 * 1000\n};\n\n\n\n/**\n * The Firebase user.\n * @param {!Object} appOptions The application options.\n * @param {!Object} stsTokenResponse The server STS token response.\n * @param {?Object=} opt_accountInfo The optional user account info.\n * @constructor\n * @extends {goog.events.EventTarget}\n * @implements {fireauth.AuthEventHandler}\n */\nfireauth.AuthUser =\n function(appOptions, stsTokenResponse, opt_accountInfo) {\n /** @private {!Array<!goog.Promise<*, *>|!goog.Promise<void>>} List of pending\n * promises. */\n this.pendingPromises_ = [];\n // User is only created via Auth so API key should always be available.\n /** @private {string} The API key. */\n this.apiKey_ = /** @type {string} */ (appOptions['apiKey']);\n // This is needed to associate a user to the corresponding Auth instance.\n /** @private {string} The App name. */\n this.appName_ = /** @type {string} */ (appOptions['appName']);\n /** @private {?string} The Auth domain. */\n this.authDomain_ = appOptions['authDomain'] || null;\n var clientFullVersion = firebase.SDK_VERSION ?\n fireauth.util.getClientVersion(\n fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION) :\n null;\n /** @private {!fireauth.RpcHandler} The RPC handler instance. */\n this.rpcHandler_ = new fireauth.RpcHandler(\n this.apiKey_,\n // Get the client Auth endpoint used.\n fireauth.constants.getEndpointConfig(fireauth.constants.clientEndpoint),\n clientFullVersion);\n // TODO: Consider having AuthUser take a fireauth.StsTokenManager\n // instance instead of a token response but make sure lastAccessToken_ also\n // initialized at the right time. In this case initializeFromIdTokenResponse\n // will take in a token response object and convert it to an instance of\n // fireauth.StsTokenManager to properly initialize user.\n /** @private {!fireauth.StsTokenManager} The STS token manager instance. */\n this.stsTokenManager_ = new fireauth.StsTokenManager(this.rpcHandler_);\n\n this.setLastAccessToken_(\n stsTokenResponse[fireauth.RpcHandler.AuthServerField.ID_TOKEN]);\n // STS token manager will always be populated using server response.\n this.stsTokenManager_.parseServerResponse(stsTokenResponse);\n fireauth.object.setReadonlyProperty(\n this, 'refreshToken', this.stsTokenManager_.getRefreshToken());\n this.setAccountInfo(/** @type {!fireauth.AuthUser.AccountInfo} */ (\n opt_accountInfo || {}));\n // Add call to superclass constructor.\n fireauth.AuthUser.base(this, 'constructor');\n /** @private {boolean} Whether popup and redirect is enabled on the user. */\n this.popupRedirectEnabled_ = false;\n if (this.authDomain_ &&\n fireauth.AuthEventManager.ENABLED &&\n // Make sure popup and redirects are supported in the current environment.\n fireauth.util.isPopupRedirectSupported()) {\n // Get the Auth event manager associated with this user.\n this.authEventManager_ = fireauth.AuthEventManager.getManager(\n this.authDomain_, this.apiKey_, this.appName_);\n }\n /** @private {!Array<!function(!fireauth.AuthUser):!goog.Promise>} The list of\n * state change listeners. This is needed to make sure state changes are\n * resolved before resolving user API promises. For example redirect\n * operations should make sure the associated event ID is saved before\n * redirecting.\n */\n this.stateChangeListeners_ = [];\n /**\n * @private {?fireauth.AuthError} The user invalidation error if it exists.\n */\n this.userInvalidatedError_ = null;\n /**\n * @private {!fireauth.ProactiveRefresh} The reference to the proactive token\n * refresher utility for the current user.\n */\n this.proactiveRefresh_ = this.initializeProactiveRefreshUtility_();\n /**\n * @private {!function(!Object)} The handler for user token changes used to\n * realign the proactive token refresh with external token refresh calls.\n */\n this.userTokenChangeListener_ = goog.bind(this.handleUserTokenChange_, this);\n var self = this;\n /** @private {?string} The current user's language code. */\n this.languageCode_ = null;\n /**\n * @private {function(!goog.events.Event)} The on language code changed event\n * handler.\n */\n this.onLanguageCodeChanged_ = function(event) {\n // Update the user language code.\n self.setLanguageCode(event.languageCode);\n };\n /**\n * @private {?goog.events.EventTarget} The language code change event\n * dispatcher.\n */\n this.languageCodeChangeEventDispatcher_ = null;\n\n /** @private {!Array<string>} The current Firebase frameworks. */\n this.frameworks_ = [];\n /**\n * @private {function(!goog.events.Event)} The on framework list changed event\n * handler.\n */\n this.onFrameworkChanged_ = function(event) {\n // Update the Firebase frameworks.\n self.setFramework(event.frameworks);\n };\n /**\n * @private {?goog.events.EventTarget} The framework change event dispatcher.\n */\n this.frameworkChangeEventDispatcher_ = null;\n /**\n * @const @private {!fireauth.MultiFactorUser} The multifactor user instance.\n */\n this.multiFactorUser_ = new fireauth.MultiFactorUser(\n this, /** @type {?fireauth.AuthUser.AccountInfo|undefined} */ (\n opt_accountInfo));\n fireauth.object.setReadonlyProperty(\n this, 'multiFactor', this.multiFactorUser_);\n};\ngoog.inherits(fireauth.AuthUser, goog.events.EventTarget);\n\n\n/**\n * Updates the user language code.\n * @param {?string} languageCode The current language code to use in user\n * requests.\n */\nfireauth.AuthUser.prototype.setLanguageCode = function(languageCode) {\n // Save current language.\n this.languageCode_ = languageCode;\n // Update the custom locale header.\n this.rpcHandler_.updateCustomLocaleHeader(languageCode);\n};\n\n\n/** @return {?string} The current user's language code. */\nfireauth.AuthUser.prototype.getLanguageCode = function() {\n return this.languageCode_;\n};\n\n\n/**\n * Listens to language code changes triggered by the provided dispatcher.\n * @param {?goog.events.EventTarget} dispatcher The language code changed event\n * dispatcher.\n */\nfireauth.AuthUser.prototype.setLanguageCodeChangeDispatcher =\n function(dispatcher) {\n // Remove any previous listener.\n if (this.languageCodeChangeEventDispatcher_) {\n goog.events.unlisten(\n this.languageCodeChangeEventDispatcher_,\n fireauth.constants.AuthEventType.LANGUAGE_CODE_CHANGED,\n this.onLanguageCodeChanged_);\n }\n // Update current dispatcher.\n this.languageCodeChangeEventDispatcher_ = dispatcher;\n // Using an event listener makes it easy for non-currentUsers to detect\n // language changes on the parent Auth instance. A developer could still call\n // APIs that require localization on signed out user references.\n if (dispatcher) {\n goog.events.listen(\n dispatcher,\n fireauth.constants.AuthEventType.LANGUAGE_CODE_CHANGED,\n this.onLanguageCodeChanged_);\n }\n};\n\n\n/**\n * Updates the Firebase frameworks on the current user.\n * @param {!Array<string>} framework The list of Firebase frameworks.\n */\nfireauth.AuthUser.prototype.setFramework = function(framework) {\n // Save current frameworks.\n this.frameworks_ = framework;\n // Update the client version in RPC handler with the new frameworks.\n this.rpcHandler_.updateClientVersion(firebase.SDK_VERSION ?\n fireauth.util.getClientVersion(\n fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION,\n this.frameworks_) :\n null);\n};\n\n\n/** @return {!Array<string>} The current Firebase frameworks. */\nfireauth.AuthUser.prototype.getFramework = function() {\n return goog.array.clone(this.frameworks_);\n};\n\n\n/**\n * Listens to framework changes triggered by the provided dispatcher.\n * @param {?goog.events.EventTarget} dispatcher The framework changed event\n * dispatcher.\n */\nfireauth.AuthUser.prototype.setFrameworkChangeDispatcher =\n function(dispatcher) {\n // Remove any previous listener.\n if (this.frameworkChangeEventDispatcher_) {\n goog.events.unlisten(\n this.frameworkChangeEventDispatcher_,\n fireauth.constants.AuthEventType.FRAMEWORK_CHANGED,\n this.onFrameworkChanged_);\n }\n // Update current dispatcher.\n this.frameworkChangeEventDispatcher_ = dispatcher;\n // Using an event listener makes it easy for non-currentUsers to detect\n // framework changes on the parent Auth instance.\n if (dispatcher) {\n goog.events.listen(\n dispatcher,\n fireauth.constants.AuthEventType.FRAMEWORK_CHANGED,\n this.onFrameworkChanged_);\n }\n};\n\n\n/**\n * Handles user token changes. Currently used to realign the proactive token\n * refresh internal timing with successful external token refreshes.\n * @param {!Object} event The token change event.\n * @private\n */\nfireauth.AuthUser.prototype.handleUserTokenChange_ = function(event) {\n // If an external service refreshes the token, reset the proactive token\n // refresh utility in case it is still running so the next run time is\n // up to date.\n // This will currently also trigger when the proactive refresh succeeds.\n // This is not ideal but should not have any downsides. It just adds a\n // redundant reset which can be optimized not to run in the future.\n if (this.proactiveRefresh_.isRunning()) {\n this.proactiveRefresh_.stop();\n this.proactiveRefresh_.start();\n }\n};\n\n\n/**\n * @return {!fireauth.Auth} The corresponding Auth instance that created the\n * current user.\n * @private\n */\nfireauth.AuthUser.prototype.getAuth_ = function() {\n try {\n // Get the Auth instance for the current app identified by the App name.\n // This could fail if, for example, the App instance was deleted.\n return firebase['app'](this.appName_)['auth']();\n } catch (e) {\n // Throw appropriate error.\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'No firebase.auth.Auth instance is available for the Firebase App ' +\n '\\'' + this.appName_ + '\\'!');\n }\n};\n\n\n/**\n * @return {string} The user's API key.\n */\nfireauth.AuthUser.prototype.getApiKey = function() {\n return this.apiKey_;\n};\n\n\n/**\n * Returns the RPC handler of the user.\n * @return {!fireauth.RpcHandler} The RPC handler.\n */\nfireauth.AuthUser.prototype.getRpcHandler = function() {\n return this.rpcHandler_;\n};\n\n\n/**\n * Used to initialize the current user's proactive token refresher utility.\n * @return {!fireauth.ProactiveRefresh} The user's proactive token refresh\n * utility.\n * @private\n */\nfireauth.AuthUser.prototype.initializeProactiveRefreshUtility_ = function() {\n var self = this;\n return new fireauth.ProactiveRefresh(\n // Force ID token refresh right before expiration.\n function() {\n // Keep in mind when this fails for any reason other than a network\n // error, it will effectively stop the proactive refresh.\n return self.getIdToken(true);\n },\n // Retry only on network errors.\n function(error) {\n if (error && error.code == 'auth/network-request-failed') {\n return true;\n }\n return false;\n },\n // Return next time to run with offset applied.\n function() {\n // Get time until expiration minus the refresh offset.\n var waitInterval =\n self.stsTokenManager_.getExpirationTime() - goog.now() -\n fireauth.TokenRefreshTime.OFFSET_DURATION;\n // Set to zero if wait interval is negative.\n return waitInterval > 0 ? waitInterval : 0;\n },\n // Retrial minimum wait.\n fireauth.TokenRefreshTime.RETRIAL_MIN_WAIT,\n // Retrial maximum wait.\n fireauth.TokenRefreshTime.RETRIAL_MAX_WAIT,\n // Do not run in background as it is common to have multiple tabs open\n // in a browser and this could increase QPS on server.\n false);\n};\n\n\n/** Starts token proactive refresh. */\nfireauth.AuthUser.prototype.startProactiveRefresh = function() {\n // Only allow if not destroyed and not already started.\n if (!this.destroyed_ && !this.proactiveRefresh_.isRunning()) {\n this.proactiveRefresh_.start();\n // Unlisten any previous token change listener.\n goog.events.unlisten(\n this,\n fireauth.UserEventType.TOKEN_CHANGED,\n this.userTokenChangeListener_);\n // Listen to token changes to reset the token refresher.\n goog.events.listen(\n this,\n fireauth.UserEventType.TOKEN_CHANGED,\n this.userTokenChangeListener_);\n }\n};\n\n\n/** Stops token proactive refresh. */\nfireauth.AuthUser.prototype.stopProactiveRefresh = function() {\n // Remove internal token change listener.\n goog.events.unlisten(\n this,\n fireauth.UserEventType.TOKEN_CHANGED,\n this.userTokenChangeListener_);\n // Stop proactive token refresh.\n this.proactiveRefresh_.stop();\n};\n\n\n/**\n * Sets latest access token for the AuthUser object.\n * @param {string} lastAccessToken\n * @private\n */\nfireauth.AuthUser.prototype.setLastAccessToken_ = function(lastAccessToken) {\n /** @private {?string} Latest access token. */\n this.lastAccessToken_ = lastAccessToken;\n fireauth.object.setReadonlyProperty(this, '_lat', lastAccessToken);\n};\n\n\n/**\n * @param {function(!fireauth.AuthUser):!goog.Promise} listener The listener\n * to state changes to add.\n */\nfireauth.AuthUser.prototype.addStateChangeListener = function(listener) {\n this.stateChangeListeners_.push(listener);\n};\n\n\n/**\n * @param {function(!fireauth.AuthUser):!goog.Promise} listener The listener\n * to state changes to remove.\n */\nfireauth.AuthUser.prototype.removeStateChangeListener = function(listener) {\n goog.array.removeAllIf(this.stateChangeListeners_, function(ele) {\n return ele == listener;\n });\n};\n\n\n/**\n * Executes all state change listener promises and when all fulfilled, resolves\n * with the current user.\n * @return {!goog.Promise} A promise that resolves when all state listeners\n * fulfilled.\n * @private\n */\nfireauth.AuthUser.prototype.notifyStateChangeListeners_ = function() {\n var promises = [];\n var self = this;\n for (var i = 0; i < this.stateChangeListeners_.length; i++) {\n // Run listener with Auth user instance and add to list of promises.\n promises.push(this.stateChangeListeners_[i](this));\n }\n return goog.Promise.allSettled(promises).then(function(results) {\n // State change errors should be recoverable even if errors occur.\n return self;\n });\n};\n\n\n/**\n * Sets the user current pending popup event ID.\n * @param {string} eventId The pending popup event ID.\n */\nfireauth.AuthUser.prototype.setPopupEventId = function(eventId) {\n // Saving a popup event in a separate property other than redirectEventId\n // would prevent a pending redirect event from being overwritten by a newly\n // called popup operation.\n this.popupEventId_ = eventId;\n};\n\n\n/**\n * @return {?string} The pending popup event ID.\n */\nfireauth.AuthUser.prototype.getPopupEventId = function() {\n return this.popupEventId_ || null;\n};\n\n\n/**\n * Sets the user current pending redirect event ID.\n * @param {string} eventId The pending redirect event ID.\n */\nfireauth.AuthUser.prototype.setRedirectEventId = function(eventId) {\n this.redirectEventId_ = eventId;\n};\n\n\n/**\n * @return {?string} The pending redirect event ID.\n */\nfireauth.AuthUser.prototype.getRedirectEventId = function() {\n return this.redirectEventId_ || null;\n};\n\n\n/**\n * Subscribes to Auth event manager to handle popup and redirect events.\n * This is an explicit operation as users could exist in temporary states. For\n * example a user change could be detected in another tab. When syncing to those\n * changes, a temporary user is retrieved from storage and then copied to\n * existing user. The temporary user should not subscribe to Auth event changes.\n */\nfireauth.AuthUser.prototype.enablePopupRedirect = function() {\n // Subscribe to Auth event manager if available.\n if (this.authEventManager_ && !this.popupRedirectEnabled_) {\n this.popupRedirectEnabled_ = true;\n this.authEventManager_.subscribe(this);\n }\n};\n\n\n/**\n * getAccountInfo users field.\n * @const {string}\n */\nfireauth.AuthUser.GET_ACCOUNT_INFO_USERS = 'users';\n\n\n/**\n * getAccountInfo response user fields.\n * @enum {string}\n */\nfireauth.AuthUser.GetAccountInfoField = {\n CREATED_AT: 'createdAt',\n DISPLAY_NAME: 'displayName',\n EMAIL: 'email',\n EMAIL_VERIFIED: 'emailVerified',\n LAST_LOGIN_AT: 'lastLoginAt',\n LOCAL_ID: 'localId',\n PASSWORD_HASH: 'passwordHash',\n PASSWORD_UPDATED_AT: 'passwordUpdatedAt',\n PHONE_NUMBER: 'phoneNumber',\n PHOTO_URL: 'photoUrl',\n PROVIDER_USER_INFO: 'providerUserInfo',\n TENANT_ID: 'tenantId'\n};\n\n\n/**\n * setAccountInfo response user fields.\n * @enum {string}\n */\nfireauth.AuthUser.SetAccountInfoField = {\n DISPLAY_NAME: 'displayName',\n EMAIL: 'email',\n PHOTO_URL: 'photoUrl',\n PROVIDER_ID: 'providerId',\n PROVIDER_USER_INFO: 'providerUserInfo'\n};\n\n\n/**\n * getAccountInfo response provider user info fields.\n * @enum {string}\n */\nfireauth.AuthUser.GetAccountInfoProviderField = {\n DISPLAY_NAME: 'displayName',\n EMAIL: 'email',\n PHOTO_URL: 'photoUrl',\n PHONE_NUMBER: 'phoneNumber',\n PROVIDER_ID: 'providerId',\n RAW_ID: 'rawId'\n};\n\n\n/**\n * verifyAssertion response fields.\n * @enum {string}\n */\nfireauth.AuthUser.VerifyAssertionField = {\n ID_TOKEN: 'idToken',\n PROVIDER_ID: 'providerId'\n};\n\n\n/** @return {!fireauth.StsTokenManager} The STS token manager instance */\nfireauth.AuthUser.prototype.getStsTokenManager = function() {\n return this.stsTokenManager_;\n};\n\n\n/**\n * Sets the user account info.\n * @param {!fireauth.AuthUser.AccountInfo} accountInfo The account information\n * from the default provider.\n */\nfireauth.AuthUser.prototype.setAccountInfo = function(accountInfo) {\n fireauth.object.setReadonlyProperties(this, {\n 'uid': accountInfo['uid'],\n 'displayName': accountInfo['displayName'] || null,\n 'photoURL': accountInfo['photoURL'] || null,\n 'email': accountInfo['email'] || null,\n 'emailVerified': accountInfo['emailVerified'] || false,\n 'phoneNumber': accountInfo['phoneNumber'] || null,\n 'isAnonymous': accountInfo['isAnonymous'] || false,\n 'tenantId': accountInfo['tenantId'] || null,\n 'metadata': new fireauth.UserMetadata(\n accountInfo['createdAt'], accountInfo['lastLoginAt']),\n 'providerData': []\n });\n // Sets the tenant ID on RPC handler. For requests with ID tokens, the source\n // of truth is the tenant ID in the ID token. If the request body has a\n // tenant ID (optional here), the backend will confirm it matches the\n // tenant ID in the ID token, otherwise throw an error. If no tenant ID is\n // passed in the request, it will be determined from the ID token.\n this.rpcHandler_.updateTenantId(this['tenantId']);\n};\n\n\n/**\n * Type specifying the parameters that can be passed to the\n * {@code fireauth.AuthUser} constructor.\n * @typedef {{\n * uid: (?string|undefined),\n * displayName: (?string|undefined),\n * photoURL: (?string|undefined),\n * email: (?string|undefined),\n * emailVerified: ?boolean,\n * phoneNumber: (?string|undefined),\n * isAnonymous: ?boolean,\n * createdAt: (?string|undefined),\n * lastLoginAt: (?string|undefined),\n * tenantId: (?string|undefined),\n * multiFactor: ({\n * enrolledFactors: (?Array<!fireauth.MultiFactorInfo>|undefined)\n * }|undefined)\n * }}\n */\nfireauth.AuthUser.AccountInfo;\n\n\n/**\n * The provider for all fireauth.AuthUser objects is 'firebase'.\n */\nfireauth.object.setReadonlyProperty(fireauth.AuthUser.prototype, 'providerId',\n fireauth.idp.ProviderId.FIREBASE);\n\n\n/**\n * Returns nothing. This can be used to consume the output of a Promise.\n * @private\n */\nfireauth.AuthUser.returnNothing_ = function() {\n // Return nothing. Intentionally left empty.\n};\n\n\n/**\n * Ensures the user is still logged in before moving to the next promise\n * resolution.\n * @return {!goog.Promise<undefined,undefined>}\n * @private\n */\nfireauth.AuthUser.prototype.checkDestroyed_ = function() {\n var self = this;\n return goog.Promise.resolve().then(function() {\n if (self.destroyed_) {\n throw new fireauth.AuthError(fireauth.authenum.Error.MODULE_DESTROYED);\n }\n });\n};\n\n\n/**\n * @return {!Array<!fireauth.idp.ProviderId>} The list of provider IDs.\n */\nfireauth.AuthUser.prototype.getProviderIds = function() {\n return goog.array.map(this['providerData'], function(userInfo) {\n return userInfo['providerId'];\n });\n};\n\n\n/**\n * Adds the provided user info to list of providers' data.\n * @param {?fireauth.AuthUserInfo} providerData Provider data to store for user.\n */\nfireauth.AuthUser.prototype.addProviderData = function(providerData) {\n if (!providerData) {\n return;\n }\n this.removeProviderData(providerData['providerId']);\n this['providerData'].push(providerData);\n};\n\n\n/**\n * @param {!fireauth.idp.ProviderId} providerId The provider ID whose\n * data should be removed.\n */\nfireauth.AuthUser.prototype.removeProviderData = function(providerId) {\n goog.array.removeAllIf(this['providerData'], function(userInfo) {\n return userInfo['providerId'] == providerId;\n });\n};\n\n\n/**\n * @param {string} propName The property name to modify.\n * @param {?string|boolean} value The new value to set.\n */\nfireauth.AuthUser.prototype.updateProperty = function(propName, value) {\n // User ID is required.\n if (propName == 'uid' && !value) {\n return;\n }\n if (this.hasOwnProperty(propName)) {\n fireauth.object.setReadonlyProperty(this, propName, value);\n }\n};\n\n\n/**\n * @param {!fireauth.AuthUser} otherUser The other user to compare to.\n * @return {boolean} True if both User objects have the same user ID.\n */\nfireauth.AuthUser.prototype.hasSameUserIdAs = function(otherUser) {\n var thisId = this['uid'];\n var thatId = otherUser['uid'];\n if (thisId === undefined || thisId === null || thisId === '' ||\n thatId === undefined || thatId === null || thatId === '') {\n return false;\n }\n return thisId == thatId;\n};\n\n\n/**\n * Copies all properties and STS token manager instance from userToCopy to\n * current user without triggering any Auth state change or token change\n * listener.\n * @param {!fireauth.AuthUser} userToCopy The updated user to overwrite current\n * user.\n */\nfireauth.AuthUser.prototype.copy = function(userToCopy) {\n var self = this;\n // Copy to self.\n if (self == userToCopy) {\n return;\n }\n fireauth.object.setReadonlyProperties(this, {\n 'uid': userToCopy['uid'],\n 'displayName': userToCopy['displayName'],\n 'photoURL': userToCopy['photoURL'],\n 'email': userToCopy['email'],\n 'emailVerified': userToCopy['emailVerified'],\n 'phoneNumber': userToCopy['phoneNumber'],\n 'isAnonymous': userToCopy['isAnonymous'],\n 'tenantId': userToCopy['tenantId'],\n 'providerData': []\n });\n // This should always be available but just in case there is a conflict with\n // a user from an older version.\n if (userToCopy['metadata']) {\n fireauth.object.setReadonlyProperty(\n this,\n 'metadata',\n /** @type{!fireauth.UserMetadata} */ (userToCopy['metadata']).clone());\n } else {\n // User to copy has no metadata. Align with that.\n fireauth.object.setReadonlyProperty(\n this, 'metadata', new fireauth.UserMetadata());\n }\n goog.array.forEach(userToCopy['providerData'], function(userInfo) {\n self.addProviderData(userInfo);\n });\n this.stsTokenManager_.copy(userToCopy.getStsTokenManager());\n fireauth.object.setReadonlyProperty(\n this, 'refreshToken', this.stsTokenManager_.getRefreshToken());\n // Copy multi-factor info to current user.\n // This should be backward compatible.\n // If the userToCopy is loaded from an older version, multiFactorUser\n // enrolled factors will be initialized empty and copied empty to current\n // multiFactorUser.\n this.multiFactorUser_.copy(userToCopy.multiFactorUser_);\n};\n\n\n/**\n * Set the Auth user redirect storage manager.\n * @param {?fireauth.storage.RedirectUserManager} redirectStorageManager The\n * utility used to store or delete the user on redirect.\n */\nfireauth.AuthUser.prototype.setRedirectStorageManager =\n function(redirectStorageManager) {\n /**\n * @private {?fireauth.storage.RedirectUserManager} The redirect user storage\n * manager.\n */\n this.redirectStorageManager_ = redirectStorageManager;\n};\n\n\n/**\n * Refreshes the current user, if signed in.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.reload = function() {\n var self = this;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(this.checkDestroyed_().then(function() {\n return self.reloadWithoutSaving_()\n .then(function() {\n return self.notifyStateChangeListeners_();\n })\n .then(fireauth.AuthUser.returnNothing_);\n }));\n};\n\n\n/**\n * Refreshes the current user, if signed in.\n * @return {!goog.Promise<string>} Promise that resolves with the idToken.\n * @private\n */\nfireauth.AuthUser.prototype.reloadWithoutSaving_ = function() {\n var self = this;\n // ID token is required to refresh the user's data.\n // If this is called after invalidation, getToken will throw the cached error.\n return this.getIdToken().then(function(idToken) {\n var isAnonymous = self['isAnonymous'];\n return self.setUserAccountInfoFromToken_(idToken)\n .then(function(user) {\n if (!isAnonymous) {\n // Preserves the not anonymous status of the stored user,\n // even if no more credentials (federated or email/password)\n // linked to the user.\n self.updateProperty('isAnonymous', false);\n }\n return idToken;\n });\n });\n};\n\n\n/**\n * This operation resolves with the Firebase ID token result which contains\n * the entire payload claims.\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<!fireauth.IdTokenResult>} A Promise that resolves with\n * the ID token result.\n */\nfireauth.AuthUser.prototype.getIdTokenResult = function(opt_forceRefresh) {\n return this.getIdToken(opt_forceRefresh).then(function(idToken) {\n return new fireauth.IdTokenResult(idToken);\n });\n};\n\n\n/**\n * This operation resolves with the Firebase ID token.\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<string>} A Promise that resolves with the ID token.\n */\nfireauth.AuthUser.prototype.getIdToken = function(opt_forceRefresh) {\n var self = this;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(this.checkDestroyed_().then(function() {\n return self.stsTokenManager_.getToken(opt_forceRefresh);\n }).then(function(response) {\n if (!response) {\n // If the user exists, the token manager should be initialized.\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n // Only if the access token is refreshed, notify Auth listeners.\n if (response['accessToken'] != self.lastAccessToken_) {\n self.setLastAccessToken_(response['accessToken']);\n // Auth state change, notify listeners.\n self.notifyAuthListeners_();\n }\n self.updateProperty('refreshToken', response['refreshToken']);\n return response['accessToken'];\n }));\n};\n\n\n/**\n * Checks if the error corresponds to a user invalidation action.\n * @param {*} error The error returned by a user operation.\n * @return {boolean} Whether the user is invalidated based on the error\n * provided.\n * @private\n */\nfireauth.AuthUser.isUserInvalidated_ = function(error) {\n return !!(error &&\n (error.code == 'auth/user-disabled' ||\n error.code == 'auth/user-token-expired'));\n};\n\n\n/**\n * Updates the current tokens using a server response, if new tokens are\n * present and are different from the current ones, and notify the Auth\n * listeners.\n * @param {!Object} response The response from the server.\n */\nfireauth.AuthUser.prototype.updateTokensIfPresent = function(response) {\n if (response[fireauth.RpcHandler.AuthServerField.ID_TOKEN] &&\n this.lastAccessToken_ != response[\n fireauth.RpcHandler.AuthServerField.ID_TOKEN]) {\n this.stsTokenManager_.parseServerResponse(response);\n this.notifyAuthListeners_();\n this.setLastAccessToken_(response[\n fireauth.RpcHandler.AuthServerField.ID_TOKEN]);\n // Update refresh token property.\n this.updateProperty(\n 'refreshToken', this.stsTokenManager_.getRefreshToken());\n }\n};\n\n\n/**\n * Called internally on Auth (access token) changes to notify listeners.\n * @private\n */\nfireauth.AuthUser.prototype.notifyAuthListeners_ = function() {\n this.dispatchEvent(\n new fireauth.UserEvent(fireauth.UserEventType.TOKEN_CHANGED));\n};\n\n\n/**\n * Called internally on user deletion to notify listeners.\n * @private\n */\nfireauth.AuthUser.prototype.notifyUserDeletedListeners_ = function() {\n this.dispatchEvent(\n new fireauth.UserEvent(fireauth.UserEventType.USER_DELETED));\n};\n\n\n/**\n * Called internally on user session invalidation to notify listeners.\n * @private\n */\nfireauth.AuthUser.prototype.notifyUserInvalidatedListeners_ = function() {\n this.dispatchEvent(\n new fireauth.UserEvent(fireauth.UserEventType.USER_INVALIDATED));\n};\n\n\n/**\n * Queries the backend using the provided ID token for all linked accounts to\n * build the Firebase user object.\n * @param {string} idToken The ID token string.\n * @return {!goog.Promise<undefined>}\n * @private\n */\nfireauth.AuthUser.prototype.setUserAccountInfoFromToken_ = function(idToken) {\n return this.rpcHandler_.getAccountInfoByIdToken(idToken)\n .then(goog.bind(this.parseAccountInfo_, this));\n};\n\n\n/**\n * Parses the response from the getAccountInfo endpoint.\n * @param {!Object} resp The backend response.\n * @private\n */\nfireauth.AuthUser.prototype.parseAccountInfo_ = function(resp) {\n var users = resp[fireauth.AuthUser.GET_ACCOUNT_INFO_USERS];\n if (!users || !users.length) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n var user = users[0];\n var accountInfo = /** @type {!fireauth.AuthUser.AccountInfo} */ ({\n 'uid': /** @type {string} */ (\n user[fireauth.AuthUser.GetAccountInfoField.LOCAL_ID]),\n 'displayName': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.DISPLAY_NAME]),\n 'photoURL': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.PHOTO_URL]),\n 'email': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.EMAIL]),\n 'emailVerified':\n !!user[fireauth.AuthUser.GetAccountInfoField.EMAIL_VERIFIED],\n 'phoneNumber': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.PHONE_NUMBER]),\n 'lastLoginAt': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.LAST_LOGIN_AT]),\n 'createdAt': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.CREATED_AT]),\n 'tenantId': /** @type {?string|undefined} */ (\n user[fireauth.AuthUser.GetAccountInfoField.TENANT_ID])\n });\n this.setAccountInfo(accountInfo);\n var linkedAccounts = this.extractLinkedAccounts_(user);\n for (var i = 0; i < linkedAccounts.length; i++) {\n this.addProviderData(linkedAccounts[i]);\n }\n // Sets the isAnonymous flag based on email, passwordHash and providerData.\n var isAnonymous = !(this['email'] &&\n user[fireauth.AuthUser.GetAccountInfoField.PASSWORD_HASH]) &&\n !(this['providerData'] && this['providerData'].length);\n this.updateProperty('isAnonymous', isAnonymous);\n // Notify external listeners of the reload.\n this.dispatchEvent(new fireauth.UserEvent(\n fireauth.UserEventType.USER_RELOADED,\n {userServerResponse: user}));\n};\n\n\n/**\n * Extracts the linked accounts from getAccountInfo response and returns an\n * array of corresponding provider data.\n * @param {!Object} resp The response object.\n * @return {!Array<!fireauth.AuthUserInfo>} The linked accounts.\n * @private\n */\nfireauth.AuthUser.prototype.extractLinkedAccounts_ = function(resp) {\n var providerInfo =\n resp[fireauth.AuthUser.GetAccountInfoField.PROVIDER_USER_INFO];\n if (!providerInfo || !providerInfo.length) {\n return [];\n }\n\n return goog.array.map(providerInfo, function(info) {\n return new fireauth.AuthUserInfo(\n info[fireauth.AuthUser.GetAccountInfoProviderField.RAW_ID],\n info[fireauth.AuthUser.GetAccountInfoProviderField.PROVIDER_ID],\n info[fireauth.AuthUser.GetAccountInfoProviderField.EMAIL],\n info[fireauth.AuthUser.GetAccountInfoProviderField.DISPLAY_NAME],\n info[fireauth.AuthUser.GetAccountInfoProviderField.PHOTO_URL],\n info[fireauth.AuthUser.GetAccountInfoProviderField.PHONE_NUMBER]);\n });\n};\n\n\n/**\n * Reauthenticates a user using a fresh credential, to be used before operations\n * such as updatePassword that require tokens from recent login attempts. It\n * also returns any additional user info data or credentials returned form the\n * backend. It has been deprecated in favor of reauthenticateWithCredential.\n * @param {!fireauth.AuthCredential} credential\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.reauthenticateAndRetrieveDataWithCredential =\n function(credential) {\n fireauth.deprecation.log(\n fireauth.deprecation.Deprecations.REAUTH_WITH_CREDENTIAL);\n return this.reauthenticateWithCredential(credential);\n};\n\n\n/**\n * Reauthenticates a user using a fresh credential, to be used before operations\n * such as updatePassword that require tokens from recent login attempts. It\n * also returns any additional user info data or credentials returned form the\n * backend.\n * @param {!fireauth.AuthCredential} credential\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithCredential =\n function(credential) {\n var self = this;\n var userCredential = null;\n // Register this pending promise but bypass user invalidation check.\n return this.registerPendingPromise_(\n // Match ID token from credential with the current user UID.\n credential.matchIdTokenWithUid(this.rpcHandler_, this['uid'])\n .then(function(response) {\n // If the credential is valid and matches the current user ID, then\n // update the tokens accordingly.\n self.updateTokensIfPresent(response);\n // Get user credential.\n userCredential = self.getUserCredential_(\n response, fireauth.constants.OperationType.REAUTHENTICATE);\n // This could potentially validate an invalidated user. This happens in\n // the case a password reset was applied. The refresh token is expired.\n // Reauthentication should revalidate the user.\n // User would remain non current if already signed out, but should be\n // enabled again.\n self.userInvalidatedError_ = null;\n return self.reload();\n }).then(function() {\n // Return user credential after reauthenticated user is reloaded.\n return userCredential;\n }),\n // Skip invalidation check as reauthentication could revalidate a user.\n true);\n};\n\n\n/**\n * Reloads the user and then checks if a provider is already linked. If so,\n * this returns a Promise that rejects. Note that state change listeners are not\n * notified on success, so that operations using this can make changes and then\n * do one final listener notification.\n * @param {string} providerId\n * @return {!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.checkIfAlreadyLinked_ =\n function(providerId) {\n var self = this;\n // Reload first in case the user was updated elsewhere.\n return this.reloadWithoutSaving_()\n .then(function() {\n if (goog.array.contains(self.getProviderIds(), providerId)) {\n return self.notifyStateChangeListeners_()\n .then(function() {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.PROVIDER_ALREADY_LINKED);\n });\n }\n });\n};\n\n\n/**\n * Links a provider to the current user and returns any additional user info\n * data or credentials returned form the backend. It has been deprecated in\n * favor of linkWithCredential.\n * @param {!fireauth.AuthCredential} credential The credential from the Auth\n * provider.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.linkAndRetrieveDataWithCredential =\n function(credential) {\n fireauth.deprecation.log(\n fireauth.deprecation.Deprecations.LINK_WITH_CREDENTIAL);\n return this.linkWithCredential(credential);\n};\n\n\n/**\n * Links a provider to the current user and returns any additional user info\n * data or credentials returned form the backend.\n * @param {!fireauth.AuthCredential} credential The credential from the Auth\n * provider.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.linkWithCredential = function(credential) {\n var self = this;\n var userCredential = null;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n this.checkIfAlreadyLinked_(credential['providerId'])\n .then(function() {\n return self.getIdToken();\n })\n .then(function(idToken) {\n return credential.linkToIdToken(self.rpcHandler_, idToken);\n })\n .then(function(response) {\n // Get user credential.\n userCredential = self.getUserCredential_(\n response, fireauth.constants.OperationType.LINK);\n // Finalize linking.\n return self.finalizeLinking_(response);\n })\n .then(function(user) {\n // Return user credential after finalizing linking.\n return userCredential;\n })\n );\n};\n\n\n/**\n * Links a phone number using the App verifier instance and returns a\n * promise that resolves with the confirmation result which on confirmation\n * will resolve with the UserCredential object.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n * verifier.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.AuthUser.prototype.linkWithPhoneNumber =\n function(phoneNumber, appVerifier) {\n var self = this;\n return /** @type {!goog.Promise<!fireauth.ConfirmationResult>} */ (\n this.registerPendingPromise_(\n // Check if linked already. If so, throw an error.\n // This is redundant but is needed to prevent the need to send the\n // SMS (worth the cost).\n this.checkIfAlreadyLinked_(fireauth.idp.ProviderId.PHONE)\n .then(function() {\n return fireauth.ConfirmationResult.initialize(\n self.getAuth_(),\n phoneNumber,\n appVerifier,\n // This will check again if the credential is linked.\n goog.bind(self.linkWithCredential, self));\n })));\n};\n\n\n/**\n * Reauthenticates a user with a phone number using the App verifier instance\n * and returns a promise that resolves with the confirmation result which on\n * confirmation will resolve with the UserCredential object.\n * @param {string} phoneNumber The phone number to authenticate with.\n * @param {!firebase.auth.ApplicationVerifier} appVerifier The application\n * verifier.\n * @return {!goog.Promise<!fireauth.ConfirmationResult>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithPhoneNumber =\n function(phoneNumber, appVerifier) {\n var self = this;\n return /** @type {!goog.Promise<!fireauth.ConfirmationResult>} */ (\n this.registerPendingPromise_(\n // Wrap this operation in a Promise since self.getAuth_() may throw an\n // error synchronously.\n goog.Promise.resolve().then(function() {\n return fireauth.ConfirmationResult.initialize(\n // Get corresponding Auth instance.\n self.getAuth_(),\n phoneNumber,\n appVerifier,\n goog.bind(self.reauthenticateWithCredential,\n self));\n }),\n // Skip invalidation check as reauthentication could revalidate a\n // user.\n true));\n};\n\n\n/**\n * Converts an ID token response (eg. verifyAssertion) to a UserCredential\n * object.\n * @param {!Object} idTokenResponse The ID token response.\n * @param {!fireauth.constants.OperationType} operationType The operation type\n * to set in the user credential.\n * @return {!fireauth.AuthEventManager.Result} The UserCredential object\n * constructed from the response.\n * @private\n */\nfireauth.AuthUser.prototype.getUserCredential_ =\n function(idTokenResponse, operationType) {\n // Get credential if available in the response.\n var credential = fireauth.AuthProvider.getCredentialFromResponse(\n idTokenResponse);\n // Get additional user info data if available in the response.\n var additionalUserInfo = fireauth.AdditionalUserInfo.fromPlainObject(\n idTokenResponse);\n // Return the readonly copy of the user credential object.\n return fireauth.object.makeReadonlyCopy({\n // Return the current user reference.\n 'user': this,\n // Return any credential passed from the backend.\n 'credential': credential,\n // Return any additional IdP data passed from the backend.\n 'additionalUserInfo': additionalUserInfo,\n // Return the operation type in the user credential object.\n 'operationType': operationType\n });\n};\n\n\n/**\n * Finalizes a linking flow, updating idToken and user's data using the\n * RPC linking response.\n * @param {!Object} response The RPC linking response.\n * @return {!goog.Promise<!fireauth.AuthUser>}\n * @private\n */\nfireauth.AuthUser.prototype.finalizeLinking_ = function(response) {\n // The response may contain a new access token,\n // so we should update them just like a new sign in.\n this.updateTokensIfPresent(response);\n // This will take care of saving the updated state.\n var self = this;\n return this.reload().then(function() {\n return self;\n });\n};\n\n\n/**\n * Updates the user's email.\n * @param {string} newEmail The new email.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.updateEmail = function(newEmail) {\n var self = this;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(this.getIdToken()\n .then(function(idToken) {\n return self.rpcHandler_.updateEmail(idToken, newEmail);\n })\n .then(function(response) {\n // Calls to SetAccountInfo may invalidate old tokens.\n self.updateTokensIfPresent(response);\n // Reloads the user to update emailVerified.\n return self.reload();\n }));\n};\n\n\n/**\n * Updates the user's phone number.\n * @param {!fireauth.PhoneAuthCredential} phoneCredential\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.updatePhoneNumber = function(phoneCredential) {\n var self = this;\n return this.registerPendingPromise_(this.getIdToken()\n .then(function(idToken) {\n // The backend always overwrites the existing phone number during a\n // link operation.\n return phoneCredential.linkToIdToken(self.rpcHandler_, idToken);\n })\n .then(function(response) {\n self.updateTokensIfPresent(response);\n return self.reload();\n }));\n};\n\n\n/**\n * Updates the user's password.\n * @param {string} newPassword The new password.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.updatePassword = function(newPassword) {\n var self = this;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n this.getIdToken()\n .then(function(idToken) {\n return self.rpcHandler_.updatePassword(idToken, newPassword);\n })\n .then(function(response) {\n self.updateTokensIfPresent(response);\n // Reloads the user in case email has also been updated and the user\n // was anonymous.\n return self.reload();\n }));\n};\n\n\n/**\n * Updates the user's profile data.\n * @param {!Object} profile The profile data to update.\n * @return {!goog.Promise<undefined>}\n */\nfireauth.AuthUser.prototype.updateProfile = function(profile) {\n if (profile['displayName'] === undefined &&\n profile['photoURL'] === undefined) {\n // No change, directly return.\n return this.checkDestroyed_();\n }\n var self = this;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n this.getIdToken().then(function(idToken) {\n // Translate the request into one that the backend accepts.\n var profileRequest = {\n 'displayName': profile['displayName'],\n 'photoUrl': profile['photoURL']\n };\n return self.rpcHandler_.updateProfile(idToken, profileRequest);\n })\n .then(function(response) {\n // Calls to SetAccountInfo may invalidate old tokens.\n self.updateTokensIfPresent(response);\n // Update properties.\n self.updateProperty('displayName',\n response[fireauth.AuthUser.SetAccountInfoField.DISPLAY_NAME] ||\n null);\n self.updateProperty('photoURL',\n response[fireauth.AuthUser.SetAccountInfoField.PHOTO_URL] || null);\n goog.array.forEach(self['providerData'], function(userInfo) {\n // Check if password provider is linked.\n if (userInfo['providerId'] === fireauth.idp.ProviderId.PASSWORD) {\n // If so, update both fields in that provider.\n fireauth.object.setReadonlyProperty(\n userInfo, 'displayName', self['displayName']);\n fireauth.object.setReadonlyProperty(\n userInfo, 'photoURL', self['photoURL']);\n }\n });\n // Notify changes and resolve.\n return self.notifyStateChangeListeners_();\n })\n .then(fireauth.AuthUser.returnNothing_));\n};\n\n\n/**\n * Unlinks a provider from an account.\n * @param {!fireauth.idp.ProviderId} providerId The ID of the provider to\n * unlink.\n * @return {!goog.Promise<!fireauth.AuthUser>}\n */\nfireauth.AuthUser.prototype.unlink = function(providerId) {\n var self = this;\n // Make sure we have updated user providers to avoid removing a linked\n // provider that hasn't been updated in current copy of user.\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n this.reloadWithoutSaving_()\n .then(function(idToken) {\n // Provider already unlinked.\n if (!goog.array.contains(self.getProviderIds(), providerId)) {\n return self.notifyStateChangeListeners_()\n .then(function() {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.NO_SUCH_PROVIDER);\n });\n }\n // We delete the providerId given.\n return self.rpcHandler_\n .deleteLinkedAccounts(idToken, [providerId])\n .then(function(resp) {\n // Construct the set of provider IDs returned by server.\n var remainingProviderIds = {};\n var userInfo = resp[fireauth.AuthUser.SetAccountInfoField.\n PROVIDER_USER_INFO] || [];\n goog.array.forEach(userInfo, function(obj) {\n remainingProviderIds[\n obj[fireauth.AuthUser.SetAccountInfoField.PROVIDER_ID]] =\n true;\n });\n\n // Remove all provider data objects where the provider ID no\n // longer exists in this user.\n goog.array.forEach(self.getProviderIds(), function(pId) {\n if (!remainingProviderIds[pId]) {\n // This provider no longer linked, remove it from user.\n self.removeProviderData(pId);\n }\n });\n\n // Remove the phone number if the phone provider was unlinked.\n if (!remainingProviderIds[fireauth.PhoneAuthProvider[\n 'PROVIDER_ID']]) {\n fireauth.object.setReadonlyProperty(self, 'phoneNumber', null);\n }\n\n return self.notifyStateChangeListeners_();\n });\n }));\n};\n\n\n/**\n * Deletes the user, triggering an Auth token change if successful.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.delete = function() {\n // Notice the way of declaring the method, it's to avoid a weird bug on IE8.\n var self = this;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n this.getIdToken()\n .then(function(idToken) {\n return self.rpcHandler_.deleteAccount(idToken);\n })\n .then(function() {\n self.notifyUserDeletedListeners_();\n }))\n .then(function() {\n // Destroying after the registered promise is handled ensures it won't\n // be canceled.\n self.destroy();\n });\n};\n\n\n/**\n * Tells the Auth event manager if this user is the owner of a detected Auth\n * event. A user can handle linkWithPopup and linkWithRedirect operations.\n * In addition, the event ID should match the user's event IDs.\n * @param {!fireauth.AuthEvent.Type} mode The Auth operation mode (popup,\n * redirect).\n * @param {?string=} opt_eventId The event ID.\n * @return {boolean} Whether the Auth event handler can handler the provided\n * event.\n * @override\n */\nfireauth.AuthUser.prototype.canHandleAuthEvent = function(mode, opt_eventId) {\n if (mode == fireauth.AuthEvent.Type.LINK_VIA_POPUP &&\n this.getPopupEventId() == opt_eventId &&\n this.pendingPopupResolvePromise_) {\n // The link via popup event's ID matches the user's popup event ID which\n // makes this user the owner of this event.\n return true;\n } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_POPUP &&\n this.getPopupEventId() == opt_eventId &&\n this.pendingPopupResolvePromise_) {\n // The reauth via popup event's ID matches the user's popup event ID which\n // makes this user the owner of this event.\n return true;\n } else if (mode == fireauth.AuthEvent.Type.LINK_VIA_REDIRECT &&\n this.getRedirectEventId() == opt_eventId) {\n // The link via redirect event's ID matches the user's redirect event ID\n // which makes this user the owner of this event.\n return true;\n } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT &&\n this.getRedirectEventId() == opt_eventId) {\n // The reauth via redirect event's ID matches the user's redirect event ID\n // which makes this user the owner of this event.\n return true;\n }\n return false;\n};\n\n\n/**\n * Completes the pending popup operation. If error is not null, rejects with the\n * error. Otherwise, it resolves with the popup redirect result.\n * @param {!fireauth.AuthEvent.Type} mode The Auth operation mode (popup,\n * redirect).\n * @param {?fireauth.AuthEventManager.Result} popupRedirectResult The result\n * to resolve with when no error supplied.\n * @param {?fireauth.AuthError} error When supplied, the promise will reject.\n * @param {?string=} opt_eventId The event ID.\n * @override\n */\nfireauth.AuthUser.prototype.resolvePendingPopupEvent =\n function(mode, popupRedirectResult, error, opt_eventId) {\n // Only handles popup events with event IDs that match a pending popup ID.\n if ((mode != fireauth.AuthEvent.Type.LINK_VIA_POPUP &&\n mode != fireauth.AuthEvent.Type.REAUTH_VIA_POPUP) ||\n opt_eventId != this.getPopupEventId()) {\n return;\n }\n if (error && this.pendingPopupRejectPromise_) {\n // Reject with error for supplied mode.\n this.pendingPopupRejectPromise_(error);\n } else if (popupRedirectResult &&\n !error &&\n this.pendingPopupResolvePromise_) {\n // Resolve with result for supplied mode.\n this.pendingPopupResolvePromise_(popupRedirectResult);\n }\n // Now that event is resolved, delete timeout promise.\n if (this.popupTimeoutPromise_) {\n this.popupTimeoutPromise_.cancel();\n this.popupTimeoutPromise_ = null;\n }\n // Delete pending promises.\n delete this.pendingPopupResolvePromise_;\n delete this.pendingPopupRejectPromise_;\n};\n\n\n/**\n * Returns the handler's appropriate popup and redirect sign in operation\n * finisher. Can handle link or reauth events that match existing event IDs.\n * @param {!fireauth.AuthEvent.Type} mode The Auth operation mode (popup,\n * redirect).\n * @param {?string=} opt_eventId The optional event ID.\n * @return {?function(string, string, ?string,\n * ?string=):!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @override\n */\nfireauth.AuthUser.prototype.getAuthEventHandlerFinisher =\n function(mode, opt_eventId) {\n if (mode == fireauth.AuthEvent.Type.LINK_VIA_POPUP &&\n opt_eventId == this.getPopupEventId()) {\n // Link with popup ID matches popup event ID.\n return goog.bind(this.finishPopupAndRedirectLink, this);\n } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_POPUP &&\n opt_eventId == this.getPopupEventId()) {\n // Reauth with popup ID matches popup event ID.\n return goog.bind(this.finishPopupAndRedirectReauth, this);\n } else if (mode == fireauth.AuthEvent.Type.LINK_VIA_REDIRECT &&\n this.getRedirectEventId() == opt_eventId) {\n // Link with redirect ID matches redirect event ID.\n return goog.bind(this.finishPopupAndRedirectLink, this);\n } else if (mode == fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT &&\n this.getRedirectEventId() == opt_eventId) {\n // Reauth with redirect ID matches redirect event ID.\n return goog.bind(this.finishPopupAndRedirectReauth, this);\n }\n return null;\n};\n\n\n/**\n * @return {string} The generated event ID used to identify a popup or redirect\n * event.\n * @private\n */\nfireauth.AuthUser.prototype.generateEventId_ = function() {\n return fireauth.util.generateEventId(this['uid'] + ':::');\n};\n\n\n/**\n * Links to Auth provider via popup.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.linkWithPopup = function(provider) {\n var self = this;\n // Additional check to return to fail when the provider is already linked.\n var additionalCheck = function() {\n return self.checkIfAlreadyLinked_(provider['providerId'])\n .then(function() {\n // Notify state listeners after the check as it will update the user\n // state.\n return self.notifyStateChangeListeners_();\n });\n };\n return this.runOperationWithPopup_(\n fireauth.AuthEvent.Type.LINK_VIA_POPUP, provider, additionalCheck, false);\n};\n\n\n/**\n * Reauthenticate to Auth provider via popup.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithPopup = function(provider) {\n // No additional check needed before running this operation.\n var additionalCheck = function() {\n return goog.Promise.resolve();\n };\n return this.runOperationWithPopup_(\n fireauth.AuthEvent.Type.REAUTH_VIA_POPUP,\n provider,\n additionalCheck,\n // Do not update token and skip session invalidation check.\n true);\n};\n\n\n/**\n * Runs a specific OAuth operation using the Auth provider via popup.\n * @param {!fireauth.AuthEvent.Type} mode The mode of operation (link or\n * reauth).\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function():!goog.Promise} additionalCheck The additional check to\n * run before proceeding with the popup processing.\n * @param {boolean} isReauthOperation whether this is a reauth operation or not.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n * @private\n */\nfireauth.AuthUser.prototype.runOperationWithPopup_ =\n function(mode, provider, additionalCheck, isReauthOperation) {\n // Check if popup and redirect are supported in this environment.\n if (!fireauth.util.isPopupRedirectSupported()) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n }\n // Quickly throw user invalidation error if already invalidated.\n if (this.userInvalidatedError_ &&\n // Skip invalidation check as reauthentication could revalidate a user.\n !isReauthOperation) {\n return goog.Promise.reject(this.userInvalidatedError_);\n }\n var self = this;\n // Popup the window immediately to make sure the browser associates the\n // popup with the click that triggered it.\n\n // Get provider settings.\n var settings = fireauth.idp.getIdpSettings(provider['providerId']);\n // There could multiple users at the same time and multiple users could have\n // the same UID. So try to ensure event ID uniqueness.\n var eventId = this.generateEventId_();\n // If incapable of redirecting popup from opener, popup destination URL\n // directly. This could also happen in a sandboxed iframe.\n var oauthHelperWidgetUrl = null;\n if ((!fireauth.util.runsInBackground() || fireauth.util.isIframe()) &&\n this.authDomain_ &&\n provider['isOAuthProvider']) {\n oauthHelperWidgetUrl =\n fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl(\n this.authDomain_,\n this.apiKey_,\n this.appName_,\n mode,\n provider,\n null,\n eventId,\n firebase.SDK_VERSION || null,\n null,\n null,\n this['tenantId']);\n }\n // The popup must have a name, otherwise when successive popups are triggered\n // they will all render in the same instance and none will succeed since the\n // popup cancel of first window will close the shared popup window instance.\n var popupWin =\n fireauth.util.popup(\n oauthHelperWidgetUrl,\n fireauth.util.generateRandomString(),\n settings && settings.popupWidth,\n settings && settings.popupHeight);\n var p = additionalCheck().then(function() {\n // Auth event manager must be available for account linking or\n // reauthentication to be possible.\n self.getAuthEventManager();\n if (!isReauthOperation) {\n // Some operations like reauthenticate do not require this.\n return self.getIdToken().then(function(idToken) {});\n }\n }).then(function() {\n // Process popup request.\n return self.authEventManager_.processPopup(\n popupWin, mode, provider, eventId, !!oauthHelperWidgetUrl,\n self['tenantId']);\n }).then(function() {\n return new goog.Promise(function(resolve, reject) {\n // Expire other pending promises if still available.\n self.resolvePendingPopupEvent(\n mode,\n null,\n new fireauth.AuthError(fireauth.authenum.Error.EXPIRED_POPUP_REQUEST),\n // Existing popup event ID.\n self.getPopupEventId());\n // Save current pending promises.\n self.pendingPopupResolvePromise_ = resolve;\n self.pendingPopupRejectPromise_ = reject;\n // Overwrite popup event ID with new one.\n self.setPopupEventId(eventId);\n // Keep track of timeout promise to cancel it on promise resolution before\n // it times out.\n self.popupTimeoutPromise_ =\n self.authEventManager_.startPopupTimeout(\n self, mode, /** @type {!Window} */ (popupWin), eventId);\n });\n }).then(function(result) {\n // On resolution, close popup if still opened and pass result through.\n if (popupWin) {\n fireauth.util.closeWindow(popupWin);\n }\n if (result) {\n return fireauth.object.makeReadonlyCopy(result);\n }\n return null;\n }).thenCatch(function(error) {\n if (popupWin) {\n fireauth.util.closeWindow(popupWin);\n }\n throw error;\n });\n // Register this pending promise. This will also check for user invalidation.\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(\n p,\n // Skip invalidation check as reauthentication could revalidate a\n // user.\n isReauthOperation));\n};\n\n\n/**\n * Links to Auth provider via redirect.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.linkWithRedirect = function(provider) {\n var mode = fireauth.AuthEvent.Type.LINK_VIA_REDIRECT;\n var self = this;\n // Additional check to return to fail when the provider is already linked.\n var additionalCheck = function() {\n return self.checkIfAlreadyLinked_(provider['providerId']);\n };\n return this.runOperationWithRedirect_(mode, provider, additionalCheck, false);\n};\n\n\n/**\n * Reauthenticates to Auth provider via redirect.\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.reauthenticateWithRedirect = function(provider) {\n // No additional check needed.\n var additionalCheck = function() {\n return goog.Promise.resolve();\n };\n return this.runOperationWithRedirect_(\n fireauth.AuthEvent.Type.REAUTH_VIA_REDIRECT,\n provider,\n additionalCheck,\n // Do not update token and skip session invalidation check.\n true);\n};\n\n\n\n/**\n * Runs a specific OAuth operation using the Auth provider via redirect.\n * @param {!fireauth.AuthEvent.Type} mode The mode of operation (link or\n * reauth).\n * @param {!fireauth.AuthProvider} provider The Auth provider to sign in with.\n * @param {function():!goog.Promise} additionalCheck The additional check to\n * run before proceeding with the redirect processing.\n * @param {boolean} isReauthOperation whether this is a reauth operation or not.\n * @return {!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.runOperationWithRedirect_ =\n function(mode, provider, additionalCheck, isReauthOperation) {\n // Check if popup and redirect are supported in this environment.\n if (!fireauth.util.isPopupRedirectSupported()) {\n return goog.Promise.reject(new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED));\n }\n // Quickly throw user invalidation error if already invalidated.\n if (this.userInvalidatedError_ &&\n // Skip invalidation check as reauthentication could revalidate a user.\n !isReauthOperation) {\n return goog.Promise.reject(this.userInvalidatedError_);\n }\n var self = this;\n var errorThrown = null;\n // There could multiple users at the same time and multiple users could have\n // the same UID. So try to ensure event ID uniqueness.\n var eventId = this.generateEventId_();\n var p = additionalCheck().then(function() {\n // Auth event manager must be available for account linking or\n // reauthentication to be possible.\n self.getAuthEventManager();\n if (!isReauthOperation) {\n // Some operations like reauthenticate do not require this.\n return self.getIdToken().then(function(idToken) {});\n }\n }).then(function() {\n // Process redirect operation.\n self.setRedirectEventId(eventId);\n // Before redirecting save the event ID.\n // It is important that the user redirect event ID is updated in storage\n // before redirecting.\n return self.notifyStateChangeListeners_();\n }).then(function(user) {\n if (self.redirectStorageManager_) {\n // Save the user before redirecting in case it is not current so that it\n // can be retrieved after reloading for linking or reauthentication to\n // succeed.\n return self.redirectStorageManager_.setRedirectUser(self);\n }\n return user;\n }).then(function(user) {\n // Complete the redirect operation.\n return self.authEventManager_.processRedirect(\n mode, provider, eventId, self['tenantId']);\n }).thenCatch(function(error) {\n // Catch error if any is generated.\n errorThrown = error;\n if (self.redirectStorageManager_) {\n // If an error is detected, delete the redirected user from storage.\n return self.redirectStorageManager_.removeRedirectUser();\n }\n // No storage manager, just throw error.\n throw errorThrown;\n }).then(function() {\n // Rethrow the error.\n if (errorThrown) {\n throw errorThrown;\n }\n });\n // Register this pending promise. This will also check for user invalidation.\n return /** @type {!goog.Promise<void>} */ (this.registerPendingPromise_(\n p,\n // Skip invalidation check as reauthentication could revalidate a user.\n isReauthOperation));\n};\n\n\n/**\n * @return {!fireauth.AuthEventManager} The user's Auth event manager.\n */\nfireauth.AuthUser.prototype.getAuthEventManager = function() {\n // Either return the manager instance if available, otherwise throw an error.\n if (this.authEventManager_ && this.popupRedirectEnabled_) {\n return this.authEventManager_;\n } else if (this.authEventManager_ && !this.popupRedirectEnabled_) {\n // This should not happen as Auth will enable a user after it is created.\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR);\n }\n throw new fireauth.AuthError(fireauth.authenum.Error.MISSING_AUTH_DOMAIN);\n};\n\n\n/**\n * Finishes the popup and redirect account linking operations.\n * @param {string} requestUri The callback URL with the OAuth response.\n * @param {string} sessionId The session ID used to generate the authUri.\n * @param {?string} tenantId The tenant ID.\n * @param {?string=} opt_postBody The optional POST body content.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.finishPopupAndRedirectLink =\n function(requestUri, sessionId, tenantId, opt_postBody) {\n var self = this;\n // Now that popup has responded, delete popup timeout promise.\n if (this.popupTimeoutPromise_) {\n this.popupTimeoutPromise_.cancel();\n this.popupTimeoutPromise_ = null;\n }\n var userCredential = null;\n // This routine could be run before init state, make sure it waits for that to\n // complete otherwise this would fail as user not loaded from storage yet.\n var p = this.getIdToken()\n .then(function(idToken) {\n var request = {\n 'requestUri': requestUri,\n 'postBody': opt_postBody,\n 'sessionId': sessionId,\n // To link a tenant user, the tenant ID will be passed to the\n // backend as part of the ID token.\n 'idToken': idToken\n };\n // This operation should fail if new ID token differs from old one.\n // So this can be treate as a profile update operation.\n return self.rpcHandler_.verifyAssertionForLinking(request);\n })\n .then(function(response) {\n // Get user credential.\n userCredential = self.getUserCredential_(\n response, fireauth.constants.OperationType.LINK);\n // Finalizes the linking process.\n return self.finalizeLinking_(response);\n })\n .then(function(user) {\n // Return the user credential response.\n return userCredential;\n });\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(p));\n};\n\n\n/**\n * Finishes the popup and redirect account reauthentication operations.\n * @param {string} requestUri The callback URL with the OAuth response.\n * @param {string} sessionId The session ID used to generate the authUri.\n * @param {?string} tenantId The tenant ID.\n * @param {?string=} opt_postBody The optional POST body content.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>}\n */\nfireauth.AuthUser.prototype.finishPopupAndRedirectReauth =\n function(requestUri, sessionId, tenantId, opt_postBody) {\n var self = this;\n // Now that popup has responded, delete popup timeout promise.\n if (this.popupTimeoutPromise_) {\n this.popupTimeoutPromise_.cancel();\n this.popupTimeoutPromise_ = null;\n }\n var userCredential = null;\n // This routine could be run before init state, make sure it waits for that to\n // complete otherwise this would fail as user not loaded from storage yet.\n var p = goog.Promise.resolve()\n .then(function() {\n var request = {\n 'requestUri': requestUri,\n 'sessionId': sessionId,\n 'postBody': opt_postBody,\n // To reauthenticate a tenant user, the tenant ID will be passed to\n // the backend explicitly.\n // Even if tenant ID is null, still pass it to RPC handler explicitly\n // so that it won't be overridden by RPC handler's tenant ID.\n 'tenantId': tenantId\n };\n // Finish sign in by calling verifyAssertionForExisting and then\n // matching the returned ID token's UID with the current user's.\n return fireauth.AuthCredential.verifyTokenResponseUid(\n self.rpcHandler_.verifyAssertionForExisting(request),\n self['uid']);\n }).then(function(response) {\n // Get credential from response if available.\n // Get user credential.\n userCredential = self.getUserCredential_(\n response, fireauth.constants.OperationType.REAUTHENTICATE);\n // If the credential is valid and matches the current user ID, then\n // update the tokens accordingly.\n self.updateTokensIfPresent(response);\n // This could potentially validate an invalidated user. This happens in\n // the case a password reset was applied. The refresh token is expired.\n // Reauthentication should revalidate the user.\n // User would remain non current if already signed out, but should be\n // enabled again.\n self.userInvalidatedError_ = null;\n return self.reload();\n })\n .then(function() {\n // Return the user credential response.\n return userCredential;\n });\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(\n p,\n // Skip invalidation check as reauthentication could revalidate a\n // user.\n true));\n};\n\n\n/**\n * Sends the verification email to the email in the user's account.\n * @param {?Object=} opt_actionCodeSettings The optional action code settings\n * object.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.sendEmailVerification =\n function(opt_actionCodeSettings) {\n var self = this;\n var idToken = null;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n // Wrap in promise as ActionCodeSettings constructor could throw a\n // synchronous error if invalid arguments are specified.\n this.getIdToken().then(function(latestIdToken) {\n idToken = latestIdToken;\n if (typeof opt_actionCodeSettings !== 'undefined' &&\n // Ignore empty objects.\n !goog.object.isEmpty(opt_actionCodeSettings)) {\n return new fireauth.ActionCodeSettings(\n /** @type {!Object} */ (opt_actionCodeSettings)).buildRequest();\n }\n return {};\n })\n .then(function(additionalRequestData) {\n return self.rpcHandler_.sendEmailVerification(\n /** @type {string} */ (idToken), additionalRequestData);\n })\n .then(function(email) {\n if (self['email'] != email) {\n // Our local copy does not have an email. If the email changed,\n // reload the user.\n return self.reload();\n }\n })\n .then(function() {\n // Return nothing.\n }));\n};\n\n\n/**\n * Sends the verification email before updating the email on the user.\n * @param {string} newEmail The new email.\n * @param {?Object=} opt_actionCodeSettings The optional action code settings\n * object.\n * @return {!goog.Promise<void>}\n */\nfireauth.AuthUser.prototype.verifyBeforeUpdateEmail =\n function(newEmail, opt_actionCodeSettings) {\n var self = this;\n var idToken = null;\n // Register this pending promise. This will also check for user invalidation.\n return this.registerPendingPromise_(\n // Wrap in promise as ActionCodeSettings constructor could throw a\n // synchronous error if invalid arguments are specified.\n this.getIdToken().then(function(latestIdToken) {\n idToken = latestIdToken;\n if (typeof opt_actionCodeSettings !== 'undefined' &&\n // Ignore empty objects.\n !goog.object.isEmpty(opt_actionCodeSettings)) {\n return new fireauth.ActionCodeSettings(\n /** @type {!Object} */ (opt_actionCodeSettings)).buildRequest();\n }\n return {};\n })\n .then(function(additionalRequestData) {\n return self.rpcHandler_.verifyBeforeUpdateEmail(\n /** @type {string} */ (idToken), newEmail, additionalRequestData);\n })\n .then(function(email) {\n if (self['email'] != email) {\n // If the local copy of the email on user is outdated, reload the\n // user.\n return self.reload();\n }\n })\n .then(function() {\n // Return nothing.\n }));\n};\n\n\n/**\n * Destroys the user object and makes further operations invalid. Sensitive\n * fields (refreshToken) are also cleared.\n */\nfireauth.AuthUser.prototype.destroy = function() {\n // Cancel all pending promises.\n for (var i = 0; i < this.pendingPromises_.length; i++) {\n this.pendingPromises_[i].cancel(fireauth.authenum.Error.MODULE_DESTROYED);\n }\n // Stop listening to language code changes.\n this.setLanguageCodeChangeDispatcher(null);\n // Stop listening to framework changes.\n this.setFrameworkChangeDispatcher(null);\n // Empty pending promises array.\n this.pendingPromises_ = [];\n this.destroyed_ = true;\n // Stop proactive refresh if running.\n this.stopProactiveRefresh();\n fireauth.object.setReadonlyProperty(this, 'refreshToken', null);\n // Make sure the destroyed user is unsubscribed from Auth event handling.\n if (this.authEventManager_) {\n this.authEventManager_.unsubscribe(this);\n }\n};\n\n\n/**\n * Takes in a pending promise, saves it and adds a clean up callback which\n * forgets the pending promise after it is fulfilled and echoes the promise\n * back. If in the process, a user invalidation error is detected, caches the\n * error so next time a call is made on the user, the operation will fail with\n * the cached error.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @param {boolean=} opt_skipInvalidationCheck Whether to skip invalidation\n * check.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.registerPendingPromise_ =\n function(p, opt_skipInvalidationCheck) {\n var self = this;\n // Check if user invalidation occurs.\n var processedP = this.checkIfInvalidated_(p, opt_skipInvalidationCheck);\n // Save created promise in pending list.\n this.pendingPromises_.push(processedP);\n processedP.thenAlways(function() {\n // When fulfilled, remove from pending list.\n goog.array.remove(self.pendingPromises_, processedP);\n });\n // Return the promise.\n return processedP\n .thenCatch(function(error) {\n var multiFactorError = null;\n if (error && error['code'] === 'auth/multi-factor-auth-required') {\n multiFactorError = fireauth.MultiFactorError.fromPlainObject(\n error.toPlainObject(),\n self.getAuth_(),\n goog.bind(self.handleMultiFactorIdTokenResolver_, self));\n }\n throw multiFactorError || error;\n });\n};\n\n\n/**\n * Completes multi-factor sign-in. This is only relevant for re-authentication\n * flows.\n * @param {{idToken: string, refreshToken: string}} response The successful\n * sign-in response containing the new ID tokens.\n * @return {!goog.Promise<!fireauth.AuthEventManager.Result>} A Promise that\n * resolves with the updated `UserCredential`.\n * @private\n */\nfireauth.AuthUser.prototype.handleMultiFactorIdTokenResolver_ =\n function(response) {\n var userCredential = null;\n var self = this;\n // Validate token response matches current user ID.\n var p = fireauth.AuthCredential.verifyTokenResponseUid(\n goog.Promise.resolve(response),\n self['uid'])\n .then(function(response) {\n // Get credential from response if available.\n userCredential = self.getUserCredential_(\n response, fireauth.constants.OperationType.REAUTHENTICATE);\n // If the credential is valid and matches the current user ID, then\n // update the tokens accordingly.\n self.updateTokensIfPresent(response);\n // This could potentially validate an invalidated user.\n self.userInvalidatedError_ = null;\n // Reload the user with the latest profile.\n return self.reload();\n })\n .then(function() {\n // Return the user credential response.\n return userCredential;\n });\n return /** @type {!goog.Promise<!fireauth.AuthEventManager.Result>} */ (\n this.registerPendingPromise_(\n p,\n // Skip invalidation check as reauthentication could revalidate a\n // user.\n true));\n};\n\n\n/**\n * Check if user invalidation occurs. If so, it caches the error so it can be\n * thrown immediately the next time an operation is run on the user.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @param {boolean=} opt_skipInvalidationCheck Whether to skip invalidation\n * check.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.AuthUser.prototype.checkIfInvalidated_ =\n function(p, opt_skipInvalidationCheck) {\n var self = this;\n // Already invalidated, reject with token expired error.\n // Unless invalidation check is to be skipped.\n if (this.userInvalidatedError_ && !opt_skipInvalidationCheck) {\n // Cancel pending promise.\n p.cancel();\n // Reject with cached error.\n return goog.Promise.reject(this.userInvalidatedError_);\n }\n return p.thenCatch(function(error) {\n // Session invalidated.\n if (fireauth.AuthUser.isUserInvalidated_(error)) {\n // Notify listeners of invalidated session.\n if (!self.userInvalidatedError_) {\n self.notifyUserInvalidatedListeners_();\n }\n // Cache the invalidation error.\n self.userInvalidatedError_ = /** @type {!fireauth.AuthError} */ (error);\n }\n // Rethrow the error.\n throw error;\n });\n};\n\n\n/**\n * @return {!Object} The object representation of the user instance.\n * @override\n */\nfireauth.AuthUser.prototype.toJSON = function() {\n // Return the plain object representation in case JSON.stringify is called on\n // a user instance.\n return this.toPlainObject();\n};\n\n\n/**\n * @return {!Object} The object representation of the user instance.\n */\nfireauth.AuthUser.prototype.toPlainObject = function() {\n var obj = {\n 'uid': this['uid'],\n 'displayName': this['displayName'],\n 'photoURL': this['photoURL'],\n 'email': this['email'],\n 'emailVerified': this['emailVerified'],\n 'phoneNumber': this['phoneNumber'],\n 'isAnonymous': this['isAnonymous'],\n 'tenantId': this['tenantId'],\n 'providerData': [],\n 'apiKey': this.apiKey_,\n 'appName': this.appName_,\n 'authDomain': this.authDomain_,\n 'stsTokenManager': this.stsTokenManager_.toPlainObject(),\n // Redirect event ID must be maintained in case there is a pending redirect\n // event.\n 'redirectEventId': this.getRedirectEventId()\n };\n // Extend user plain object with metadata object.\n if (this['metadata']) {\n goog.object.extend(obj, this['metadata'].toPlainObject());\n }\n goog.array.forEach(this['providerData'], function(userInfo) {\n obj['providerData'].push(fireauth.object.makeWritableCopy(userInfo));\n });\n // Extend plain object with multi-factor user data.\n goog.object.extend(obj, this.multiFactorUser_.toPlainObject());\n return obj;\n};\n\n\n/**\n * Converts a plain user object to {@code fireauth.AuthUser}.\n * @param {!Object} user The object representation of the user instance.\n * @return {?fireauth.AuthUser} The Firebase user object corresponding to\n * object.\n */\nfireauth.AuthUser.fromPlainObject = function(user) {\n if (!user['apiKey']) {\n return null;\n }\n var options = {\n 'apiKey': user['apiKey'],\n 'authDomain': user['authDomain'],\n 'appName': user['appName']\n };\n // Convert to server response format. Constructor does not take\n // stsTokenManager toPlainObject as that format is different than the return\n // server response which is always used to initialize a user instance.\n var stsTokenManagerResponse = {};\n if (user['stsTokenManager'] &&\n user['stsTokenManager']['accessToken']) {\n stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.ID_TOKEN] =\n user['stsTokenManager']['accessToken'];\n // Refresh token could be expired.\n stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN] =\n user['stsTokenManager']['refreshToken'] || null;\n } else {\n // Token response is a required field.\n return null;\n }\n var firebaseUser = new fireauth.AuthUser(options,\n stsTokenManagerResponse,\n /** @type {!fireauth.AuthUser.AccountInfo} */ (user));\n if (user['providerData']) {\n goog.array.forEach(user['providerData'], function(userInfo) {\n if (userInfo) {\n firebaseUser.addProviderData(/** @type {!fireauth.AuthUserInfo} */ (\n fireauth.object.makeReadonlyCopy(userInfo)));\n }\n });\n }\n // Redirect event ID must be restored to complete any pending link with\n // redirect operation owned by this user.\n if (user['redirectEventId']) {\n firebaseUser.setRedirectEventId(user['redirectEventId']);\n }\n return firebaseUser;\n};\n\n\n\n/**\n * Factory method for initializing a Firebase user object and populating its\n * user info. This is the recommended way for initializing a user externally.\n * On sign in/up operation, the server returns a token response. The response is\n * all that is needed to initialize this user.\n * @param {!Object} appOptions The application options.\n * @param {!Object} stsTokenResponse The server STS token response.\n * @param {?fireauth.storage.RedirectUserManager=}\n * opt_redirectStorageManager The utility used to store and delete a user on\n * link with redirect.\n * @param {?Array<string>=} opt_frameworks The list of frameworks to log on the\n * user on initialization.\n * @return {!goog.Promise<!fireauth.AuthUser>}\n */\nfireauth.AuthUser.initializeFromIdTokenResponse = function(appOptions,\n stsTokenResponse, opt_redirectStorageManager, opt_frameworks) {\n // Initialize the Firebase Auth user.\n var user = new fireauth.AuthUser(\n appOptions, stsTokenResponse);\n // If redirect storage manager provided, set it.\n if (opt_redirectStorageManager) {\n user.setRedirectStorageManager(opt_redirectStorageManager);\n }\n // If frameworks provided, set it.\n if (opt_frameworks) {\n user.setFramework(opt_frameworks);\n }\n // Updates the user info and data and resolves with a user instance.\n return user.reload().then(function() {\n return user;\n });\n};\n\n\n/**\n * Returns an AuthUser copy of the provided user using the provided parameters\n * without making any network request.\n * @param {!fireauth.AuthUser} user The user to be copied.\n * @param {?Object=} opt_appOptions The application options.\n * @param {?fireauth.storage.RedirectUserManager=}\n * opt_redirectStorageManager The utility used to store and delete a user on\n * link with redirect.\n * @param {?Array<string>=} opt_frameworks The list of frameworks to log on the\n * user on initialization.\n * @return {!fireauth.AuthUser}\n */\nfireauth.AuthUser.copyUser = function(user, opt_appOptions,\n opt_redirectStorageManager, opt_frameworks) {\n var appOptions = opt_appOptions || {\n 'apiKey': user.apiKey_,\n 'authDomain': user.authDomain_,\n 'appName': user.appName_\n };\n var newUser = new fireauth.AuthUser(\n appOptions, user.getStsTokenManager().toServerResponse());\n // If redirect storage manager provided, set it.\n if (opt_redirectStorageManager) {\n newUser.setRedirectStorageManager(opt_redirectStorageManager);\n }\n // If frameworks provided, set it.\n if (opt_frameworks) {\n newUser.setFramework(opt_frameworks);\n }\n // Copy remaining properties.\n newUser.copy(user);\n return newUser;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Utility for proactive refresh with exponential backoff\n * algorithm typically used to define a retry policy for certain async\n * operations.\n */\n\ngoog.provide('fireauth.ProactiveRefresh');\n\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.Timer');\n\n\n/**\n * The helper utility used to proactively refresh a certain operation based on\n * certain constraints with an exponential backoff retrial policy when\n * specific recoverable errors occur. Typically this is used to retry an\n * operation on network errors.\n * @param {!function():!goog.Promise} operation The promise returning operation\n * to run.\n * @param {!function(*):boolean} retryPolicy A function that takes in an error\n * and returns whether a retry policy should be implemented based on the\n * error. If not, the operation will not run again.\n * @param {!function():number} getWaitDuration A function that returns the wait\n * period before running again.\n * @param {number} lowerBound The lower bound duration to wait when an error\n * occurs. This is the first interval to wait before rerunning after an\n * error is detected.\n * @param {number} upperBound The upper bound duration to wait when an error\n * keeps occurring. This upper bound should not be exceeded.\n * @param {boolean=} opt_runInBackground Whether to run in the background, when\n * the tab is not visible. If the refresh should only run when the app is\n * visible, the operation will block until the app is visible and then run.\n * @constructor @struct @final\n */\nfireauth.ProactiveRefresh = function(\n operation,\n retryPolicy,\n getWaitDuration,\n lowerBound,\n upperBound,\n opt_runInBackground) {\n /**\n * @const @private {!function():!goog.Promise} The promise returning operation\n * to run.\n */\n this.operation_ = operation;\n /**\n * @const @private {!function(*):boolean} The function that takes in an error\n * and returns whether a retry policy should be implemented based on the\n * error caught.\n */\n this.retryPolicy_ = retryPolicy;\n /**\n * @const @private {!function():number} The function that returns the wait\n * period after a successful operation before running again.\n */\n this.getWaitDuration_ = getWaitDuration;\n /**\n * @const @private {number} The lower bound duration to wait when an error\n * first occurs.\n */\n this.lowerBound_ = lowerBound;\n /**\n * @const @private {number} The upper bound duration to wait when an error\n * keeps occurring. This upper bound should not be exceeded.\n */\n this.upperBound_ = upperBound;\n /**\n * @const @private {boolean} Whether to run in the background, when the tab is\n * not visible.\n */\n this.runInBackground_ = !!opt_runInBackground;\n /**\n * @private {?goog.Promise} The pending promise for the next operation to run.\n */\n this.pending_ = null;\n /**\n * @private {number} The first wait interval when a new error occurs.\n */\n this.nextErrorWaitInterval_ = this.lowerBound_;\n // Throw an error if the lower bound is greater than upper bound.\n if (this.upperBound_ < this.lowerBound_) {\n throw new Error('Proactive refresh lower bound greater than upper bound!');\n }\n};\n\n\n/** Starts the proactive refresh based on the current configuration. */\nfireauth.ProactiveRefresh.prototype.start = function() {\n // Set the next error wait interval to the lower bound. On each consecutive\n // error, this will double in value until it reaches the upper bound.\n this.nextErrorWaitInterval_ = this.lowerBound_;\n // Start proactive refresh with clean slate (successful status).\n this.process_(true);\n};\n\n\n/**\n * Returns the wait duration before the next run depending on the last run\n * status. If the last operation has succeeded, returns the getWaitDuration()\n * response. Otherwise, doubles the last error wait interval starting from\n * lowerBound and up to upperBound.\n * @param {boolean} hasSucceeded Whether last run succeeded.\n * @return {number} The wait time for the next run.\n * @private\n */\nfireauth.ProactiveRefresh.prototype.getNextRun_ = function(hasSucceeded) {\n if (hasSucceeded) {\n // If last operation succeeded, reset next error wait interval and return\n // the default wait duration.\n this.nextErrorWaitInterval_ = this.lowerBound_;\n // Return typical wait duration interval after a successful operation.\n return this.getWaitDuration_();\n } else {\n // Get next error wait interval.\n var currentErrorWaitInterval = this.nextErrorWaitInterval_;\n // Double interval for next consecutive error.\n this.nextErrorWaitInterval_ *= 2;\n // Make sure next wait interval does not exceed the maximum upper bound.\n if (this.nextErrorWaitInterval_ > this.upperBound_) {\n this.nextErrorWaitInterval_ = this.upperBound_;\n }\n return currentErrorWaitInterval;\n }\n};\n\n\n/**\n * Processes one refresh call and sets the timer for the next call based on\n * the last recorded result.\n * @param {boolean} hasSucceeded Whether last run succeeded.\n * @private\n */\nfireauth.ProactiveRefresh.prototype.process_ = function(hasSucceeded) {\n var self = this;\n // Stop any other pending operation.\n this.stop();\n // Wait for next scheduled run based on whether an error occurred during last\n // run.\n this.pending_ = goog.Timer.promise(this.getNextRun_(hasSucceeded))\n .then(function() {\n // Block for conditions (if app is required to be visible) to be ready.\n return self.waitUntilReady_();\n })\n .then(function() {\n // Run the operation.\n return self.operation_();\n })\n .then(function() {\n // If successful, try again on next cycle with no previous error\n // passed.\n self.process_(true);\n })\n .thenCatch(function(error) {\n // If an error occurs, only rerun when the error meets the retry\n // policy.\n if (self.retryPolicy_(error)) {\n // Should retry with error to trigger exponentional backoff.\n self.process_(false);\n }\n // Any other error is considered unrecoverable. Do not try again.\n });\n};\n\n\n/**\n * Returns a promise which resolves when the current tab is visible.\n * This resolves quickly if refresh is supposed to run in the background too.\n * @return {!goog.Promise} The promise that resolves when the tab is visible or\n * that requirement is not needed.\n * @private\n */\nfireauth.ProactiveRefresh.prototype.waitUntilReady_ = function() {\n // Wait until app is in foreground if required.\n if (this.runInBackground_) {\n // If runs in background, resolve quickly.\n return goog.Promise.resolve();\n } else {\n // Wait for the app to be visible before resolving the promise.\n return fireauth.util.onAppVisible();\n }\n};\n\n\n/** Stops the proactive refresh from running again. */\nfireauth.ProactiveRefresh.prototype.stop = function() {\n // If there is a pending promise.\n if (this.pending_) {\n // Cancel the pending promise and nullify it.\n this.pending_.cancel();\n this.pending_ = null;\n }\n};\n\n\n/** @return {boolean} Whether the proactive refresh is running or not. */\nfireauth.ProactiveRefresh.prototype.isRunning = function() {\n return !!this.pending_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Utility class to retrieve and cache STS token.\n */\ngoog.provide('fireauth.StsTokenManager');\ngoog.provide('fireauth.StsTokenManager.Response');\ngoog.provide('fireauth.StsTokenManager.ResponseData');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.IdToken');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('goog.Promise');\ngoog.require('goog.asserts');\n\n\n\n/**\n * Creates STS token manager.\n *\n * @param {!fireauth.RpcHandler} rpcHandler Handler for RPC requests.\n * @constructor\n */\nfireauth.StsTokenManager = function(rpcHandler) {\n /**\n * @const @private {!fireauth.RpcHandler} The RPC handler used to request STS\n * tokens.\n */\n this.rpcHandler_ = rpcHandler;\n /** @private {?string} The STS refresh token. */\n this.refreshToken_ = null;\n /** @private {?fireauth.IdToken} The STS ID token. */\n this.accessToken_ = null;\n};\n\n\n/**\n * @return {!Object} The plain object representation of the STS token manager.\n */\nfireauth.StsTokenManager.prototype.toPlainObject = function() {\n return {\n 'apiKey': this.rpcHandler_.getApiKey(),\n 'refreshToken': this.refreshToken_,\n 'accessToken': this.accessToken_ && this.accessToken_.toString(),\n // To support downgrade flows, return expiration time.\n 'expirationTime': this.getExpirationTime()\n };\n};\n\n\n/**\n * @param {!fireauth.RpcHandler} rpcHandler The RPC handler for the token\n * manager.\n * @param {?Object} obj The plain object whose STS token manager instance is to\n * be returned.\n * @return {?fireauth.StsTokenManager} The STS token manager instance from the\n * plain object provided using the RPC handler provided.\n */\nfireauth.StsTokenManager.fromPlainObject = function(rpcHandler, obj) {\n var stsTokenManager = null;\n if (obj && obj['apiKey']) {\n // These should be always equals and must be enforced in internal use.\n goog.asserts.assert(obj['apiKey'] == rpcHandler.getApiKey());\n stsTokenManager = new fireauth.StsTokenManager(rpcHandler);\n stsTokenManager.setRefreshToken(obj['refreshToken']);\n stsTokenManager.setAccessToken(obj['accessToken']);\n }\n return stsTokenManager;\n};\n\n\n/**\n * @typedef {{\n * accessToken: (?string),\n * refreshToken: (?string)\n * }}\n */\nfireauth.StsTokenManager.Response;\n\n\n/**\n * @typedef {{\n * access_token: (?string|undefined),\n * refresh_token: (?string|undefined)\n * }}\n */\nfireauth.StsTokenManager.ResponseData;\n\n\n/**\n * @param {?string} refreshToken The STS refresh token.\n */\nfireauth.StsTokenManager.prototype.setRefreshToken = function(refreshToken) {\n this.refreshToken_ = refreshToken;\n};\n\n\n/**\n * @param {?string} accessToken The STS access token.\n */\nfireauth.StsTokenManager.prototype.setAccessToken = function(accessToken) {\n this.accessToken_ = fireauth.IdToken.parse(accessToken || '');\n};\n\n\n/**\n * @return {?string} The refresh token.\n */\nfireauth.StsTokenManager.prototype.getRefreshToken = function() {\n return this.refreshToken_;\n};\n\n\n/**\n * @return {number} The STS access token expiration time in milliseconds.\n */\nfireauth.StsTokenManager.prototype.getExpirationTime = function() {\n return (this.accessToken_ && this.accessToken_.getExp() * 1000) || 0;\n};\n\n\n/**\n * The number of milliseconds before the official expiration time of a token\n * to refresh that token, to provide a buffer for RPCs to complete.\n * @const {number}\n */\nfireauth.StsTokenManager.TOKEN_REFRESH_BUFFER = 30 * 1000;\n\n\n/**\n * @return {boolean} Whether the STS access token is expired or not.\n * @private\n */\nfireauth.StsTokenManager.prototype.isExpired_ = function() {\n return goog.now() >\n this.getExpirationTime() - fireauth.StsTokenManager.TOKEN_REFRESH_BUFFER;\n};\n\n\n/**\n * Parses a response from the server that contains STS tokens (e.g. from\n * VerifyAssertion or VerifyPassword) and save the access token, refresh token,\n * and expiration time.\n * @param {!Object} response The backend response.\n * @return {string} The STS access token.\n */\nfireauth.StsTokenManager.prototype.parseServerResponse = function(response) {\n var idToken = response[fireauth.RpcHandler.AuthServerField.ID_TOKEN];\n var refreshToken =\n response[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN];\n this.setAccessToken(idToken);\n this.setRefreshToken(refreshToken);\n return idToken;\n};\n\n\n/**\n * Converts STS token manager instance to server response object.\n * @return {!Object}\n */\nfireauth.StsTokenManager.prototype.toServerResponse = function() {\n var stsTokenManagerResponse = {};\n stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.ID_TOKEN] =\n this.accessToken_ && this.accessToken_.toString();\n // Refresh token could be expired.\n stsTokenManagerResponse[fireauth.RpcHandler.AuthServerField.REFRESH_TOKEN] =\n this.getRefreshToken();\n return stsTokenManagerResponse;\n};\n\n\n/**\n * Copies IdToken, refreshToken and expirationTime from tokenManagerToCopy.\n * @param {!fireauth.StsTokenManager} tokenManagerToCopy\n */\nfireauth.StsTokenManager.prototype.copy = function(tokenManagerToCopy) {\n this.accessToken_ = tokenManagerToCopy.accessToken_;\n this.refreshToken_ = tokenManagerToCopy.refreshToken_;\n};\n\n\n/**\n * Exchanges the current refresh token with an access and refresh token.\n * @return {!goog.Promise<?fireauth.StsTokenManager.Response>}\n * @private\n */\nfireauth.StsTokenManager.prototype.exchangeRefreshToken_ = function() {\n var data = {\n 'grant_type': 'refresh_token',\n 'refresh_token': this.refreshToken_\n };\n return this.requestToken_(data);\n};\n\n\n/**\n * Sends a request to STS token endpoint for an access/refresh token.\n * @param {!Object} data The request data to send to STS token endpoint.\n * @return {!goog.Promise<?fireauth.StsTokenManager.Response>}\n * @private\n */\nfireauth.StsTokenManager.prototype.requestToken_ = function(data) {\n var self = this;\n // Send RPC request to STS token endpoint.\n return this.rpcHandler_.requestStsToken(data).then(function(resp) {\n var response = /** @type {!fireauth.StsTokenManager.ResponseData} */ (resp);\n self.accessToken_ = fireauth.IdToken.parse(\n response[fireauth.RpcHandler.StsServerField.ACCESS_TOKEN]);\n self.refreshToken_ =\n response[fireauth.RpcHandler.StsServerField.REFRESH_TOKEN];\n return /** @type {!fireauth.StsTokenManager.Response} */ ({\n 'accessToken': self.accessToken_.toString(),\n 'refreshToken': self.refreshToken_\n });\n }).thenCatch(function(error) {\n // Refresh token expired or user deleted. In this case, reset refresh token\n // to prevent sending the request again to the STS server unless\n // the token is manually updated, perhaps via successful reauthentication.\n if (error['code'] == 'auth/user-token-expired') {\n self.refreshToken_ = null;\n }\n throw error;\n });\n};\n\n\n/** @return {boolean} Whether the refresh token is expired. */\nfireauth.StsTokenManager.prototype.isRefreshTokenExpired = function() {\n return !!(this.accessToken_ && !this.refreshToken_);\n};\n\n\n/**\n * Returns an STS token. If the cached one is unexpired it is directly returned.\n * Otherwise the existing ID token or refresh token is exchanged for a new one.\n * If there is no user signed in, returns null.\n *\n * @param {boolean=} opt_forceRefresh Whether to force refresh token exchange.\n * @return {!goog.Promise<?fireauth.StsTokenManager.Response>}\n */\nfireauth.StsTokenManager.prototype.getToken = function(opt_forceRefresh) {\n var self = this;\n var forceRefresh = !!opt_forceRefresh;\n // Refresh token is expired.\n if (this.isRefreshTokenExpired()) {\n return goog.Promise.reject(\n new fireauth.AuthError(fireauth.authenum.Error.TOKEN_EXPIRED));\n }\n if (!forceRefresh && this.accessToken_ && !this.isExpired_()) {\n // Cached STS access token not expired, return it.\n return /** @type {!goog.Promise} */ (goog.Promise.resolve({\n 'accessToken': self.accessToken_.toString(),\n 'refreshToken': self.refreshToken_\n }));\n } else if (this.refreshToken_) {\n // Expired but refresh token available, exchange refresh token for STS\n // token.\n return this.exchangeRefreshToken_();\n } else {\n // No token, return null token.\n return goog.Promise.resolve(\n /** @type {?fireauth.StsTokenManager.Response} */ (null));\n }\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the fireauth.storage.RedirectUserManager class which\n * provides utilities to store, retrieve and delete an Auth user during a\n * redirect operation.\n */\n\ngoog.provide('fireauth.storage.RedirectUserManager');\n\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.authStorage');\n\n\n/**\n * Defines the Auth redirect user storage manager. It provides methods\n * to store, load and delete a user going through a link with redirect\n * operation.\n * @param {string} appId The Auth state's application ID.\n * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage\n * manager to use. If none is provided, the default global instance is used.\n * @constructor @struct @final\n */\nfireauth.storage.RedirectUserManager = function(appId, opt_manager) {\n /** @const @private{string} appId The Auth state's application ID. */\n this.appId_ = appId;\n /**\n * @const @private{!fireauth.authStorage.Manager} The underlying storage\n * manager.\n */\n this.manager_ = opt_manager || fireauth.authStorage.Manager.getInstance();\n};\n\n\n/**\n * @const @private{!fireauth.authStorage.Key} The Auth redirect user storage\n * identifier.\n */\nfireauth.storage.RedirectUserManager.REDIRECT_USER_KEY_ = {\n name: 'redirectUser',\n persistent: fireauth.authStorage.Persistence.SESSION\n};\n\n\n/**\n * Stores the user being redirected for the provided application ID.\n * @param {!fireauth.AuthUser} redirectUser The user being redirected.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.RedirectUserManager.prototype.setRedirectUser =\n function(redirectUser) {\n return this.manager_.set(\n fireauth.storage.RedirectUserManager.REDIRECT_USER_KEY_,\n redirectUser.toPlainObject(),\n this.appId_);\n};\n\n\n/**\n * Removes the stored redirected user for provided app ID.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.RedirectUserManager.prototype.removeRedirectUser =\n function() {\n return this.manager_.remove(\n fireauth.storage.RedirectUserManager.REDIRECT_USER_KEY_, this.appId_);\n};\n\n\n/**\n * @param {?string=} opt_authDomain The optional Auth domain to override if\n * provided.\n * @return {!goog.Promise<?fireauth.AuthUser>} A promise that resolves with\n * the stored redirected user for the provided app ID.\n */\nfireauth.storage.RedirectUserManager.prototype.getRedirectUser =\n function(opt_authDomain) {\n return this.manager_.get(\n fireauth.storage.RedirectUserManager.REDIRECT_USER_KEY_, this.appId_)\n .then(function(response) {\n // If potential user saved, override Auth domain if authDomain is\n // provided.\n if (response && opt_authDomain) {\n response['authDomain'] = opt_authDomain;\n }\n return fireauth.AuthUser.fromPlainObject(response || {});\n });\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the fireauth.storage.UserManager class which provides\n * utilities to retrieve, store and delete the currently logged in user and to\n * listen to external authentication changes for the same app.\n * With the ability to modify Auth state persistence. The behavior is as\n * follows:\n * Common cases:\n * <ul>\n * <li>Initially, local and session storage will be checked and the state will\n * be loaded from there without changing it unless the developer calls\n * setPersistence explicitly. The requirement is that at any time, Auth\n * state can be saved using one type only of persistence and never more than\n * one.</li>\n * <li>If the developer tries to sign in with no persistence specified, the\n * default setting will be used (local in a browser).</li>\n * <li>If the user is not signed in and persistence is set, any future sign-in\n * attempt will use that type of persistence.</li>\n * <li>If the user is signed in and the developer then switches persistence,\n * that existing signed in user will change persistence to the new one. All\n * future sign-in attempts will use that same persistence.</li>\n * <li>When signInWithRedirect is called, the current persistence type is passed\n * along with that request and on redirect back to app will pass that type\n * to determine how that state is saved (overriding the default). If the\n * persistence is explicitly specified on that page, it will change that\n * redirected Auth state persistence. This is the only time the persistence\n * is passed from one page to another.\n * So internally, on redirect, the redirect state is retrieved and then we\n * check: If the persistence was explicitly provided, we override the\n * previous type and save the Auth state using that. If no persistence was\n * explicitly provided, we use the previous persistence type that was passed\n * in the redirect response.</li>\n * </ul>\n * Behavior across tabs:\n * <ul>\n * <li>User can sign in using session storage on multiple tabs. Each tab cannot\n * see the state of the other tab.</li>\n * <li>Any attempt to sign in using local storage will be detected and\n * synchronized on all tabs. If the user was previously signed in on a\n * specific tab using session storage, that state will be cleared.</li>\n * <li>If the user was previously signed in using local storage and then signs\n * in using session storage, the user will be signed in on the current tab\n * only and signed out on all other tabs.</li>\n * <li>Similar logic is applied to the ‘none’ state. In one tab, switching to\n * ‘none’ state will delete any previously saved state in ‘local’\n * persistence in other tabs.</li>\n * </ul>\n */\n\ngoog.provide('fireauth.storage.UserManager');\n\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.authStorage');\ngoog.require('goog.Promise');\n\n\n/**\n * Defines the Auth user storage manager. It provides methods to\n * store, load and delete an authenticated current user. It also provides\n * methods to listen to external user changes (updates, sign in, sign out, etc.)\n * @param {string} appId The Auth state's application ID.\n * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage\n * manager to use. If none is provided, the default global instance is used.\n * @constructor @struct @final\n */\nfireauth.storage.UserManager = function(appId, opt_manager) {\n /** @const @private{string} appId The Auth state's application ID. */\n this.appId_ = appId;\n /**\n * @const @private{!fireauth.authStorage.Manager} The underlying storage\n * manager.\n */\n this.manager_ = opt_manager || fireauth.authStorage.Manager.getInstance();\n /**\n * @private {?fireauth.authStorage.Key} The current Auth user storage\n * identifier.\n */\n this.currentAuthUserKey_ = null;\n /**\n * @private {!goog.Promise} Storage operation serializer promise. This will\n * initialize the current persistence used and clean up any duplicate\n * states or temporary values (persistence for pending redirect).\n * Afterwards this is used to queue storage requests to make sure\n * storage operations are always synchronized and read/write events are\n * processed on the same storage.\n */\n this.onReady_ = this.initialize_();\n // This internal listener will always run before the external ones.\n // This is needed to queue processing of this first before any getCurrentUser\n // is called from external listeners.\n this.manager_.addListener(\n fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.LOCAL),\n this.appId_,\n goog.bind(this.switchToLocalOnExternalEvent_, this));\n};\n\n\n/**\n * Switches to local storage on external storage event. This will happen when\n * state is specified as local in an external tab while it is none or session\n * in the current one. If a user signs in in an external tab, the current window\n * should detect this, clear existing storage and switch to local storage.\n * @private\n */\nfireauth.storage.UserManager.prototype.switchToLocalOnExternalEvent_ =\n function() {\n var self = this;\n var localKey = fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.LOCAL);\n // Wait for any pending operation to finish first.\n // Block next read/write operation until persistence is transitioned to\n // local.\n this.waitForReady_(function() {\n return goog.Promise.resolve().then(function() {\n // If current persistence is not already local.\n if (self.currentAuthUserKey_ &&\n self.currentAuthUserKey_.persistent !=\n fireauth.authStorage.Persistence.LOCAL) {\n // Check if new current user is available in local storage.\n return self.manager_.get(localKey, self.appId_);\n }\n return null;\n }).then(function(response) {\n // Sign in on an external tab.\n if (response) {\n // Remove any existing non-local user.\n return self.removeAllExcept_(\n fireauth.authStorage.Persistence.LOCAL).then(function() {\n // Set persistence to local.\n self.currentAuthUserKey_ = localKey;\n });\n }\n });\n });\n};\n\n\n/**\n * Removes all states stored in all supported persistence types excluding the\n * specified one.\n * @param {?fireauth.authStorage.Persistence} persistence The type of storage\n * persistence to switch to.\n * @return {!goog.Promise} The promise that resolves when all stored values are\n * removed for types of storage excluding specified persistence. This helps\n * ensure there is always one type of persistence at any time.\n * @private\n */\nfireauth.storage.UserManager.prototype.removeAllExcept_ =\n function(persistence) {\n var promises = [];\n // Queue all promises to remove current user in any other persistence type.\n for (var key in fireauth.authStorage.Persistence) {\n // Skip specified persistence.\n if (fireauth.authStorage.Persistence[key] !== persistence) {\n var storageKey = fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence[key]);\n promises.push(this.manager_.remove(\n /** @type {!fireauth.authStorage.Key} */ (storageKey),\n this.appId_));\n }\n }\n // Clear persistence key (only useful for initial load upon returning from a\n // a redirect sign-in operation).\n promises.push(this.manager_.remove(\n fireauth.storage.UserManager.PERSISTENCE_KEY_,\n this.appId_));\n return goog.Promise.all(promises);\n};\n\n\n/**\n * Initializes the current persistence state. This will check the 3 supported\n * types. The first one that is found will be the current persistence. All\n * others will be cleared. If none is found we check PERSISTENCE_KEY_ which\n * when specified means that the operation is returning from a\n * signInWithRedirect call. This persistence will be applied.\n * Otherwise the default local persistence is used.\n * @return {!goog.Promise} A promise that resolves when the current persistence\n * is resolved.\n * @private\n */\nfireauth.storage.UserManager.prototype.initialize_ = function() {\n var self = this;\n // Local key.\n var localKey = fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.LOCAL);\n // Session key.\n var sessionKey = fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.SESSION);\n // In memory key. This is unlikely to contain anything on load.\n var inMemoryKey = fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.NONE);\n // Migrate any old currentUser from localStorage to indexedDB.\n // This keeps any user signed in without the need for reauthentication and\n // minimizes risks of dangling Auth states.\n return this.manager_.migrateFromLocalStorage(\n localKey, this.appId_).then(function() {\n // Check if state is stored in session storage.\n return self.manager_.get(sessionKey, self.appId_);\n }).then(function(response) {\n if (response) {\n // Session storage is being used.\n return sessionKey;\n } else {\n // Session storage is empty. Check in memory storage.\n return self.manager_.get(inMemoryKey, self.appId_)\n .then(function(response) {\n if (response) {\n // In memory storage being used.\n return inMemoryKey;\n } else {\n // Check local storage.\n return self.manager_.get(localKey, self.appId_)\n .then(function(response) {\n if (response) {\n // Local storage being used.\n return localKey;\n } else {\n // Nothing found in any supported storage.\n // Check current user persistence in storage.\n return self.manager_.get(\n fireauth.storage.UserManager.PERSISTENCE_KEY_,\n self.appId_).then(function(persistence) {\n if (persistence) {\n // Sign in with redirect operation, apply this\n // persistence to any current user.\n return fireauth.storage.UserManager\n .getAuthUserKey_(persistence);\n } else {\n // No persistence found, use the default.\n return localKey;\n }\n });\n }\n });\n }\n });\n }\n }).then(function(currentKey) {\n // Set current key according to the persistence detected.\n self.currentAuthUserKey_ = currentKey;\n // Make sure only one state available. Clean up everything else.\n return self.removeAllExcept_(currentKey.persistent);\n }).thenCatch(function(error) {\n // If an error occurs in the process and no current key detected, set to\n // persistence value to default.\n if (!self.currentAuthUserKey_) {\n self.currentAuthUserKey_ = localKey;\n }\n });\n};\n\n\n/**\n * @const @private {string} The Auth current user storage identifier name.\n */\nfireauth.storage.UserManager.AUTH_USER_KEY_NAME_ = 'authUser';\n\n\n/**\n * @const @private{!fireauth.authStorage.Key} The Auth user storage persistence\n * identifier. This is needed to remember the previous persistence state for\n * sign-in with redirect.\n */\nfireauth.storage.UserManager.PERSISTENCE_KEY_ = {\n name: 'persistence',\n persistent: fireauth.authStorage.Persistence.SESSION\n};\n\n\n/**\n * Returns the Auth user key corresponding to the persistence type provided.\n * @param {!fireauth.authStorage.Persistence} persistence The key for the\n * specified type of persistence.\n * @return {!fireauth.authStorage.Key} The corresponding Auth user storage\n * identifier.\n * @private\n */\nfireauth.storage.UserManager.getAuthUserKey_ = function(persistence) {\n return {\n name: fireauth.storage.UserManager.AUTH_USER_KEY_NAME_,\n persistent: persistence\n };\n};\n\n\n/**\n * Sets the persistence to the specified type.\n * If an existing user already is in storage, it copies that value to the new\n * storage and clears all the others.\n * @param {!fireauth.authStorage.Persistence} persistence The type of storage\n * persistence to switch to.\n * @return {!goog.Promise} A promise that resolves when persistence change is\n * applied.\n */\nfireauth.storage.UserManager.prototype.setPersistence = function(persistence) {\n var currentUser = null;\n var self = this;\n // Validate the persistence type provided. This will throw a synchronous error\n // if invalid.\n fireauth.authStorage.validatePersistenceArgument(persistence);\n // Wait for turn in queue.\n return this.waitForReady_(function() {\n // If persistence hasn't changed, do nothing.\n if (persistence != self.currentAuthUserKey_.persistent) {\n // Persistence changed. Copy from current storage to new one.\n return self.manager_.get(\n /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n self.appId_).then(function(result) {\n // Save current user.\n currentUser = result;\n // Clear from current storage.\n return self.removeAllExcept_(persistence);\n }).then(function() {\n // Update persistence key to the new one.\n self.currentAuthUserKey_ =\n fireauth.storage.UserManager.getAuthUserKey_(persistence);\n // Copy current storage type to the new one.\n if (currentUser) {\n return self.manager_.set(\n /** @type {!fireauth.authStorage.Key} */ (\n self.currentAuthUserKey_),\n currentUser,\n self.appId_);\n }\n });\n }\n // No change in persistence type.\n return goog.Promise.resolve();\n });\n};\n\n\n/**\n * Saves the current persistence type so it can be retrieved after a page\n * redirect. This is relevant for signInWithRedirect.\n * @return {!goog.Promise} Promise that resolve when current persistence is\n * saved.\n */\nfireauth.storage.UserManager.prototype.savePersistenceForRedirect = function() {\n var self = this;\n return this.waitForReady_(function() {\n // Save persistence to survive redirect.\n return self.manager_.set(\n fireauth.storage.UserManager.PERSISTENCE_KEY_,\n self.currentAuthUserKey_.persistent,\n self.appId_);\n });\n};\n\n\n/**\n * Stores the current Auth user for the provided application ID.\n * @param {!fireauth.AuthUser} currentUser The app current Auth user to save.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.UserManager.prototype.setCurrentUser = function(currentUser) {\n var self = this;\n // Wait for any pending persistence change to be resolved.\n return this.waitForReady_(function() {\n return self.manager_.set(\n /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n currentUser.toPlainObject(),\n self.appId_);\n });\n};\n\n\n/**\n * Removes the stored current user for provided app ID.\n * @return {!goog.Promise<void>} A promise that resolves on success.\n */\nfireauth.storage.UserManager.prototype.removeCurrentUser = function() {\n var self = this;\n // Wait for any pending persistence change to be resolved.\n return this.waitForReady_(function() {\n return self.manager_.remove(\n /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n self.appId_);\n });\n};\n\n\n/**\n * @param {?string=} opt_authDomain The optional Auth domain to override if\n * provided.\n * @return {!goog.Promise<?fireauth.AuthUser>} A promise that resolves with\n * the stored current user for the provided app ID.\n */\nfireauth.storage.UserManager.prototype.getCurrentUser =\n function(opt_authDomain) {\n var self = this;\n // Wait for any pending persistence change to be resolved.\n return this.waitForReady_(function() {\n return self.manager_.get(\n /** @type {!fireauth.authStorage.Key} */ (self.currentAuthUserKey_),\n self.appId_).then(function(response) {\n // If potential user saved, override Auth domain if authDomain is\n // provided.\n // This is useful in cases where on one page the developer initializes\n // the Auth instance without authDomain and signs in user using\n // headless methods. On another page, Auth is initialized with\n // authDomain for the purpose of linking with a popup. The loaded user\n // (stored without the authDomain) must have this field updated with\n // the current authDomain.\n if (response && opt_authDomain) {\n response['authDomain'] = opt_authDomain;\n }\n return fireauth.AuthUser.fromPlainObject(response || {});\n });\n });\n};\n\n\n/**\n * Serializes storage access operations especially since persistence\n * could be updated from one type to the other while read/write operations\n * occur.\n * @param {function():!goog.Promise<T>} cb The promise return callback to chain\n * when pending operations are resolved.\n * @return {!goog.Promise<T>} The resulting promise that resolves when provided\n * promise finally resolves.\n * @template T\n * @private\n */\nfireauth.storage.UserManager.prototype.waitForReady_ = function(cb) {\n // Wait for any pending persistence change to be resolved before running\n // storage related operation. Chain to onReady so next call will wait for\n // this operation to resolve.\n // While an error is unlikely, run callback even if it happens, otherwise\n // no storage related event will be allowed to complete after an error.\n this.onReady_ = this.onReady_.then(cb, cb);\n return this.onReady_;\n};\n\n\n/**\n * Adds a listener to Auth current user change event for app ID provided.\n * @param {!function()} listener The listener to run on current user change\n * event.\n */\nfireauth.storage.UserManager.prototype.addCurrentUserChangeListener =\n function(listener) {\n // When this is triggered, getCurrentUser is called, that will have to wait\n // for switchToLocalOnExternalEvent_ to resolve which is ahead of it in the\n // queue.\n this.manager_.addListener(\n fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.LOCAL),\n this.appId_,\n listener);\n};\n\n\n/**\n * Removes a listener to Auth current user change event for app ID provided.\n * @param {!function()} listener The listener to remove from current user change\n * event changes.\n */\nfireauth.storage.UserManager.prototype.removeCurrentUserChangeListener =\n function(listener) {\n this.manager_.removeListener(\n fireauth.storage.UserManager.getAuthUserKey_(\n fireauth.authStorage.Persistence.LOCAL),\n this.appId_,\n listener);\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the grecaptcha interface.\n */\n\ngoog.provide('fireauth.grecaptcha');\n\n\n/**\n * The reCAPTCHA interface for initializing and managing visible v2\n * reCAPTCHAs as well as invisible ones.\n * @interface\n */\nfireauth.grecaptcha = function() {};\n\n\n/**\n * Creates a new instance of the recaptcha client.\n *\n * @param {!Element|string} elementOrId Element or element ID for the\n * placeholder to render the reCAPTCHA client.\n * @param {!Object} params Parameters for the recaptcha client.\n * @return {number} The client ID.\n */\nfireauth.grecaptcha.prototype.render = function(elementOrId, params) {};\n\n\n/**\n * Resets a client with the given ID. If an ID is not provided, resets the\n * default client.\n *\n * @param {number=} id The ID of the recaptcha client.\n * @param {?Object=} params Parameters for the recaptcha client.\n */\nfireauth.grecaptcha.prototype.reset = function(id, params) {};\n\n\n/**\n * Gets the response for the client with the given ID. If an ID is not\n * provided, gets the response for the default client.\n *\n * @param {number=} id The ID of the recaptcha client.\n * @return {?string}\n */\nfireauth.grecaptcha.prototype.getResponse = function(id) {};\n\n\n/**\n * Programmatically triggers the invisible reCAPTCHA.\n *\n * @param {number=} opt_id The ID of the recaptcha client. Defaults to the\n * first widget created if unspecified.\n */\nfireauth.grecaptcha.prototype.execute = function(opt_id) {};\n","/**\n * @license\n * Copyright 2019 Google Inc.\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 * @fileoverview Defines the MultiFactorGenerators used to generate\n * MultiFactorAssertions. This currently covers only PhoneMultiFactorGenerator.\n */\n\ngoog.provide('fireauth.PhoneMultiFactorGenerator');\n\ngoog.require('fireauth.PhoneMultiFactorAssertion');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.object');\n\n\n/**\n * Defines the multi-factor generator for PhoneMultiFactorAssertions.\n * This class acts only as a namespace and defines some static methods and\n * properties.\n * @constructor @struct @final\n */\nfireauth.PhoneMultiFactorGenerator = function() {};\nfireauth.object.setReadonlyProperty(fireauth.PhoneMultiFactorGenerator,\n 'FACTOR_ID', fireauth.constants.SecondFactorType.PHONE);\n\n\n/**\n * Initializes a `PhoneMultiFactorAssertion` given a `PhoneAuthCredential`.\n * @param {!fireauth.PhoneAuthCredential} phoneAuthCredential\n * @return {!fireauth.PhoneMultiFactorAssertion} The `MultiFactorAssertion`\n * corresponding to the provided `PhoneAuthCredential`.\n */\nfireauth.PhoneMultiFactorGenerator.assertion = function(phoneAuthCredential) {\n return new fireauth.PhoneMultiFactorAssertion(phoneAuthCredential);\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the RecaptchaLoader implementation used to mock loading\n * of grecaptcha dependencies.\n */\n\ngoog.provide('fireauth.RecaptchaMockLoader');\n\ngoog.require('fireauth.GRecaptchaMockFactory');\ngoog.require('fireauth.RecaptchaLoader');\ngoog.require('goog.Promise');\n\n\n/**\n * Defines a mock reCAPTCHA loader by implementing the fireauth.RecaptchaLoader\n * interface.\n * @constructor\n * @implements {fireauth.RecaptchaLoader}\n */\nfireauth.RecaptchaMockLoader = function() {};\n\n\n/**\n * Loads the grecaptcha mock library if it is not loaded and returns a promise\n * that resolves on success. If the right conditions are available, will reload\n * the dependencies for a specified language code.\n * @param {?string} hl The reCAPTCHA language code.\n * @return {!goog.Promise<!fireauth.grecaptcha>} A promise that resolves when\n * grecaptcha is loaded.\n * @override\n */\nfireauth.RecaptchaMockLoader.prototype.loadRecaptchaDeps =\n function(hl) {\n return goog.Promise.resolve(\n \t/** @type {!fireauth.grecaptcha} */ (fireauth.GRecaptchaMockFactory.getInstance()));\n};\n\n\n/**\n * Decrements the reCAPTCHA instance counter.\n * @override\n */\nfireauth.RecaptchaMockLoader.prototype.clearSingleRecaptcha =\n function() {};\n\n\n/**\n * @private {?fireauth.RecaptchaMockLoader} The singleton instance\n * for the mock reCAPTCHA dependency loader.\n */\nfireauth.RecaptchaMockLoader.instance_ = null;\n\n\n/**\n * @return {!fireauth.RecaptchaMockLoader} The singleton mock reCAPTCHA\n * dependency loader instance.\n */\nfireauth.RecaptchaMockLoader.getInstance = function() {\n // Check if there is an existing instance. Otherwise create one and cache it.\n if (!fireauth.RecaptchaMockLoader.instance_) {\n fireauth.RecaptchaMockLoader.instance_ =\n new fireauth.RecaptchaMockLoader();\n }\n return fireauth.RecaptchaMockLoader.instance_;\n};\n","/**\n * @license\n * Copyright 2018 Google Inc.\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 * @fileoverview Defines the RecaptchaLoader implementation used to load all\n * the grecaptcha dependencies.\n */\n\ngoog.provide('fireauth.RecaptchaRealLoader');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.RecaptchaLoader');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.net.jsloader');\ngoog.require('goog.string.Const');\n\n\n/**\n * Utility to help load reCAPTCHA dependencies for specified languages.\n * @constructor\n * @implements {fireauth.RecaptchaLoader}\n */\nfireauth.RecaptchaRealLoader = function() {\n /**\n * @private {number} The reCAPTCHA instance counter. This is used to track the\n * number of reCAPTCHAs rendered on the page. This is needed to allow\n * localization of the reCAPTCHA. Localization is applied by loading the\n * grecaptcha SDK with the hl field provided. However, this will break\n * existing reCAPTCHAs. So we should only support i18n when there are no\n * other widgets rendered on this screen. If the developer is already\n * using reCAPTCHA in another context, we will disable localization so we\n * don't accidentally break existing reCAPTCHA widgets.\n */\n this.counter_ = goog.global['grecaptcha'] ? Infinity : 0;\n /** @private {?string} The current reCAPTCHA language code. */\n this.hl_ = null;\n /** @const @private {string} The reCAPTCHA callback name. */\n this.cbName_ = '__rcb' + Math.floor(Math.random() * 1000000).toString();\n};\n\n\n/** @private @const {!goog.string.Const} The reCAPTCHA javascript source URL. */\nfireauth.RecaptchaRealLoader.RECAPTCHA_SRC_ = goog.string.Const.from(\n 'https://www.google.com/recaptcha/api.js?onload=%{onload}&render=explicit' +\n '&hl=%{hl}');\n\n\n/**\n * The default timeout delay (units in milliseconds) for requests loading\n * the external reCAPTCHA dependencies.\n * @const {!fireauth.util.Delay}\n * @private\n */\nfireauth.RecaptchaRealLoader.DEFAULT_DEPENDENCY_TIMEOUT_ =\n new fireauth.util.Delay(30000, 60000);\n\n\n/**\n * Loads the grecaptcha client library if it is not loaded and returns a promise\n * that resolves on success. If the right conditions are available, will reload\n * the dependencies for a specified language code.\n * @param {?string} hl The reCAPTCHA language code.\n * @return {!goog.Promise<!fireauth.grecaptcha>} A promise that resolves when\n * grecaptcha is loaded.\n * @override\n */\nfireauth.RecaptchaRealLoader.prototype.loadRecaptchaDeps =\n function(hl) {\n var self = this;\n return new goog.Promise(function(resolve, reject) {\n var timer = setTimeout(\n function() {\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.NETWORK_REQUEST_FAILED));\n },\n fireauth.RecaptchaRealLoader.DEFAULT_DEPENDENCY_TIMEOUT_\n .get()\n );\n // Load grecaptcha SDK if not already loaded or language changed since last\n // load and no other rendered reCAPTCHA is visible,\n if (!goog.global['grecaptcha'] || (hl !== self.hl_ && !self.counter_)) {\n // reCAPTCHA saves the onload function and applies it on subsequent\n // reloads. This means that the callback name has to remain the same.\n goog.global[self.cbName_] = function() {\n if (!goog.global['grecaptcha']) {\n clearTimeout(timer);\n // This should not happen.\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR));\n } else {\n // Update the current language code.\n self.hl_ = hl;\n var render = goog.global['grecaptcha']['render'];\n // Wrap grecaptcha.render to keep track of rendered grecaptcha. This\n // helps detect if the developer rendered a non\n // firebase.auth.RecaptchaVerifier reCAPTCHA.\n goog.global['grecaptcha']['render'] =\n function(container, parameters) {\n var widgetId = render(container, parameters);\n // Increment only after render succeeds, in case an error is thrown\n // during rendering.\n self.counter_++;\n return widgetId;\n };\n clearTimeout(timer);\n resolve(goog.global['grecaptcha']);\n }\n delete goog.global[self.cbName_];\n };\n // Construct reCAPTCHA URL and on load, run the temporary function.\n var url = goog.html.TrustedResourceUrl.format(\n fireauth.RecaptchaRealLoader.RECAPTCHA_SRC_,\n {'onload': self.cbName_, 'hl': hl || ''});\n // TODO: eventually, replace all dependencies on goog.net.jsloader.\n goog.Promise.resolve(goog.net.jsloader.safeLoad(url))\n .thenCatch(function(error) {\n clearTimeout(timer);\n // In case library fails to load, typically due to a network error,\n // reset cached loader to null to force a refresh on a retrial.\n reject(new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'Unable to load external reCAPTCHA dependencies!'));\n });\n } else {\n clearTimeout(timer);\n resolve(goog.global['grecaptcha']);\n }\n });\n};\n\n\n/**\n * Decrements the reCAPTCHA instance counter.\n * @override\n */\nfireauth.RecaptchaRealLoader.prototype.clearSingleRecaptcha =\n function() {\n this.counter_--;\n};\n\n\n/**\n * @private {?fireauth.RecaptchaRealLoader} The singleton instance\n * for reCAPTCHA dependency loader.\n */\nfireauth.RecaptchaRealLoader.instance_ = null;\n\n\n/**\n * @return {!fireauth.RecaptchaRealLoader} The singleton reCAPTCHA\n * dependency loader instance.\n */\nfireauth.RecaptchaRealLoader.getInstance = function() {\n // Check if there is an existing instance. Otherwise create one and cache it.\n if (!fireauth.RecaptchaRealLoader.instance_) {\n fireauth.RecaptchaRealLoader.instance_ =\n new fireauth.RecaptchaRealLoader();\n }\n return fireauth.RecaptchaRealLoader.instance_;\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Defines the reCAPTCHA app verifier and its base class. The\n * former is currently used for web phone authentication whereas the latter is\n * used for the mobile app verification web fallback.\n */\ngoog.provide('fireauth.BaseRecaptchaVerifier');\ngoog.provide('fireauth.RecaptchaVerifier');\n\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.RecaptchaMockLoader');\ngoog.require('fireauth.RecaptchaRealLoader');\ngoog.require('fireauth.RpcHandler');\ngoog.require('fireauth.authenum.Error');\ngoog.require('fireauth.constants');\ngoog.require('fireauth.object');\ngoog.require('fireauth.util');\ngoog.require('goog.Promise');\ngoog.require('goog.array');\ngoog.require('goog.dom');\n\n\n/**\n * Creates the firebase base reCAPTCHA app verifier independent of Firebase\n * App or Auth instances.\n *\n * @param {string} apiKey The API key used to initialize the RPC handler for\n * querying the Auth backend.\n * @param {!Element|string} container The reCAPTCHA container parameter. This\n * has different meaning depending on whether the reCAPTCHA is hidden or\n * visible.\n * @param {?Object=} opt_parameters The optional reCAPTCHA parameters.\n * @param {?(function():?string)=} opt_getLanguageCode The language code getter\n * function.\n * @param {?string=} opt_clientVersion The optional client version to append to\n * RPC header.\n * @param {?Object=} opt_rpcHandlerConfig The optional RPC handler\n * configuration, typically passed when different Auth endpoints are to be\n * used.\n * @param {boolean=} opt_isTestingMode Whether the reCAPTCHA is to be rendered\n * in testing mode.\n * @constructor\n */\nfireauth.BaseRecaptchaVerifier = function(apiKey, container, opt_parameters,\n opt_getLanguageCode, opt_clientVersion, opt_rpcHandlerConfig,\n opt_isTestingMode) {\n // Set the type readonly property needed for full implementation of the\n // firebase.auth.ApplicationVerifier interface.\n fireauth.object.setReadonlyProperty(this, 'type', 'recaptcha');\n /**\n * @private {?goog.Promise<void>} The cached reCAPTCHA ready response. This is\n * null until the first time it is triggered or when an error occurs in\n * getting ready.\n */\n this.cachedReadyPromise_ = null;\n /** @private {?number} The reCAPTCHA widget ID. Null when not rendered. */\n this.widgetId_ = null;\n /** @private {boolean} Whether the instance is already destroyed. */\n this.destroyed_ = false;\n /** @private {!Element|string} The reCAPTCHA container. */\n this.container_ = container;\n /**\n * @private {?fireauth.grecaptcha} The reCAPTCHA client library namespace.\n */\n this.grecaptcha_ = null;\n /**\n * @const @private {!fireauth.RecaptchaLoader} The grecaptcha loader.\n */\n this.recaptchaLoader_ = !!opt_isTestingMode ?\n fireauth.RecaptchaMockLoader.getInstance() :\n fireauth.RecaptchaRealLoader.getInstance();\n // If no parameters passed, use default settings.\n // Currently, visible recaptcha is the default setting as invisible reCAPTCHA\n // is not yet supported by the backend.\n /** @private {!Object} The reCAPTCHA parameters. */\n this.parameters_ = opt_parameters || {\n 'theme': 'light',\n 'type': 'image'\n };\n /** @private {!Array<!goog.Promise<*>|!goog.Promise<void>>} List of\n * pending promises. */\n this.pendingPromises_ = [];\n if (this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SITEKEY]) {\n // sitekey should not be provided.\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n 'sitekey should not be provided for reCAPTCHA as one is ' +\n 'automatically provisioned for the current project.');\n }\n /** @private {boolean} Whether the reCAPTCHA is invisible or not. */\n this.isInvisible_ =\n this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SIZE] ===\n 'invisible';\n // Check if DOM is supported.\n if (!fireauth.util.isDOMSupported()) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED,\n 'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' +\n 'environment with DOM support.');\n }\n // reCAPTCHA container must be valid and if visible, not empty.\n // An invisible reCAPTCHA will not render in its container. That container\n // will execute the reCAPTCHA when it is clicked.\n if (!goog.dom.getElement(container) ||\n (!this.isInvisible_ && goog.dom.getElement(container).hasChildNodes())) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n 'reCAPTCHA container is either not found or already contains inner ' +\n 'elements!');\n }\n /**\n * @private {!fireauth.RpcHandler} The RPC handler for querying the auth\n * backend.\n */\n this.rpcHandler_ = new fireauth.RpcHandler(\n apiKey,\n opt_rpcHandlerConfig || null,\n opt_clientVersion || null);\n /**\n * @private {function():?string} Current language code getter.\n */\n this.getLanguageCode_ = opt_getLanguageCode || function() {return null;};\n var self = this;\n /**\n * @private {!Array<function(?string)>} The token change listeners.\n */\n this.tokenListeners_ = [];\n // Wrap token callback.\n var existingCallback =\n this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.CALLBACK];\n this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.CALLBACK] =\n function(response) {\n // Dispatch internal event for the token response.\n self.dispatchEvent_(response);\n if (typeof existingCallback === 'function') {\n existingCallback(response);\n } else if (typeof existingCallback === 'string') {\n // Check if the provided callback is a global function name.\n var cb = fireauth.util.getObjectRef(existingCallback, goog.global);\n if (typeof cb === 'function') {\n // If so, trigger it.\n cb(response);\n }\n }\n };\n // Wrap expired token callback.\n var existingExpiredCallback = this.parameters_[\n fireauth.BaseRecaptchaVerifier.ParamName.EXPIRED_CALLBACK];\n this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.EXPIRED_CALLBACK] =\n function() {\n // Dispatch internal event for the token expiration.\n self.dispatchEvent_(null);\n if (typeof existingExpiredCallback === 'function') {\n existingExpiredCallback();\n } else if (typeof existingExpiredCallback === 'string') {\n // Check if the provided expired callback is a global function name.\n var cb = fireauth.util.getObjectRef(existingExpiredCallback, goog.global);\n if (typeof cb === 'function') {\n // If so, trigger it.\n cb();\n }\n }\n };\n};\n\n\n/**\n * grecaptcha parameter names.\n * @enum {string}\n */\nfireauth.BaseRecaptchaVerifier.ParamName = {\n CALLBACK: 'callback',\n EXPIRED_CALLBACK: 'expired-callback',\n SITEKEY: 'sitekey',\n SIZE: 'size'\n};\n\n\n/**\n * Dispatches the token change event to all subscribed listeners.\n * @param {?string} token The current detected token, null for none.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.dispatchEvent_ = function(token) {\n for (var i = 0; i < this.tokenListeners_.length; i++) {\n try {\n this.tokenListeners_[i](token);\n } catch (e) {\n // If any handler fails, ignore and run next handler.\n }\n }\n};\n\n\n/**\n * Add a reCAPTCHA token change listener.\n * @param {function(?string)} listener The token listener to add.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.addTokenChangeListener_ =\n function(listener) {\n this.tokenListeners_.push(listener);\n};\n\n\n/**\n * Remove a reCAPTCHA token change listener.\n * @param {function(?string)} listener The token listener to remove.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.removeTokenChangeListener_ =\n function(listener) {\n goog.array.removeAllIf(this.tokenListeners_, function(ele) {\n return ele == listener;\n });\n};\n\n\n/**\n * Takes in a pending promise, saves it and adds a clean up callback which\n * forgets the pending promise after it is fulfilled and echoes the promise\n * back.\n * @param {!goog.Promise<*, *>|!goog.Promise<void>} p The pending promise.\n * @return {!goog.Promise<*, *>|!goog.Promise<void>}\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.registerPendingPromise_ = function(p) {\n var self = this;\n // Save created promise in pending list.\n this.pendingPromises_.push(p);\n p.thenAlways(function() {\n // When fulfilled, remove from pending list.\n goog.array.remove(self.pendingPromises_, p);\n });\n // Return the promise.\n return p;\n};\n\n\n/** @return {boolean} Whether verifier instance has pending promises. */\nfireauth.BaseRecaptchaVerifier.prototype.hasPendingPromises = function() {\n return this.pendingPromises_.length != 0;\n};\n\n\n/**\n * Gets the current RecaptchaVerifier in a ready state for rendering by first\n * checking that the environment supports a reCAPTCHA, loading reCAPTCHA\n * dependencies if not already available and then getting the Firebase project's\n * provisioned reCAPTCHA configuration.\n * @return {!goog.Promise<void>} The promise that resolves when recaptcha\n * is ready for rendering.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.isReady_ = function() {\n var self = this;\n // If previously called, return the cached response.\n if (this.cachedReadyPromise_) {\n return this.cachedReadyPromise_;\n }\n this.cachedReadyPromise_ = this.registerPendingPromise_(goog.Promise.resolve()\n .then(function() {\n // Verify environment first.\n // Fail quickly from a worker environment or non-HTTP/HTTPS environment.\n if (fireauth.util.isHttpOrHttps() && !fireauth.util.isWorker()) {\n // Wait for DOM to be ready as this feature depends on that.\n return fireauth.util.onDomReady();\n } else {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.OPERATION_NOT_SUPPORTED,\n 'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' +\n 'environment.');\n }\n })\n .then(function() {\n // Load external reCAPTCHA dependencies if not already there, taking\n // into account the current language code.\n return self.recaptchaLoader_.loadRecaptchaDeps(self.getLanguageCode_());\n })\n .then(function(grecaptcha) {\n self.grecaptcha_ = grecaptcha;\n // Load Firebase project's reCAPTCHA configuration.\n return self.rpcHandler_.getRecaptchaParam();\n })\n .then(function(result) {\n // Update the reCAPTCHA parameters.\n self.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SITEKEY] =\n result[fireauth.RpcHandler.AuthServerField.RECAPTCHA_SITE_KEY];\n }).thenCatch(function(error) {\n // Anytime an error occurs, reset the cached ready promise to rerun on\n // retrial.\n self.cachedReadyPromise_ = null;\n // Rethrow the error.\n throw error;\n }));\n // Return the cached/pending ready promise.\n return this.cachedReadyPromise_;\n};\n\n/**\n * Renders the reCAPTCHA and returns the allocated widget ID.\n * @return {!goog.Promise<number>} The promise that resolves with the reCAPTCHA\n * widget ID when it is rendered.\n */\nfireauth.BaseRecaptchaVerifier.prototype.render = function() {\n this.checkIfDestroyed_();\n var self = this;\n // Get reCAPTCHA ready.\n return this.registerPendingPromise_(this.isReady_().then(function() {\n if (self.widgetId_ === null) {\n // For a visible reCAPTCHA, embed in a wrapper DIV container to allow\n // re-rendering in the same developer provided container.\n var container = self.container_;\n if (!self.isInvisible_) {\n // Get outer container (the developer provided container).\n var outerContainer = goog.dom.getElement(container);\n // Create wrapper temp DIV container.\n container = goog.dom.createDom(goog.dom.TagName.DIV);\n // Add temp DIV to outer container.\n outerContainer.appendChild(container);\n }\n // If not initialized, initialize reCAPTCHA and return its widget ID.\n self.widgetId_ = self.grecaptcha_.render(container, self.parameters_);\n }\n return self.widgetId_;\n }));\n};\n\n\n/**\n * Gets the reCAPTCHA ready and waits for the reCAPTCHA token to be available\n * before resolving the promise returned.\n * @return {!goog.Promise<string>} The promise that resolves with the reCAPTCHA\n * token when reCAPTCHA challenge is solved.\n */\nfireauth.BaseRecaptchaVerifier.prototype.verify = function() {\n // Fail if reCAPTCHA is already destroyed.\n this.checkIfDestroyed_();\n var self = this;\n // Render reCAPTCHA.\n return this.registerPendingPromise_(this.render().then(function(widgetId) {\n return new goog.Promise(function(resolve, reject) {\n // Get current reCAPTCHA token.\n var recaptchaToken = self.grecaptcha_.getResponse(widgetId);\n if (recaptchaToken) {\n // Unexpired token already available. Resolve pending promise with that\n // token.\n resolve(recaptchaToken);\n } else {\n // No token available. Listen to token change.\n var cb = function(token) {\n if (!token) {\n // Ignore token expirations.\n return;\n }\n // Remove temporary token change listener.\n self.removeTokenChangeListener_(cb);\n // Resolve with new token.\n resolve(token);\n };\n // Add temporary token change listener.\n self.addTokenChangeListener_(cb);\n if (self.isInvisible_) {\n // Execute invisible reCAPTCHA to force a challenge.\n // This should do nothing if already triggered either by developer or\n // by a button click.\n self.grecaptcha_.execute(/** @type {number} */ (self.widgetId_));\n }\n }\n });\n }));\n};\n\n\n/**\n * Resets the reCAPTCHA widget.\n */\nfireauth.BaseRecaptchaVerifier.prototype.reset = function() {\n this.checkIfDestroyed_();\n if (this.widgetId_ !== null) {\n this.grecaptcha_.reset(this.widgetId_);\n }\n};\n\n\n/**\n * Throws an error if the reCAPTCHA verifier is already cleared.\n * @private\n */\nfireauth.BaseRecaptchaVerifier.prototype.checkIfDestroyed_ = function() {\n if (this.destroyed_) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.INTERNAL_ERROR,\n 'RecaptchaVerifier instance has been destroyed.');\n }\n};\n\n\n/**\n * Removes the reCAPTCHA from the DOM.\n */\nfireauth.BaseRecaptchaVerifier.prototype.clear = function() {\n this.checkIfDestroyed_();\n this.destroyed_ = true;\n // Decrement reCAPTCHA instance counter.\n this.recaptchaLoader_.clearSingleRecaptcha();\n // Cancel all pending promises.\n for (var i = 0; i < this.pendingPromises_.length; i++) {\n this.pendingPromises_[i].cancel(\n 'RecaptchaVerifier instance has been destroyed.');\n }\n if (!this.isInvisible_) {\n goog.dom.removeChildren(goog.dom.getElement(this.container_));\n }\n};\n\n\n/**\n * Creates the Firebase reCAPTCHA app verifier, publicly available, for the\n * Firebase app provided, used for web phone authentication.\n * This is a subclass of fireauth.BaseRecaptchaVerifier.\n *\n * @param {!Element|string} container The reCAPTCHA container parameter. This\n * has different meaning depending on whether the reCAPTCHA is hidden or\n * visible.\n * @param {?Object=} opt_parameters The optional reCAPTCHA parameters.\n * @param {?firebase.app.App=} opt_app The corresponding Firebase app.\n * @constructor\n * @extends {fireauth.BaseRecaptchaVerifier}\n */\nfireauth.RecaptchaVerifier = function(container, opt_parameters, opt_app) {\n var isTestingMode = false;\n var apiKey;\n try {\n /** @private {!firebase.app.App} The corresponding Firebase app instance. */\n this.app_ = opt_app || firebase.app();\n } catch (error) {\n throw new fireauth.AuthError(\n fireauth.authenum.Error.ARGUMENT_ERROR,\n 'No firebase.app.App instance is currently initialized.');\n }\n // API key is required for web client RPC calls.\n if (this.app_.options && this.app_.options['apiKey']) {\n apiKey = this.app_.options['apiKey'];\n } else {\n throw new fireauth.AuthError(fireauth.authenum.Error.INVALID_API_KEY);\n }\n var self = this;\n // Construct the language code getter based on the underlying Auth instance.\n var getLanguageCode = function() {\n var languageCode;\n // Get the latest language setting.\n // reCAPTCHA does not support updating the language of an already\n // rendered reCAPTCHA. Reloading the SDK with the new hl will break\n // the existing rendered localized reCAPTCHA. We will need to\n // document that a new fireauth.BaseRecaptchaVerifier instance needs\n // to be instantiated after the language is updated. Otherwise, the\n // old language code will remain active on the existing instance.\n try {\n languageCode = self.app_['auth']().getLanguageCode();\n } catch (e) {\n languageCode = null;\n }\n return languageCode;\n };\n // Get the framework version from Auth instance.\n var frameworkVersion = null;\n try {\n frameworkVersion = this.app_['auth']().getFramework();\n } catch (e) {\n // Do nothing.\n }\n try {\n isTestingMode =\n this.app_['auth']()['settings']['appVerificationDisabledForTesting'];\n } catch (e) {\n // Do nothing.\n }\n // Get the client version based on the Firebase JS version.\n var clientFullVersion = firebase.SDK_VERSION ?\n fireauth.util.getClientVersion(\n fireauth.util.ClientImplementation.JSCORE, firebase.SDK_VERSION,\n frameworkVersion) :\n null;\n // Call the superclass constructor with the computed API key, reCAPTCHA\n // container, optional parameters, language code getter, Firebase JS client\n // version and the current client configuration endpoints.\n fireauth.RecaptchaVerifier.base(this, 'constructor', apiKey,\n container, opt_parameters, getLanguageCode, clientFullVersion,\n fireauth.constants.getEndpointConfig(fireauth.constants.clientEndpoint),\n isTestingMode);\n};\ngoog.inherits(fireauth.RecaptchaVerifier, fireauth.BaseRecaptchaVerifier);\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Provides function argument validation for third-party calls\n * that cannot be validated with Closure compiler.\n */\n\ngoog.provide('fireauth.args');\ngoog.provide('fireauth.args.Argument');\n\ngoog.require('fireauth.Auth');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.MultiFactorSession');\ngoog.require('fireauth.authenum.Error');\n\n\n/**\n * Represents an argument to a function. Fields:\n * <ul>\n * <li> name: A label for the argument. For example, the names of the arguments\n * to a signIn() function might be \"email\" and \"password\".\n * <li> typeLabel: A label for the expected type of the argument, starting with\n * an article, for example, \"an object\" or \"a valid credential\".\n * <li> optional: Whether or not this argument is optional. Optional arguments\n * cannot come after non-optional arguments in the input to validate().\n * <li> validator: A function that takes the passed value of this argument\n * and returns whether the value is valid or not.\n * </ul>\n * @typedef {{\n * name: string,\n * typeLabel: string,\n * optional: boolean,\n * validator: function (*) : boolean,\n * }}\n */\nfireauth.args.Argument;\n\n\n/**\n * Validates the arguments to a method call and throws an error if invalid. This\n * can be used to validate external calls where the Closure compiler cannot\n * detect errors.\n *\n * Example usage:\n * function greet(recipient, opt_useFormalLanguage) {\n * fireauth.args.validate('greet', [\n * fireauth.args.string('recipient'),\n * fireauth.args.bool('opt_useFormalLanguage', true)\n * ], arguments);\n * if (opt_useFormalLanguage) {\n * console.log('Good day, ' + recipient + '.');\n * } else {\n * console.log('Wassup, ' + recipient + '?');\n * }\n * }\n * greet('Mr. Manager', true); // Prints 'Good day, Mr. Manager.'\n * greet('Billy Bob'); // Prints 'Wassup, Billy Bob?'\n * greet(133); // Throws 'greet failed: First argument \"recipient\" must be a\n * // valid string.'\n * greet(); // Throws 'greet failed: Expected 1-2 arguments but got 0.'\n * greet('Mr. Manager', true, 'ohno'); // Throws 'greet failed: Expected 1-2\n * // arguments but got 3.'\n *\n * This can also be used to validate setters by passing an additional true\n * argument to fireauth.args.validate. This modifies the error message to be\n * relevant for that setter.\n *\n * @param {string} apiName The name of the method being called, to display in\n * the error message for debugging purposes.\n * @param {!Array<!fireauth.args.Argument>} expected The expected arguments.\n * @param {!IArrayLike} actual The arguments object of the function whose\n * parameters we want to validate.\n * @param {boolean=} opt_isSetter Whether the function is a setter which takes\n * a single argument.\n */\nfireauth.args.validate = function(apiName, expected, actual, opt_isSetter) {\n // Convert the arguments object into a real array.\n var actualAsArray = Array.prototype.slice.call(actual);\n var errorMessage = fireauth.args.validateAndGetMessage_(\n expected, actualAsArray, opt_isSetter);\n if (errorMessage) {\n throw new fireauth.AuthError(fireauth.authenum.Error.ARGUMENT_ERROR,\n apiName + ' failed: ' + errorMessage);\n }\n};\n\n\n/**\n * @param {!Array<!fireauth.args.Argument>} expected\n * @param {!Array<*>} actual\n * @param {boolean=} opt_isSetter Whether the function is a setter which takes\n * a single argument.\n * @return {?string} The error message if there is an error, or otherwise\n * null.\n * @private\n */\nfireauth.args.validateAndGetMessage_ =\n function(expected, actual, opt_isSetter) {\n var minNumArgs = fireauth.args.calcNumRequiredArgs_(expected);\n var maxNumArgs = expected.length;\n if (actual.length < minNumArgs || maxNumArgs < actual.length) {\n return fireauth.args.makeLengthError_(minNumArgs, maxNumArgs,\n actual.length);\n }\n\n for (var i = 0; i < actual.length; i++) {\n // Argument is optional and undefined is explicitly passed.\n var optionalUndefined = expected[i].optional && actual[i] === undefined;\n // Check if invalid argument and the argument is not optional with undefined\n // passed.\n if (!expected[i].validator(actual[i]) && !optionalUndefined) {\n return fireauth.args.makeErrorAtPosition_(i, expected[i], opt_isSetter);\n }\n }\n\n return null;\n};\n\n\n/**\n * @param {!Array<!fireauth.args.Argument>} expected\n * @return {number} The number of required arguments.\n * @private\n */\nfireauth.args.calcNumRequiredArgs_ = function(expected) {\n var numRequiredArgs = 0;\n var isOptionalSection = false;\n for (var i = 0; i < expected.length; i++) {\n if (expected[i].optional) {\n isOptionalSection = true;\n } else {\n if (isOptionalSection) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'Argument validator encountered a required argument after an ' +\n 'optional argument.');\n }\n numRequiredArgs++;\n }\n }\n return numRequiredArgs;\n};\n\n\n/**\n * @param {number} min The minimum number of arguments to the function,\n * inclusive.\n * @param {number} max The maximum number of arguments to the function,\n * inclusive.\n * @param {number} actual The actual number of arguments received.\n * @return {string} The error message.\n * @private\n */\nfireauth.args.makeLengthError_ = function(min, max, actual) {\n var numExpectedString;\n if (min == max) {\n if (min == 1) {\n numExpectedString = '1 argument';\n } else {\n numExpectedString = min + ' arguments';\n }\n } else {\n numExpectedString = min + '-' + max + ' arguments';\n }\n return 'Expected ' + numExpectedString + ' but got ' + actual + '.';\n};\n\n\n/**\n * @param {number} position The position at which there was an error.\n * @param {!fireauth.args.Argument} expectedType The expected type of the\n * argument, which was violated.\n * @param {boolean=} opt_isSetter Whether the function is a setter which takes\n * a single argument.\n * @return {string} The error message.\n * @private\n */\nfireauth.args.makeErrorAtPosition_ =\n function(position, expectedType, opt_isSetter) {\n var ordinal = fireauth.args.makeOrdinal_(position);\n var argName = expectedType.name ?\n fireauth.args.quoteString_(expectedType.name) + ' ' : '';\n // Add support to setters for readable/writable properties which take a\n // required single argument.\n var errorPrefix = !!opt_isSetter ? '' : ordinal + ' argument ';\n return errorPrefix + argName + 'must be ' +\n expectedType.typeLabel + '.';\n};\n\n\n/** @private {!Array<string>} The first few ordinal numbers. */\nfireauth.args.ORDINAL_NUMBERS_ = ['First', 'Second', 'Third', 'Fourth',\n 'Fifth', 'Sixth', 'Seventh', 'Eighth', 'Ninth'];\n\n\n/**\n * @param {number} cardinal An integer.\n * @return {string} The integer converted to an ordinal number, starting at\n * \"First\". That is, makeOrdinal_(0) returns \"First\" and makeOrdinal_(1)\n * returns \"Second\", etc.\n * @private\n */\nfireauth.args.makeOrdinal_ = function(cardinal) {\n // We only support the first few ordinal numbers. We could provide a more\n // robust solution, but it is unlikely that a function would need more than\n // nine arguments.\n if (cardinal < 0 || cardinal >= fireauth.args.ORDINAL_NUMBERS_.length) {\n throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR,\n 'Argument validator received an unsupported number of arguments.');\n }\n return fireauth.args.ORDINAL_NUMBERS_[cardinal];\n};\n\n\n/**\n * Specifies a string argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.string = function(opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: 'a valid string',\n optional: !!opt_optional,\n validator: x => typeof x === 'string'\n };\n};\n\n\n/**\n * Specifies a boolean argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.bool = function(opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: 'a boolean',\n optional: !!opt_optional,\n validator: x => typeof x === 'boolean'\n };\n};\n\n\n/**\n * Specifies a number argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.number = function(opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: 'a valid number',\n optional: !!opt_optional,\n validator: x => typeof x === 'number'\n };\n};\n\n\n/**\n * Specifies an object argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.object = function(opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: 'a valid object',\n optional: !!opt_optional,\n validator: goog.isObject\n };\n};\n\n\n/**\n * Specifies a function argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.func = function(opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: 'a function',\n optional: !!opt_optional,\n validator: goog.isFunction\n };\n};\n\n\n/**\n * Specifies a null argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.null = function(opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: 'null',\n optional: !!opt_optional,\n validator: x => x === null\n };\n};\n\n\n/**\n * Specifies an HTML element argument.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.element = function(opt_name, opt_optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: opt_name || '',\n typeLabel: 'an HTML element',\n optional: !!opt_optional,\n validator: /** @type {function(!Element) : boolean} */ (\n function(element) {\n return !!(element && element instanceof Element);\n })\n });\n};\n\n\n/**\n * Specifies an instance of Firebase Auth.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.firebaseAuth = function(opt_optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: 'auth',\n typeLabel: 'an instance of Firebase Auth',\n optional: !!opt_optional,\n validator: /** @type {function(!fireauth.Auth) : boolean} */ (\n function(auth) {\n return !!(auth && auth instanceof fireauth.Auth);\n })\n });\n};\n\n\n/**\n * Specifies an instance of Firebase User.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.firebaseUser = function(opt_optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: 'user',\n typeLabel: 'an instance of Firebase User',\n optional: !!opt_optional,\n validator: /** @type {function(!fireauth.AuthUser) : boolean} */ (\n function(user) {\n return !!(user && user instanceof fireauth.AuthUser);\n })\n });\n};\n\n\n/**\n * Specifies an instance of Firebase App.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.firebaseApp = function(opt_optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: 'app',\n typeLabel: 'an instance of Firebase App',\n optional: !!opt_optional,\n validator: /** @type {function(!firebase.app.App) : boolean} */ (\n function(app) {\n return !!(app && app instanceof firebase.app.App);\n })\n });\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.AuthCredential interface.\n * @param {?fireauth.idp.ProviderId=} opt_requiredProviderId The required type\n * of provider.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.authCredential =\n function(opt_requiredProviderId, opt_name, opt_optional) {\n var name = opt_name ||\n (opt_requiredProviderId ?\n opt_requiredProviderId + 'Credential' :\n 'credential');\n var typeLabel = opt_requiredProviderId ?\n 'a valid ' + opt_requiredProviderId + ' credential' :\n 'a valid credential';\n return /** @type {!fireauth.args.Argument} */ ({\n name: name,\n typeLabel: typeLabel,\n optional: !!opt_optional,\n validator: /** @type {function(!fireauth.AuthCredential) : boolean} */ (\n function(credential) {\n if (!credential) {\n return false;\n }\n // If opt_requiredProviderId is set, make sure it matches the\n // credential's providerId.\n var matchesRequiredProvider = !opt_requiredProviderId ||\n (credential['providerId'] === opt_requiredProviderId);\n return !!(credential.getIdTokenProvider && matchesRequiredProvider);\n })\n });\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.MultiFactorAssertion\n * interface.\n * @param {?string=} requiredFactorId The required type of second factor.\n * @param {?string=} optionalName The name of the argument.\n * @param {?boolean=} optionalArg Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.multiFactorAssertion =\n function(requiredFactorId, optionalName, optionalArg) {\n var name = optionalName ||\n (requiredFactorId ?\n requiredFactorId + 'MultiFactorAssertion' : 'multiFactorAssertion');\n var typeLabel = requiredFactorId ?\n 'a valid ' + requiredFactorId + ' multiFactorAssertion' :\n 'a valid multiFactorAssertion';\n return /** @type {!fireauth.args.Argument} */ ({\n name: name,\n typeLabel: typeLabel,\n optional: !!optionalArg,\n validator:\n /** @type {function(!fireauth.MultiFactorAssertion) : boolean} */ (\n function(assertion) {\n if (!assertion) {\n return false;\n }\n // If requiredFactorId is set, make sure it matches the\n // assertion's factorId.\n var matchesRequiredFactor = !requiredFactorId ||\n (assertion['factorId'] === requiredFactorId);\n return !!(assertion.process && matchesRequiredFactor);\n })\n });\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.AuthProvider interface.\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.authProvider = function(opt_name, opt_optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: opt_name || 'authProvider',\n typeLabel: 'a valid Auth provider',\n optional: !!opt_optional,\n validator: /** @type {function(!fireauth.AuthProvider) : boolean} */ (\n function(provider) {\n return !!(provider &&\n provider['providerId'] &&\n provider.hasOwnProperty &&\n provider.hasOwnProperty('isOAuthProvider'));\n })\n });\n};\n\n\n/**\n * Specifies a phone info options argument.\n * @param {?string=} name The name of the argument.\n * @param {?boolean=} optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.phoneInfoOptions = function(name, optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: name || 'phoneInfoOptions',\n typeLabel: 'valid phone info options',\n optional: !!optional,\n validator: /** @type {function(!Object) : boolean} */ (\n function(phoneInfoOptions) {\n if (!phoneInfoOptions) {\n return false;\n }\n // For multi-factor enrollment, phone number and MFA session should\n // be provided.\n if (phoneInfoOptions['session'] &&\n phoneInfoOptions['phoneNumber']) {\n return fireauth.args.validateMultiFactorSession_(\n phoneInfoOptions['session'],\n fireauth.MultiFactorSession.Type.ENROLL) &&\n typeof phoneInfoOptions['phoneNumber'] === 'string';\n // For multi-factor sign-in, phone multi-factor hint and MFA session\n // are provided.\n } else if (phoneInfoOptions['session'] &&\n phoneInfoOptions['multiFactorHint']) {\n return fireauth.args.validateMultiFactorSession_(\n phoneInfoOptions['session'],\n fireauth.MultiFactorSession.Type.SIGN_IN) &&\n fireauth.args.validateMultiFactorInfo_(\n phoneInfoOptions['multiFactorHint']);\n // For multi-factor sign-in, phone multi-factor UID and MFA session\n // are provided.\n } else if (phoneInfoOptions['session'] &&\n phoneInfoOptions['multiFactorUid']) {\n return fireauth.args.validateMultiFactorSession_(\n phoneInfoOptions['session'],\n fireauth.MultiFactorSession.Type.SIGN_IN) &&\n typeof phoneInfoOptions['multiFactorUid'] === 'string';\n // For single-factor sign-in, only phone number needs to be provided.\n } else if (phoneInfoOptions['phoneNumber']) {\n return typeof phoneInfoOptions['phoneNumber'] === 'string';\n }\n return false;\n })\n });\n};\n\n\n/**\n * @param {*} session The multi-factor session object.\n * @param {!fireauth.MultiFactorSession.Type} type The session type.\n * @return {boolean} Whether the seesion is a valid multi-factor session.\n * @private\n */\nfireauth.args.validateMultiFactorSession_ = function(session, type) {\n return goog.isObject(session) && typeof session.type === 'string' &&\n session.type === type &&\n goog.isFunction(session.getRawSession);\n};\n\n\n/**\n * @param {*} info The multi-factor info object.\n * @return {boolean} Whether the info is a valid multi-factor info.\n * @private\n */\nfireauth.args.validateMultiFactorInfo_ = function(info) {\n return goog.isObject(info) && typeof info['uid'] === 'string';\n};\n\n\n/**\n * Specifies an argument that implements the fireauth.MultiFactorInfo\n * interface.\n * @param {?string=} name The name of the argument.\n * @param {?boolean=} optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.multiFactorInfo = function(name, optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: name || 'multiFactorInfo',\n typeLabel: 'a valid multiFactorInfo',\n optional: !!optional,\n validator: fireauth.args.validateMultiFactorInfo_\n });\n};\n\n\n/**\n * Specifies an argument that implements the firebase.auth.ApplicationVerifier\n * interface.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.applicationVerifier = function(opt_optional) {\n return /** @type {!fireauth.args.Argument} */ ({\n name: 'applicationVerifier',\n typeLabel: 'an implementation of firebase.auth.ApplicationVerifier',\n optional: !!opt_optional,\n validator:\n /** @type {function(!firebase.auth.ApplicationVerifier) : boolean} */ (\n function(applicationVerifier) {\n return !!(applicationVerifier &&\n typeof applicationVerifier.type === 'string' &&\n goog.isFunction(applicationVerifier.verify));\n })\n });\n};\n\n\n/**\n * Specifies an argument that can be either of two argument types.\n * @param {!fireauth.args.Argument} optionA\n * @param {!fireauth.args.Argument} optionB\n * @param {?string=} opt_name The name of the argument.\n * @param {?boolean=} opt_optional Whether or not this argument is optional.\n * Defaults to false.\n * @return {!fireauth.args.Argument}\n */\nfireauth.args.or = function(optionA, optionB, opt_name, opt_optional) {\n return {\n name: opt_name || '',\n typeLabel: optionA.typeLabel + ' or ' + optionB.typeLabel,\n optional: !!opt_optional,\n validator: function(value) {\n return optionA.validator(value) || optionB.validator(value);\n }\n };\n};\n\n\n/**\n * @param {string} str\n * @return {string} The string surrounded with quotes.\n * @private\n */\nfireauth.args.quoteString_ = function(str) {\n return '\"' + str + '\"';\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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 * @fileoverview Provides utilities for exporting public APIs, with error\n * checking.\n */\n\ngoog.provide('fireauth.exportlib');\ngoog.provide('fireauth.exportlib.ExportedMethod');\n\ngoog.require('fireauth.args');\n\n\n/**\n * Type constant for Firebase Auth.\n * @const {string}\n */\nfireauth.exportlib.AUTH_TYPE = 'auth';\n\n\n/**\n * Represents an exported method, with the exported name of the method and the\n * expected arguments to that method.\n * @typedef {{\n * name: string,\n * args: (Array<!fireauth.args.Argument>|null|undefined)\n * }}\n */\nfireauth.exportlib.ExportedMethod;\n\n\n/**\n * Represents an exported property, with the exported name of the property and\n * the expected argument to the setter of this property.\n * @typedef {{\n * name: string,\n * arg: !fireauth.args.Argument\n * }}\n */\nfireauth.exportlib.ExportedProperty;\n\n\n/**\n * Exports prototype methods of an object.\n * @param {!Object} protObj The prototype of an object.\n * @param {!Object<string, fireauth.exportlib.ExportedMethod>} fnMap The map of\n * prototype functions to their export name and expected arguments.\n */\nfireauth.exportlib.exportPrototypeMethods = function(protObj, fnMap) {\n // This method exports methods by aliasing the unobfuscated function name\n // (specified as a string in the \"name\" field of ExportedMethod) to the\n // obfuscated function name (specified as a key of the fnMap object).\n //\n // To give a concrete example, let's say that we have this method:\n // fireauth.Auth.prototype.fetchProvidersForEmail = function() { ... };\n //\n // In the exports file, we export as follows:\n // fireauth.exportlib.exportPrototypeMethods(fireauth.Auth.prototype, {\n // fetchProvidersForEmail: {name: 'fetchProvidersForEmail', args: ...}\n // });\n //\n // When the compiler obfuscates the code, the code above will become something\n // like this:\n // fireauth.Auth.prototype.qZ = function() { ... };\n // fireauth.exportlib.exportPrototypeMethods(fireauth.Auth.prototype, {\n // qZ: {name: 'fetchProvidersForEmail', args: ...}\n // });\n //\n // (Of course, fireauth.Auth and fireauth.exportlib.exportPrototypeMethods\n // would also be obfuscated). Note that the key in fnMap is obfuscated but the\n // \"name\" field in the ExportedMethod is not. Now, exportPrototypeMethods can\n // export fetchProvidersForEmail by reading the key (\"qZ\") and the \"name\"\n // field (\"fetchProvidersForEmail\") and essentially executing this:\n // fireauth.Auth.prototype['fetchProvidersForEmail'] =\n // fireauth.Auth.prototype['qZ'];\n for (var obfuscatedFnName in fnMap) {\n var unobfuscatedFnName = fnMap[obfuscatedFnName].name;\n protObj[unobfuscatedFnName] =\n fireauth.exportlib.wrapMethodWithArgumentVerifier_(\n unobfuscatedFnName, protObj[obfuscatedFnName],\n fnMap[obfuscatedFnName].args);\n }\n};\n\n\n/**\n * Exports properties of an object. See the docs for exportPrototypeMethods for\n * more information about how this works.\n * @param {!Object} protObj The prototype of an object.\n * @param {!Object<string, !fireauth.exportlib.ExportedProperty>} propMap The\n * map of properties to their export names.\n */\nfireauth.exportlib.exportPrototypeProperties = function(protObj, propMap) {\n for (var obfuscatedPropName in propMap) {\n var unobfuscatedPropName = propMap[obfuscatedPropName].name;\n // Don't alias a property to itself.\n // Downside is that argument validation will not be possible. For now, to\n // get around it, ensure unobfuscated property names are different\n // than the corresponding obfuscated property names.\n if (unobfuscatedPropName === obfuscatedPropName) {\n continue;\n }\n /**\n * @this {!Object}\n * @param {string} obfuscatedPropName The obfuscated property name.\n * @return {*} The value of the property.\n */\n var getter = function(obfuscatedPropName) {\n return this[obfuscatedPropName];\n };\n /**\n * @this {!Object}\n * @param {string} unobfuscatedPropName The unobfuscated property name.\n * @param {string} obfuscatedPropName The obfuscated property name.\n * @param {!fireauth.args.Argument} expectedArg The expected argument to the\n * setter of this property.\n * @param {*} value The new value of the property.\n */\n var setter = function(unobfuscatedPropName, obfuscatedPropName,\n expectedArg, value) {\n // Validate the argument before setting it.\n fireauth.args.validate(\n unobfuscatedPropName, [expectedArg], [value], true);\n this[obfuscatedPropName] = value;\n };\n // Get the expected argument.\n var expectedArg = propMap[obfuscatedPropName].arg;\n Object.defineProperty(protObj, unobfuscatedPropName, {\n /**\n * @this {!Object}\n * @return {*} The value of the property.\n */\n get: goog.partial(getter, obfuscatedPropName),\n /**\n * @this {!Object}\n * @param {*} value The new value of the property.\n */\n set: goog.partial(setter, unobfuscatedPropName, obfuscatedPropName,\n expectedArg),\n enumerable: true\n });\n }\n};\n\n\n/**\n * Export a static method as a public API.\n * @param {!Object} parentObj The parent object to patch.\n * @param {string} name The public name of the method.\n * @param {!Function} func The method.\n * @param {?Array<!fireauth.args.Argument>=} opt_expectedArgs The expected\n * arguments to the method.\n */\nfireauth.exportlib.exportFunction = function(parentObj, name, func,\n opt_expectedArgs) {\n parentObj[name] = fireauth.exportlib.wrapMethodWithArgumentVerifier_(\n name, func, opt_expectedArgs);\n};\n\n\n/**\n * Wraps a method with a function that first verifies the arguments to the\n * method and then calls the original method.\n * @param {string} methodName The name of the method, which will be displayed\n * on the error message if the arguments are not valid.\n * @param {!Function} method The method to be wrapped.\n * @param {?Array<!fireauth.args.Argument>=} opt_expectedArgs The expected\n * arguments.\n * @return {!Function} The wrapped method.\n * @private\n */\nfireauth.exportlib.wrapMethodWithArgumentVerifier_ = function(methodName,\n method, opt_expectedArgs) {\n if (!opt_expectedArgs) {\n return method;\n }\n var shortName = fireauth.exportlib.extractMethodNameFromFullPath_(methodName);\n var wrapper = function() {\n var argumentsAsArray = Array.prototype.slice.call(arguments);\n fireauth.args.validate(shortName,\n /** @type {!Array<!fireauth.args.Argument>} */ (opt_expectedArgs),\n argumentsAsArray);\n return method.apply(this, argumentsAsArray);\n };\n // Reattach all static stuff to wrapper.\n for (var key in method) {\n wrapper[key] = method[key];\n }\n // Reattach all prototype stuff to wrapper.\n for (var key in method.prototype) {\n wrapper.prototype[key] = method.prototype[key];\n }\n // Return wrapper with all of method's static and prototype methods and\n // properties.\n return wrapper;\n};\n\n\n/**\n * From a full path to a method (e.g. \"fireauth.GoogleAuthProvider.credential\"),\n * get just the method name (\"credential\").\n * @param {string} path The full path.\n * @return {string} The method name.\n * @private\n */\nfireauth.exportlib.extractMethodNameFromFullPath_ = function(path) {\n var parts = path.split('.');\n return parts[parts.length - 1];\n};\n","/**\n * @license\n * Copyright 2017 Google Inc.\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\ngoog.provide('fireauth.exports');\n\ngoog.require('fireauth.ActionCodeInfo');\ngoog.require('fireauth.ActionCodeURL');\ngoog.require('fireauth.Auth');\ngoog.require('fireauth.AuthCredential');\ngoog.require('fireauth.AuthError');\ngoog.require('fireauth.AuthErrorWithCredential');\ngoog.require('fireauth.AuthSettings');\ngoog.require('fireauth.AuthUser');\ngoog.require('fireauth.ConfirmationResult');\ngoog.require('fireauth.EmailAuthCredential');\ngoog.require('fireauth.EmailAuthProvider');\ngoog.require('fireauth.FacebookAuthProvider');\ngoog.require('fireauth.GRecaptchaMockFactory');\ngoog.require('fireauth.GithubAuthProvider');\ngoog.require('fireauth.GoogleAuthProvider');\ngoog.require('fireauth.InvalidOriginError');\ngoog.require('fireauth.MultiFactorError');\ngoog.require('fireauth.MultiFactorResolver');\ngoog.require('fireauth.MultiFactorUser');\ngoog.require('fireauth.OAuthCredential');\ngoog.require('fireauth.OAuthProvider');\ngoog.require('fireauth.PhoneAuthCredential');\ngoog.require('fireauth.PhoneAuthProvider');\ngoog.require('fireauth.PhoneMultiFactorGenerator');\ngoog.require('fireauth.RecaptchaVerifier');\ngoog.require('fireauth.SAMLAuthCredential');\ngoog.require('fireauth.SAMLAuthProvider');\ngoog.require('fireauth.TwitterAuthProvider');\ngoog.require('fireauth.args');\ngoog.require('fireauth.authStorage.Persistence');\ngoog.require('fireauth.exportlib');\ngoog.require('fireauth.grecaptcha');\ngoog.require('fireauth.idp.ProviderId');\ngoog.require('goog.Promise');\n\n/** @define {string} */\nconst AUTH_NPM_PACKAGE_VERSION = '';\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.Auth.prototype, {\n applyActionCode: {\n name: 'applyActionCode',\n args: [fireauth.args.string('code')]\n },\n checkActionCode: {\n name: 'checkActionCode',\n args: [fireauth.args.string('code')]\n },\n confirmPasswordReset: {\n name: 'confirmPasswordReset',\n args: [\n fireauth.args.string('code'),\n fireauth.args.string('newPassword')\n ]\n },\n createUserWithEmailAndPassword: {\n name: 'createUserWithEmailAndPassword',\n args: [fireauth.args.string('email'), fireauth.args.string('password')]\n },\n fetchSignInMethodsForEmail: {\n name: 'fetchSignInMethodsForEmail',\n args: [fireauth.args.string('email')]\n },\n getRedirectResult: {\n name: 'getRedirectResult',\n args: []\n },\n isSignInWithEmailLink: {\n name: 'isSignInWithEmailLink',\n args: [fireauth.args.string('emailLink')]\n },\n onAuthStateChanged: {\n name: 'onAuthStateChanged',\n args: [\n fireauth.args.or(\n fireauth.args.object(),\n fireauth.args.func(),\n 'nextOrObserver'),\n fireauth.args.func('opt_error', true),\n fireauth.args.func('opt_completed', true)\n ]\n },\n onIdTokenChanged: {\n name: 'onIdTokenChanged',\n args: [\n fireauth.args.or(\n fireauth.args.object(),\n fireauth.args.func(),\n 'nextOrObserver'),\n fireauth.args.func('opt_error', true),\n fireauth.args.func('opt_completed', true)\n ]\n },\n sendPasswordResetEmail: {\n name: 'sendPasswordResetEmail',\n args: [\n fireauth.args.string('email'),\n fireauth.args.or(\n fireauth.args.object('opt_actionCodeSettings', true),\n fireauth.args.null(null, true),\n 'opt_actionCodeSettings',\n true)\n ]\n },\n sendSignInLinkToEmail: {\n name: 'sendSignInLinkToEmail',\n args: [\n fireauth.args.string('email'),\n fireauth.args.object('actionCodeSettings')\n ]\n },\n setPersistence: {\n name: 'setPersistence',\n args: [fireauth.args.string('persistence')]\n },\n signInAndRetrieveDataWithCredential: {\n name: 'signInAndRetrieveDataWithCredential',\n args: [fireauth.args.authCredential()]\n },\n signInAnonymously: {\n name: 'signInAnonymously',\n args: []\n },\n signInWithCredential: {\n name: 'signInWithCredential',\n args: [fireauth.args.authCredential()]\n },\n signInWithCustomToken: {\n name: 'signInWithCustomToken',\n args: [fireauth.args.string('token')]\n },\n signInWithEmailAndPassword: {\n name: 'signInWithEmailAndPassword',\n args: [fireauth.args.string('email'), fireauth.args.string('password')]\n },\n signInWithEmailLink: {\n name: 'signInWithEmailLink',\n args: [\n fireauth.args.string('email'), fireauth.args.string('emailLink', true)\n ]\n },\n signInWithPhoneNumber: {\n name: 'signInWithPhoneNumber',\n args: [\n fireauth.args.string('phoneNumber'),\n fireauth.args.applicationVerifier()\n ]\n },\n signInWithPopup: {\n name: 'signInWithPopup',\n args: [fireauth.args.authProvider()]\n },\n signInWithRedirect: {\n name: 'signInWithRedirect',\n args: [fireauth.args.authProvider()]\n },\n updateCurrentUser: {\n name: 'updateCurrentUser',\n args: [\n fireauth.args.or(\n fireauth.args.firebaseUser(),\n fireauth.args.null(),\n 'user')\n ]\n },\n signOut: {\n name: 'signOut',\n args: []\n },\n toJSON: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n },\n useDeviceLanguage: {\n name: 'useDeviceLanguage',\n args: []\n },\n verifyPasswordResetCode: {\n name: 'verifyPasswordResetCode',\n args: [fireauth.args.string('code')]\n }\n });\n\nfireauth.exportlib.exportPrototypeProperties(\n fireauth.Auth.prototype, {\n 'lc': {\n name: 'languageCode',\n arg: fireauth.args.or(\n fireauth.args.string(),\n fireauth.args.null(),\n 'languageCode')\n },\n 'ti': {\n name: 'tenantId',\n arg: fireauth.args.or(\n fireauth.args.string(),\n fireauth.args.null(),\n 'tenantId')\n }\n });\n\n// Exports firebase.auth.Auth.Persistence.\nfireauth.Auth['Persistence'] = fireauth.authStorage.Persistence;\nfireauth.Auth['Persistence']['LOCAL'] = fireauth.authStorage.Persistence.LOCAL;\nfireauth.Auth['Persistence']['SESSION'] =\n fireauth.authStorage.Persistence.SESSION;\nfireauth.Auth['Persistence']['NONE'] = fireauth.authStorage.Persistence.NONE;\n\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.AuthUser.prototype, {\n 'delete': {\n name: 'delete',\n args: []\n },\n getIdTokenResult: {\n name: 'getIdTokenResult',\n args: [fireauth.args.bool('opt_forceRefresh', true)]\n },\n getIdToken: {\n name: 'getIdToken',\n args: [fireauth.args.bool('opt_forceRefresh', true)]\n },\n linkAndRetrieveDataWithCredential: {\n name: 'linkAndRetrieveDataWithCredential',\n args: [fireauth.args.authCredential()]\n },\n linkWithCredential: {\n name: 'linkWithCredential',\n args: [fireauth.args.authCredential()]\n },\n linkWithPhoneNumber: {\n name: 'linkWithPhoneNumber',\n args: [\n fireauth.args.string('phoneNumber'),\n fireauth.args.applicationVerifier()\n ]\n },\n linkWithPopup: {\n name: 'linkWithPopup',\n args: [fireauth.args.authProvider()]\n },\n linkWithRedirect: {\n name: 'linkWithRedirect',\n args: [fireauth.args.authProvider()]\n },\n reauthenticateAndRetrieveDataWithCredential: {\n name: 'reauthenticateAndRetrieveDataWithCredential',\n args: [fireauth.args.authCredential()]\n },\n reauthenticateWithCredential: {\n name: 'reauthenticateWithCredential',\n args: [fireauth.args.authCredential()]\n },\n reauthenticateWithPhoneNumber: {\n name: 'reauthenticateWithPhoneNumber',\n args: [\n fireauth.args.string('phoneNumber'),\n fireauth.args.applicationVerifier()\n ]\n },\n reauthenticateWithPopup: {\n name: 'reauthenticateWithPopup',\n args: [fireauth.args.authProvider()]\n },\n reauthenticateWithRedirect: {\n name: 'reauthenticateWithRedirect',\n args: [fireauth.args.authProvider()]\n },\n reload: {\n name: 'reload',\n args: []\n },\n sendEmailVerification: {\n name: 'sendEmailVerification',\n args: [\n fireauth.args.or(\n fireauth.args.object('opt_actionCodeSettings', true),\n fireauth.args.null(null, true),\n 'opt_actionCodeSettings',\n true)\n ]\n },\n toJSON: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n },\n unlink: {\n name: 'unlink',\n args: [fireauth.args.string('provider')]\n },\n updateEmail: {\n name: 'updateEmail',\n args: [fireauth.args.string('email')]\n },\n updatePassword: {\n name: 'updatePassword',\n args: [fireauth.args.string('password')]\n },\n updatePhoneNumber: {\n name: 'updatePhoneNumber',\n args: [fireauth.args.authCredential(fireauth.idp.ProviderId.PHONE)]\n },\n updateProfile: {\n name: 'updateProfile',\n args: [fireauth.args.object('profile')]\n },\n verifyBeforeUpdateEmail: {\n name: 'verifyBeforeUpdateEmail',\n args: [\n fireauth.args.string('email'),\n fireauth.args.or(\n fireauth.args.object('opt_actionCodeSettings', true),\n fireauth.args.null(null, true),\n 'opt_actionCodeSettings',\n true)\n ]\n }\n });\n\n// Ensure internal grecaptcha mock API do not get obfuscated.\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.GRecaptchaMockFactory.prototype, {\n execute: {\n name: 'execute'\n },\n render: {\n name: 'render'\n },\n reset: {\n name: 'reset'\n },\n getResponse: {\n name: 'getResponse'\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.grecaptcha.prototype, {\n execute: {\n name: 'execute'\n },\n render: {\n name: 'render'\n },\n reset: {\n name: 'reset'\n },\n getResponse: {\n name: 'getResponse'\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n goog.Promise.prototype, {\n thenAlways: {\n name: 'finally'\n },\n thenCatch: {\n name: 'catch'\n },\n then: {\n name: 'then'\n }\n });\n\nfireauth.exportlib.exportPrototypeProperties(\n fireauth.AuthSettings.prototype, {\n 'appVerificationDisabled': {\n name: 'appVerificationDisabledForTesting',\n arg: fireauth.args.bool('appVerificationDisabledForTesting')\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.ConfirmationResult.prototype, {\n confirm: {\n name: 'confirm',\n args: [\n fireauth.args.string('verificationCode')\n ]\n }\n });\n\nfireauth.exportlib.exportFunction(\n fireauth.AuthCredential, 'fromJSON',\n fireauth.AuthCredential.fromPlainObject, [\n fireauth.args.or(fireauth.args.string(), fireauth.args.object(), 'json')\n ]);\n\nfireauth.exportlib.exportFunction(\n fireauth.EmailAuthProvider, 'credential',\n fireauth.EmailAuthProvider.credential, [\n fireauth.args.string('email'),\n fireauth.args.string('password')\n ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.EmailAuthCredential.prototype, {\n toPlainObject: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.FacebookAuthProvider.prototype, {\n addScope: {\n name: 'addScope',\n args: [fireauth.args.string('scope')]\n },\n setCustomParameters: {\n name: 'setCustomParameters',\n args: [fireauth.args.object('customOAuthParameters')]\n }\n });\nfireauth.exportlib.exportFunction(\n fireauth.FacebookAuthProvider, 'credential',\n fireauth.FacebookAuthProvider.credential, [\n fireauth.args.or(fireauth.args.string(), fireauth.args.object(),\n 'token')\n ]);\nfireauth.exportlib.exportFunction(\n fireauth.EmailAuthProvider, 'credentialWithLink',\n fireauth.EmailAuthProvider.credentialWithLink, [\n fireauth.args.string('email'),\n fireauth.args.string('emailLink')\n ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.GithubAuthProvider.prototype, {\n addScope: {\n name: 'addScope',\n args: [fireauth.args.string('scope')]\n },\n setCustomParameters: {\n name: 'setCustomParameters',\n args: [fireauth.args.object('customOAuthParameters')]\n }\n });\nfireauth.exportlib.exportFunction(\n fireauth.GithubAuthProvider, 'credential',\n fireauth.GithubAuthProvider.credential, [\n fireauth.args.or(fireauth.args.string(), fireauth.args.object(),\n 'token')\n ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.GoogleAuthProvider.prototype, {\n addScope: {\n name: 'addScope',\n args: [fireauth.args.string('scope')]\n },\n setCustomParameters: {\n name: 'setCustomParameters',\n args: [fireauth.args.object('customOAuthParameters')]\n }\n });\nfireauth.exportlib.exportFunction(\n fireauth.GoogleAuthProvider, 'credential',\n fireauth.GoogleAuthProvider.credential, [\n fireauth.args.or(fireauth.args.string(),\n fireauth.args.or(fireauth.args.object(), fireauth.args.null()),\n 'idToken'),\n fireauth.args.or(fireauth.args.string(), fireauth.args.null(),\n 'accessToken', true)\n ]);\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.TwitterAuthProvider.prototype, {\n setCustomParameters: {\n name: 'setCustomParameters',\n args: [fireauth.args.object('customOAuthParameters')]\n }\n });\nfireauth.exportlib.exportFunction(\n fireauth.TwitterAuthProvider, 'credential',\n fireauth.TwitterAuthProvider.credential, [\n fireauth.args.or(fireauth.args.string(), fireauth.args.object(),\n 'token'),\n fireauth.args.string('secret', true)\n ]);\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.OAuthProvider.prototype, {\n addScope: {\n name: 'addScope',\n args: [fireauth.args.string('scope')]\n },\n credential: {\n name: 'credential',\n args: [\n fireauth.args.or(\n fireauth.args.string(),\n fireauth.args.or(fireauth.args.object(), fireauth.args.null()),\n 'optionsOrIdToken'),\n fireauth.args.or(fireauth.args.string(), fireauth.args.null(),\n 'accessToken', true)\n ]\n },\n setCustomParameters: {\n name: 'setCustomParameters',\n args: [fireauth.args.object('customOAuthParameters')]\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.OAuthCredential.prototype, {\n toPlainObject: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.SAMLAuthCredential.prototype, {\n toPlainObject: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\n\nfireauth.exportlib.exportFunction(\n fireauth.PhoneAuthProvider, 'credential',\n fireauth.PhoneAuthProvider.credential, [\n fireauth.args.string('verificationId'),\n fireauth.args.string('verificationCode')\n ]);\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.PhoneAuthProvider.prototype, {\n verifyPhoneNumber: {\n name: 'verifyPhoneNumber',\n args: [\n fireauth.args.or(\n fireauth.args.string(),\n fireauth.args.phoneInfoOptions(),\n 'phoneInfoOptions'),\n fireauth.args.applicationVerifier()\n ]\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.PhoneAuthCredential.prototype, {\n toPlainObject: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.AuthError.prototype, {\n toJSON: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.AuthErrorWithCredential.prototype, {\n toJSON: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.InvalidOriginError.prototype, {\n toJSON: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.MultiFactorError.prototype, {\n toJSON: {\n name: 'toJSON',\n // This shouldn't take an argument but a blank string is being passed\n // on JSON.stringify and causing this to fail with an argument error.\n // So allow an optional string.\n args: [fireauth.args.string(null, true)]\n }\n });\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.MultiFactorResolver.prototype, {\n resolveSignIn: {\n name: 'resolveSignIn',\n args: [fireauth.args.multiFactorAssertion()]\n }\n });\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.MultiFactorUser.prototype, {\n getSession: {\n name: 'getSession',\n args: []\n },\n enroll: {\n name: 'enroll',\n args: [\n fireauth.args.multiFactorAssertion(),\n fireauth.args.string('displayName', true)\n ]\n },\n unenroll: {\n name: 'unenroll',\n args: [\n fireauth.args.or(\n fireauth.args.multiFactorInfo(),\n fireauth.args.string(),\n 'multiFactorInfoIdentifier')\n ]\n }\n });\n\nfireauth.exportlib.exportPrototypeMethods(\n fireauth.RecaptchaVerifier.prototype, {\n clear: {\n name: 'clear',\n args: []\n },\n render: {\n name: 'render',\n args: []\n },\n verify: {\n name: 'verify',\n args: []\n }\n });\n\nfireauth.exportlib.exportFunction(\n fireauth.ActionCodeURL, 'parseLink',\n fireauth.ActionCodeURL.parseLink, [fireauth.args.string('link')]);\n\nfireauth.exportlib.exportFunction(\n fireauth.PhoneMultiFactorGenerator, 'assertion',\n fireauth.PhoneMultiFactorGenerator.assertion,\n [fireauth.args.authCredential(fireauth.idp.ProviderId.PHONE)]);\n\n\n(function() {\n if (typeof firebase === 'undefined' || !firebase.INTERNAL ||\n !firebase.INTERNAL.registerComponent) {\n throw new Error('Cannot find the firebase namespace; be sure to include ' +\n 'firebase-app.js before this library.');\n } else {\n var namespace = {\n // Exports firebase.auth.ActionCodeInfo.Operation.\n 'ActionCodeInfo': {\n 'Operation': {\n 'EMAIL_SIGNIN': fireauth.ActionCodeInfo.Operation.EMAIL_SIGNIN,\n 'PASSWORD_RESET': fireauth.ActionCodeInfo.Operation.PASSWORD_RESET,\n 'RECOVER_EMAIL': fireauth.ActionCodeInfo.Operation.RECOVER_EMAIL,\n 'REVERT_SECOND_FACTOR_ADDITION':\n fireauth.ActionCodeInfo.Operation.REVERT_SECOND_FACTOR_ADDITION,\n 'VERIFY_AND_CHANGE_EMAIL':\n fireauth.ActionCodeInfo.Operation.VERIFY_AND_CHANGE_EMAIL,\n 'VERIFY_EMAIL': fireauth.ActionCodeInfo.Operation.VERIFY_EMAIL\n }\n },\n 'Auth': fireauth.Auth,\n 'AuthCredential': fireauth.AuthCredential,\n 'Error': fireauth.AuthError\n };\n fireauth.exportlib.exportFunction(namespace,\n 'EmailAuthProvider', fireauth.EmailAuthProvider, []);\n fireauth.exportlib.exportFunction(namespace,\n 'FacebookAuthProvider', fireauth.FacebookAuthProvider, []);\n fireauth.exportlib.exportFunction(namespace,\n 'GithubAuthProvider', fireauth.GithubAuthProvider, []);\n fireauth.exportlib.exportFunction(namespace,\n 'GoogleAuthProvider', fireauth.GoogleAuthProvider, []);\n fireauth.exportlib.exportFunction(namespace,\n 'TwitterAuthProvider', fireauth.TwitterAuthProvider, []);\n fireauth.exportlib.exportFunction(namespace,\n 'OAuthProvider', fireauth.OAuthProvider, [\n fireauth.args.string('providerId')\n ]);\n fireauth.exportlib.exportFunction(namespace,\n 'SAMLAuthProvider', fireauth.SAMLAuthProvider, [\n fireauth.args.string('providerId')\n ]);\n fireauth.exportlib.exportFunction(namespace,\n 'PhoneAuthProvider', fireauth.PhoneAuthProvider, [\n fireauth.args.firebaseAuth(true)\n ]);\n fireauth.exportlib.exportFunction(namespace,\n 'RecaptchaVerifier', fireauth.RecaptchaVerifier, [\n fireauth.args.or(\n fireauth.args.string(),\n fireauth.args.element(),\n 'recaptchaContainer'),\n fireauth.args.object('recaptchaParameters', true),\n fireauth.args.firebaseApp(true)\n ]);\n fireauth.exportlib.exportFunction(namespace,\n 'ActionCodeURL', fireauth.ActionCodeURL, []);\n fireauth.exportlib.exportFunction(namespace,\n 'PhoneMultiFactorGenerator', fireauth.PhoneMultiFactorGenerator, []);\n\n // Create auth components to register with firebase.\n // Provides Auth public APIs.\n const authComponent = { \n 'name': fireauth.exportlib.AUTH_TYPE,\n 'instanceFactory': function(container) {\n var app = container['getProvider']('app')['getImmediate']();\n return new fireauth.Auth(app);\n },\n 'multipleInstances': false,\n 'serviceProps': namespace,\n 'instantiationMode': 'LAZY',\n 'type': 'PUBLIC'\n };\n \n // Provides Auth internal APIs.\n const authInteropComponent = { \n 'name': 'auth-internal',\n 'instanceFactory': function(container) {\n var auth = container['getProvider'](fireauth.exportlib.AUTH_TYPE)['getImmediate']();\n return {\n 'getUid': goog.bind(auth.getUid, auth),\n 'getToken': goog.bind(auth.getIdTokenInternal, auth),\n 'addAuthTokenListener':\n goog.bind(auth.addAuthTokenListenerInternal, auth),\n 'removeAuthTokenListener':\n goog.bind(auth.removeAuthTokenListenerInternal, auth)\n };\n },\n 'multipleInstances': false,\n 'instantiationMode': 'LAZY',\n 'type': 'PRIVATE'\n };\n \n firebase.INTERNAL.registerComponent(authComponent);\n firebase.INTERNAL.registerComponent(authInteropComponent);\n firebase.registerVersion('@firebase/auth', AUTH_NPM_PACKAGE_VERSION);\n\n // Expose User as firebase.User.\n firebase.INTERNAL.extendNamespace({\n 'User': fireauth.AuthUser\n });\n }\n})();"]} |