{"version":3,"sources":["webpack:///firebase-app.js","webpack:/webpack/bootstrap 8ab15b975f62acbe3906","webpack:///src/utils/promise.ts","webpack:///src/app/firebase_app.ts","webpack:///src/app.ts","webpack:///src/app/errors.ts","webpack:///src/app/subscribe.ts","webpack:///src/utils/globalScope.ts","webpack:///(webpack)/buildin/global.js","webpack:///node_modules/process/browser.js","webpack:///src/utils/deep_copy.ts","webpack:///node_modules/promise-polyfill/promise.js","webpack:///node_modules/timers-browserify/main.js","webpack:///node_modules/setimmediate/setImmediate.js","firebase-auth.js","webpack:///firebase-database.js","webpack:///src/utils/assert.ts","webpack:///src/utils/crypt.ts","webpack:///src/utils/hash.ts","webpack:///src/utils/Sha1.ts","webpack:///src/database/core/util/util.ts","webpack:///src/utils/obj.ts","webpack:///src/utils/json.ts","webpack:///src/utils/environment.ts","webpack:///src/utils/constants.ts","webpack:///src/database/core/storage/DOMStorageWrapper.ts","webpack:///src/database/core/storage/MemoryStorage.ts","webpack:///src/database/core/storage/storage.ts","webpack:///src/database/realtime/Constants.ts","webpack:///src/utils/utf8.ts","webpack:///src/database/core/stats/StatsCollection.ts","webpack:///src/database/core/stats/StatsManager.ts","webpack:///src/database/realtime/WebSocketConnection.ts","webpack:///src/database/core/util/libs/parser.ts","webpack:///src/utils/validation.ts","webpack:///src/database/core/snap/comparators.ts","webpack:///src/database/core/snap/nodeFromJSON.ts","webpack:///src/database/core/snap/indexes/KeyIndex.ts","webpack:///src/database/core/snap/snap.ts","webpack:///src/database/core/snap/LeafNode.ts","webpack:///src/database/core/util/Path.ts","webpack:///src/database/core/RepoInfo.ts","webpack:///src/database/core/util/validation.ts","webpack:///src/database/api/onDisconnect.ts","webpack:///src/database/api/TransactionResult.ts","webpack:///src/database/core/util/NextPushId.ts","webpack:///src/database/core/snap/Node.ts","webpack:///src/database/core/snap/indexes/Index.ts","webpack:///src/database/core/snap/indexes/PriorityIndex.ts","webpack:///src/database/core/util/SortedMap.ts","webpack:///src/database/core/snap/childSet.ts","webpack:///src/database/core/snap/IndexMap.ts","webpack:///src/database/core/snap/ChildrenNode.ts","webpack:///src/database/core/snap/indexes/ValueIndex.ts","webpack:///src/database/api/Query.ts","webpack:///src/database/core/operation/Operation.ts","webpack:///src/database/core/snap/indexes/PathIndex.ts","webpack:///src/database/api/DataSnapshot.ts","webpack:///src/database/core/view/Event.ts","webpack:///src/database/core/view/EventRegistration.ts","webpack:///src/database/core/util/CountedSet.ts","webpack:///src/database/core/SparseSnapshotTree.ts","webpack:///src/database/core/util/ServerValues.ts","webpack:///src/database/core/operation/AckUserWrite.ts","webpack:///src/database/core/util/ImmutableTree.ts","webpack:///src/database/core/operation/ListenComplete.ts","webpack:///src/database/core/operation/Overwrite.ts","webpack:///src/database/core/operation/Merge.ts","webpack:///src/database/core/view/CacheNode.ts","webpack:///src/database/core/view/ViewCache.ts","webpack:///src/database/core/view/Change.ts","webpack:///src/database/core/view/filter/IndexedFilter.ts","webpack:///src/database/core/SyncPoint.ts","webpack:///src/database/core/view/ChildChangeAccumulator.ts","webpack:///src/database/core/view/CompleteChildSource.ts","webpack:///src/database/core/view/ViewProcessor.ts","webpack:///src/database/core/view/EventGenerator.ts","webpack:///src/database/core/view/View.ts","webpack:///src/database/core/CompoundWrite.ts","webpack:///src/database/core/WriteTree.ts","webpack:///src/database/core/SyncTree.ts","webpack:///src/database/core/SnapshotHolder.ts","webpack:///src/database/core/AuthTokenProvider.ts","webpack:///src/database/core/stats/StatsListener.ts","webpack:///src/database/core/stats/StatsReporter.ts","webpack:///src/database/core/view/EventQueue.ts","webpack:///src/database/core/util/EventEmitter.ts","webpack:///src/database/core/util/VisibilityMonitor.ts","webpack:///src/database/core/util/OnlineMonitor.ts","webpack:///src/utils/jwt.ts","webpack:///src/database/realtime/polling/PacketReceiver.ts","webpack:///src/database/realtime/BrowserPollConnection.ts","webpack:///src/database/realtime/TransportManager.ts","webpack:///src/database/realtime/Connection.ts","webpack:///src/database/core/ServerActions.ts","webpack:///src/database/core/PersistentConnection.ts","webpack:///src/utils/util.ts","webpack:///src/database/core/ReadonlyRestClient.ts","webpack:///src/database/core/Repo.ts","webpack:///src/database/core/view/filter/RangedFilter.ts","webpack:///src/database/core/view/filter/LimitedFilter.ts","webpack:///src/database/core/view/QueryParams.ts","webpack:///src/database/api/Reference.ts","webpack:///src/database/core/Repo_transaction.ts","webpack:///src/database/core/util/Tree.ts","webpack:///src/database/core/RepoManager.ts","webpack:///src/database/api/Database.ts","webpack:///src/database/api/internal.ts","webpack:///src/database/api/test_access.ts","webpack:///src/database.ts","webpack:///(webpack)/buildin/harmony-module.js","webpack:///firebase-messaging.js","webpack:///src/messaging/helpers/array-buffer-to-base64.ts","webpack:///src/messaging.ts","webpack:///src/messaging/models/errors.ts","webpack:///src/messaging/models/fcm-details.ts","webpack:///src/messaging/models/token-manager.ts","webpack:///src/messaging/controllers/controller-interface.ts","webpack:///src/messaging/models/worker-page-message.ts","webpack:///src/messaging/models/default-sw.ts","webpack:///src/messaging/controllers/window-controller.ts","webpack:///src/messaging/controllers/sw-controller.ts","webpack:///firebase-storage.js","webpack:///src/storage/implementation/error.ts","webpack:///src/storage/implementation/string.ts","webpack:///src/storage/implementation/taskenums.ts","webpack:///src/storage/implementation/object.ts","webpack:///src/storage/implementation/promise_external.ts","webpack:///src/storage/implementation/type.ts","webpack:///src/storage/implementation/json.ts","webpack:///src/storage/implementation/path.ts","webpack:///src/storage/implementation/url.ts","webpack:///src/storage/implementation/metadata.ts","webpack:///src/storage/implementation/args.ts","webpack:///src/storage/implementation/fs.ts","webpack:///src/storage/implementation/array.ts","webpack:///src/storage/implementation/requests.ts","webpack:///src/storage/implementation/async.ts","webpack:///src/storage/implementation/backoff.ts","webpack:///src/storage/implementation/request.ts","webpack:///src/storage.ts","webpack:///src/storage/implementation/constants.ts","webpack:///src/storage/implementation/xhrio.ts","webpack:///src/storage/implementation/xhrio_network.ts","webpack:///src/storage/implementation/xhriopool.ts","webpack:///src/storage/implementation/location.ts","webpack:///src/storage/implementation/blob.ts","webpack:///src/storage/implementation/requestinfo.ts","webpack:///src/storage/implementation/observer.ts","webpack:///src/storage/tasksnapshot.ts","webpack:///src/storage/task.ts","webpack:///src/storage/reference.ts","webpack:///src/storage/implementation/failrequest.ts","webpack:///src/storage/implementation/requestmap.ts","webpack:///src/storage/implementation/authwrapper.ts","webpack:///src/storage/service.ts"],"names":["firebase","window","self","modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","parentJsonpFunction","chunkIds","moreModules","executeModules","chunkId","result","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","shift","s","3","e","onScriptComplete","script","onerror","onload","clearTimeout","timeout","chunk","Error","undefined","installedChunkData","Promise","resolve","promise","reject","head","document","getElementsByTagName","createElement","type","charset","async","nc","setAttribute","src","p","setTimeout","appendChild","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","oe","err","console","error","__webpack_exports__","PromiseImpl","Deferred","attachDummyErrorHandler","__WEBPACK_IMPORTED_MODULE_0__utils_globalScope__","this","wrapCallback","opt_nodeCallback","meta","opt_value","catch","createFirebaseNamespace","removeApp","callAppHooks","apps_","app","DEFAULT_ENTRY_NAME","contains","initializeApp","options","FirebaseAppImpl","namespace","getApps","keys","map","registerService","createService","serviceProperties","appHook","allowMultipleInstances","factories","appHooks","forEach","serviceNamespace","appArg","__WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__","args","_i","arguments","_getService","bind","apply","extendNamespace","props","eventName","serviceName","factoryName","useAsService","useService","apps","__WEBPACK_IMPORTED_MODULE_2__utils_promise__","SDK_VERSION","INTERNAL","createSubscribe","__WEBPACK_IMPORTED_MODULE_0__subscribe__","ErrorFactory","__WEBPACK_IMPORTED_MODULE_1__errors__","deepExtend","code","appErrors","create","value","obj","key","tokenListeners","firebase_","isDeleted_","services_","name_","options_","getUid","getToken","addAuthTokenListener","callback","removeAuthTokenListener","filter","listener","checkDestroyed_","delete","_this","then","services","serviceKey","instanceKey","all","service","instanceIdentifier","instanceSpecifier","extendApp","log","errors","no-app","bad-app-name","duplicate-app","app-deleted","duplicate-service","sa-not-supported","invalid-app-argument","ERROR_NAME","captureStackTrace","FirebaseError","message","err_1","stack","constructor","pattern","data","template","fullCode","replace","match","prop","slice","executor","onNoObservers","proxy","ObserverProxy","subscribe","implementsAnyMethods","methods","_typeof","methods_1","method","noop","__WEBPACK_IMPORTED_MODULE_0__utils_promise__","Symbol","iterator","observers","unsubscribes","observerCount","task","finalized","next","forEachObserver","observer","close","complete","nextOrObserver","unsub","unsubscribeOne","finalError","fn","sendOne","global","globalScope","scope","Function","g","eval","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","runClearTimeout","marker","cachedClearTimeout","cleanUpNextTick","draining","currentQueue","queue","concat","queueIndex","drainQueue","len","run","Item","array","process","nextTick","Array","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","binding","cwd","chdir","dir","umask","deepCopy","target","source","Date","dateValue","getTime","patchProperty","setImmediate","root","thisArg","TypeError","_state","_handled","_value","_deferreds","doResolve","handle","deferred","_immediateFn","cb","onFulfilled","onRejected","ret","newValue","finale","_unhandledRejectionFn","Handler","done","reason","ex","setTimeoutFunc","prom","arr","res","val","remaining","race","values","warn","_setImmediateFn","_setUnhandledRejectionFn","Timeout","id","clearFn","_id","_clearFn","setInterval","clearInterval","unref","ref","enroll","item","msecs","_idleTimeoutId","_idleTimeout","unenroll","_unrefActive","active","_onTimeout","clearImmediate","tasksByHandle","nextHandle","registerImmediate","runIfPresent","currentlyRunningATask","doc","attachTo","getPrototypeOf","toString","postMessage","importScripts","postMessageIsAsynchronous","oldOnMessage","onmessage","messagePrefix","Math","random","onGlobalMessage","event","indexOf","addEventListener","attachEvent","MessageChannel","channel","port1","port2","html","documentElement","onreadystatechange","removeChild","default","webpackJsonpFirebase","assert","assertionError","__WEBPACK_IMPORTED_MODULE_0__constants__","assertion","__WEBPACK_IMPORTED_MODULE_0__globalScope__","stringToByteArray","str","output","charCodeAt","byteArrayToString","bytes","String","fromCharCode","base64","_","S","T","N","ENCODED_VALS_BASE","ENCODED_VALS","ENCODED_VALS_WEBSAFE","HAS_NATIVE_SUPPORT","atob","encodeByteArray","input","opt_webSafe","isArray","init_","byteToCharMap","byteToCharMapWebSafe_","byteToCharMap_","byte1","haveByte2","byte2","haveByte3","byte3","outByte1","outByte2","outByte3","outByte4","join","encodeString","btoa","decodeString","decodeStringToByteArray","charToByteMap","charToByteMapWebSafe_","charToByteMap_","charAt","haveByte4","byte4","I","Hash","blockSize","__extends","extendStatics","setPrototypeOf","__proto__","b","__","Sha1","_super","chain_","buf_","W_","pad_","inbuf_","total_","reset","compress_","buf","opt_offset","W","t","f","k","a","update","opt_length","lengthMinusBlock","inbuf","digest","totalBits","j","LUIDGenerator","util_base64Encode","util_base64Decode","util_sha1","logger","enableLogging","logWrapper","fatal","warnIfPageIsSecure","isInvalidJSONNumber","executeWhenDOMReady","MIN_NAME","MAX_NAME","nameCompare","stringCompare","requireKey","ObjectToUniqueKey","splitStringBySize","each","doubleToIEEE754String","isChromeExtensionContentScript","isWindowsStoreApp","errorForServerCode","exceptionGuard","beingCrawled","setTimeoutNonBlocking","BufferImpl","__WEBPACK_IMPORTED_MODULE_0__utils_assert__","__WEBPACK_IMPORTED_MODULE_1__utils_obj__","__WEBPACK_IMPORTED_MODULE_4__utils_utf8__","__WEBPACK_IMPORTED_MODULE_5__utils_json__","__WEBPACK_IMPORTED_MODULE_6__storage_storage__","__WEBPACK_IMPORTED_MODULE_7__utils_environment__","utf8Bytes","sha1","sha1Bytes","buildLogMessage_","var_args","firstLog_","logger_","persistent","set","remove","prefix","location","protocol","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","readyState","called_1","wrappedFn_1","body","floor","aAsInt","tryParseInt","bAsInt","sort","segsize","dataSegs","substring","v","ln","bits","abs","pow","min","LN2","round","reverse","hexByteString","hexByte","parseInt","substr","toLowerCase","test","href","Windows","UI","query","path","toUpperCase","INTEGER_REGEXP_","RegExp","intVal","search","time","safeGet","clone","isEmpty","getCount","findKey","findValue","getAnyKey","getValues","every","extend","objTo","objFrom","rv","opt_obj","opt_this","jsonEval","stringify","JSON","parse","isMobileCordova","isReactNative","isNodeSdk","getUA","navigator","NODE_CLIENT","NODE_ADMIN","CONSTANTS","__WEBPACK_IMPORTED_MODULE_0__utils_json__","DOMStorageWrapper","domStorage_","prefix_","removeItem","prefixedName_","setItem","storedVal","getItem","__WEBPACK_IMPORTED_MODULE_0__utils_obj__","MemoryStorage","cache_","isInMemoryStorage","PersistentStorage","SessionStorage","storage_createStoragefor","domStorageName","domStorage","PROTOCOL_VERSION","VERSION_PARAM","TRANSPORT_SESSION_PARAM","REFERER_PARAM","FORGE_REF","FORGE_DOMAIN","LAST_SESSION_PARAM","WEBSOCKET","LONG_POLLING","stringLength","__WEBPACK_IMPORTED_MODULE_0__assert__","out","high","__WEBPACK_IMPORTED_MODULE_0__utils_deep_copy__","StatsCollection","counters_","incrementCounter","amount","StatsManager_StatsManager","StatsManager","getCollection","repoInfo","hashString","collections_","getOrCreateReporter","creatorFunction","reporters_","WebSocketConnection","__WEBPACK_IMPORTED_MODULE_0__app__","__WEBPACK_IMPORTED_MODULE_1__utils_assert__","__WEBPACK_IMPORTED_MODULE_2__core_util_util__","__WEBPACK_IMPORTED_MODULE_3__core_stats_StatsManager__","__WEBPACK_IMPORTED_MODULE_4__Constants__","__WEBPACK_IMPORTED_MODULE_5__utils_constants__","__WEBPACK_IMPORTED_MODULE_6__core_storage_storage__","__WEBPACK_IMPORTED_MODULE_7__utils_json__","__WEBPACK_IMPORTED_MODULE_8__utils_environment__","WebSocketImpl","MozWebSocket","WebSocket","connId","transportSessionId","lastSessionId","keepaliveTimer","frames","totalFrames","bytesSent","bytesReceived","log_","stats_","connURL","connectionURL_","urlParams","connectionURL","open","onMessage","onDisconnect","everConnected_","device","headers","User-Agent","platform","origin","mySock","onClosed_","onopen","onclose","handleIncomingFrame","start","forceDisallow","forceDisallow_","isAvailable","isOldAndroid","userAgent","oldAndroidRegex","oldAndroidMatch","parseFloat","previouslyFailed","markConnectionHealthy","appendFrame_","fullMess","jsonMess","handleNewFrameCount_","frameCount","extractFrameCount_","isNaN","mess","resetKeepAlive","remainingData","send","dataStr","sendString_","shutdown_","isClosed_","responsesRequiredToBeHealthy","healthyTimeout","decodePath","pathString","pathStringDecoded","pieces","split","piece","decodeURIComponent","validation_errorPrefix","fnName","argumentNumber","optional","argName","NAME_ONLY_COMPARATOR","left","right","__WEBPACK_IMPORTED_MODULE_0__util_util__","NAME_COMPARATOR","nodeFromJSON_nodeFromJSON","json","priority","ChildrenNode_ChildrenNode","EMPTY_NODE","nodeFromJSON__typeof","__WEBPACK_IMPORTED_MODULE_4__utils_assert__","LeafNode_LeafNode","USE_HINZE","node_1","jsonObj_1","__WEBPACK_IMPORTED_MODULE_3__utils_obj__","childData","childNode","isLeafNode","updateImmediateChild","updatePriority","children_1","childrenHavePriority_1","hinzeJsonObj_1","child","getPriority","NamedNode","childSet","childSet_buildChildSet","namedNode","sortedChildSet","PRIORITY_INDEX","getCompare","IndexMap_IndexMap",".priority","Default","__EMPTY_NODE","MAX_NODE","__childrenNodeConstructor","__WEBPACK_IMPORTED_MODULE_0__util__","__WEBPACK_IMPORTED_MODULE_1__utils_utf8__","Path","pathOrString","pieceNum","pieces_","copyTo","pieceNum_","getFront","getLength","popFront","getBack","toUrlEncodedString","encodeURIComponent","begin","parent","childPathObj","childPieces","relativePath","outerPath","innerPath","outer","inner","comparePaths","leftKeys","rightKeys","cmp","equals","other","ValidationPath","errorPrefix_","parts_","byteLength_","max","checkValid_","pop","last","MAX_PATH_LENGTH_BYTES","MAX_PATH_DEPTH","toErrorString","__WEBPACK_IMPORTED_MODULE_2__storage_storage__","__WEBPACK_IMPORTED_MODULE_3__realtime_Constants__","RepoInfo","host","secure","webSocketOnly","persistenceKey","domain","internalHost","needsQueryParam","isCacheableHost","isDemoHost","isCustomHost","updateHost","newHost","params","pairs","toURLString","__WEBPACK_IMPORTED_MODULE_2__util__","parser_parseRepoInfo","dataURL","parsedUrl","parseURL","subdomain","scheme","port","colonInd","slashInd","parts","validation__typeof","validateArgCount","minCount","maxCount","argCount","argError","validateCallback","validateContextObject","context","validation___WEBPACK_IMPORTED_MODULE_1__utils_obj__","validation___WEBPACK_IMPORTED_MODULE_2__util__","util_validation__typeof","INVALID_KEY_REGEX_","INVALID_PATH_REGEX_","isValidKey","isValidPathString","isValidRootPathString","isValidPriority","validation_validateFirebaseDataArg","validation_validateFirebaseData","validateFirebaseData","errorPrefix","path_","hasDotValue_1","hasActualChild_1","validation_validateFirebaseMergePaths","mergePaths","curPath","prevPath","validation_validateFirebaseMergeDataArg","validation_validatePriority","validation_validateEventType","eventType","validation_validateKey","validation_validatePathString","validateRootPathString","validateWritablePath","validation_validateUrl","validation_validateBoolean","bool","__WEBPACK_IMPORTED_MODULE_3__utils_promise__","onDisconnect_OnDisconnect","OnDisconnect","repo_","cancel","onComplete","onDisconnectCancel","onDisconnectSet","setWithPriority","onDisconnectSetWithPriority","objectToMerge","newObjectToMerge","onDisconnectUpdate","TransactionResult","committed","snapshot","NextPushId___WEBPACK_IMPORTED_MODULE_0__utils_assert__","nextPushId","PUSH_CHARS","lastPushTime","lastRandChars","now","duplicateTime","timeStampChars","node","Wrap","__WEBPACK_IMPORTED_MODULE_1__util_util__","Index_Index","Index","compare","indexedValueChanged","oldNode","newNode","oldWrapped","newWrapped","minPost","MIN","__WEBPACK_IMPORTED_MODULE_2__util_util__","__WEBPACK_IMPORTED_MODULE_3__utils_assert__","KeyIndex_KeyIndex","KeyIndex","isDefinedOn","maxPost","makePost","indexValue","KEY_INDEX","snap___WEBPACK_IMPORTED_MODULE_0__utils_assert__","snap___WEBPACK_IMPORTED_MODULE_1__util_util__","__WEBPACK_IMPORTED_MODULE_2__utils_obj__","snap__typeof","priorityHashText","validatePriorityNode","priorityNode","LeafNode___WEBPACK_IMPORTED_MODULE_0__utils_assert__","LeafNode___WEBPACK_IMPORTED_MODULE_1__util_util__","LeafNode__typeof","LeafNode","value_","priorityNode_","lazyHash_","newPriorityNode","getImmediateChild","childName","getChild","hasChild","getPredecessorChildName","newChildNode","updateChild","front","numChildren","forEachChild","index","action","exportFormat",".value","getValue","hash","toHash","compareTo","compareToLeafNode_","otherLeaf","otherLeafType","thisLeafType","otherIndex","VALUE_TYPE_ORDER","thisIndex","withIndex","isIndexed","nodeFromJSON","PriorityIndex_MAX_NODE","PriorityIndex___WEBPACK_IMPORTED_MODULE_1__util_util__","PriorityIndex___extends","PriorityIndex_PriorityIndex","PriorityIndex","aPriority","bPriority","indexCmp","SortedMapIterator","startKey","comparator","isReverse_","resultGenerator_","nodeStack_","getNext","hasNext","peek","LLRBNode","color","RED","SortedMap","copy","count","inorderTraversal","reverseTraversal","min_","minKey","maxKey","insert","fixUp_","removeMin_","isRed_","moveRedLeft_","smallest","rotateRight_","moveRedRight_","rotateLeft_","colorFlip_","nl","nr","checkMaxDepth_","blackDepth","check_","BLACK","LLRBEmptyNode","comparator_","root_","getPredecessorKey","rightParent","getIterator","resultGenerator","getIteratorFrom","getReverseIteratorFrom","getReverseIterator","_defaultIndexMap","LOG_2","Base12Num","num","current_","mask","bits_","nextBitIsOne","childList","keyFn","mapSortFn","buildBalancedTree","low","middle","base12","buildPennant","chunkSize","childTree","attachPennant","pennant","isOne","IndexMap___WEBPACK_IMPORTED_MODULE_0__utils_assert__","IndexMap___WEBPACK_IMPORTED_MODULE_2__utils_obj__","fallbackObject","IndexMap","indexes_","indexSet_","indexKey","sortedMap","hasIndex","indexDefinition","addIndex","existingChildren","sawIndexedValue","iter","newIndex","indexName","newIndexSet","newIndexes","addToIndexes","indexedChildren","existingSnap","newChildren","removeFromIndexes","ChildrenNode___WEBPACK_IMPORTED_MODULE_0__utils_assert__","ChildrenNode___WEBPACK_IMPORTED_MODULE_1__util_util__","ChildrenNode___extends","ChildrenNode","children_","indexMap_","newIndexMap","newPriority","newImmediateChild","numKeys","allIntegerKeys","toHash_1","childHash","idx","resolveIndex_","predecessor","getFirstChildName","getFirstChild","getLastChildName","getLastChild","wrappedNode","startPost","endPost","ChildrenNode_MAX_NODE","otherChildrenNode","thisIter","otherIter","thisCurrent","otherCurrent","ChildrenNode_MaxNode","MaxNode","defineProperties","MAX","__referenceConstructor","OperationType","ValueIndex___WEBPACK_IMPORTED_MODULE_2__util_util__","ValueIndex___extends","ValueIndex_ValueIndex","ValueIndex","valueNode","VALUE_INDEX","PathIndex___WEBPACK_IMPORTED_MODULE_0__utils_assert__","PathIndex___WEBPACK_IMPORTED_MODULE_1__util_util__","PathIndex___extends","PathIndex_PathIndex","PathIndex","indexPath_","extractChild","snap","aChild","bChild","DataSnapshot_DataSnapshot","DataSnapshot","node_","ref_","index_","exportVal","toJSON","exists","childPathString","childPath","childRef","hasChildren","getKey","getRef","DataEvent","eventRegistration","prevName","getPath","getParent","getEventType","getEventRunner","CancelEvent","EventRegistration___WEBPACK_IMPORTED_MODULE_2__utils_obj__","EventRegistration___WEBPACK_IMPORTED_MODULE_3__utils_assert__","EventRegistration_ValueEventRegistration","ValueEventRegistration","callback_","cancelCallback_","context_","respondsTo","createEvent","change","getQueryParams","getIndex","snapshotNode","eventData","ctx","cancelCB_1","cb_1","createCancelEvent","matches","hasAnyCallback","EventRegistration_ChildEventRegistration","ChildEventRegistration","callbacks_","eventToCheck","cancelCB_2","cb_2","otherCount","otherKey","thisKey","Query___WEBPACK_IMPORTED_MODULE_0__utils_assert__","__WEBPACK_IMPORTED_MODULE_5__core_util_util__","__WEBPACK_IMPORTED_MODULE_10__utils_promise__","Query__typeof","Query_Query","Query","repo","queryParams_","orderByCalled_","validateQueryEndpoints_","startNode","endNode","hasStart","getIndexStartValue","hasEnd","getIndexEndValue","tooManyArgsError","wrongArgTypeError","getIndexStartName","getIndexEndName","validateLimit_","hasLimit","hasAnchoredLimit","validateNoPreviousOrderByCall_","cancelCallbackOrContext","getCancelAndContextArgs_","onValueEvent","callbacks","onChildEvent","cancelCallback","container","addEventCallbackForQuery","removeEventCallbackForQuery","userCallback","cancelOrContext","firstCall","onceCallback","limitToFirst","limit","limitToLast","orderByChild","parsedPath","newParams","orderBy","orderByKey","orderByPriority","orderByValue","startAt","endAt","equalTo","queryObject","getQueryObject","queryIdentifier","isEqual","sameRepo","samePath","sameQueryIdentifier","CountedSet","add","clear","SparseSnapshotTree_SparseSnapshotTree","SparseSnapshotTree","find","childKey","remember","forget","self_1","tree","forEachTree","prefixPath","func","ServerValues___WEBPACK_IMPORTED_MODULE_0__utils_assert__","ServerValues__typeof","generateWithValues","resolveDeferredValue","serverValues","ServerValues_resolveDeferredValueTree","resolvedTree","ServerValues_resolveDeferredValueSnapshot","resolveDeferredValueSnapshot","rawPri","leafNode","childrenNode","Operation___WEBPACK_IMPORTED_MODULE_0__utils_assert__","OperationSource","fromUser","fromServer","queryId","tagged","User","Server","forServerTaggedQuery","emptyChildrenSingleton","AckUserWrite___WEBPACK_IMPORTED_MODULE_0__utils_assert__","AckUserWrite_AckUserWrite","AckUserWrite","affectedTree","revert","ACK_USER_WRITE","operationForChild","children","subtree","Empty","ImmutableTree___WEBPACK_IMPORTED_MODULE_2__util__","ImmutableTree___WEBPACK_IMPORTED_MODULE_3__utils_obj__","ImmutableTree_EmptyChildren","ImmutableTree_ImmutableTree","ImmutableTree","fromObject","childSnap","findRootMostMatchingPathAndValue","predicate","childExistingPathAndValue","findRootMostValueAndPath","toSet","newChild","setTree","newTree","fold","fold_","pathSoFar","accum","findOnPath","findOnPath_","pathToFollow","nextChild","foreachOnPath","foreachOnPath_","currentRelativePath","foreach","foreach_","foreachChild","ListenComplete_ListenComplete","ListenComplete","LISTEN_COMPLETE","Overwrite_Overwrite","Overwrite","OVERWRITE","Merge___WEBPACK_IMPORTED_MODULE_3__utils_assert__","Merge_Merge","Merge","MERGE","CacheNode","fullyInitialized_","filtered_","isFullyInitialized","isFiltered","isCompleteForPath","isCompleteForChild","getNode","ViewCache_ViewCache","ViewCache","eventCache_","serverCache_","updateEventSnap","eventSnap","filtered","updateServerSnap","serverSnap","getEventCache","getCompleteEventSnap","getServerCache","getCompleteServerSnap","Change","oldSnap","valueChange","VALUE","childAddedChange","CHILD_ADDED","childRemovedChange","CHILD_REMOVED","childChangedChange","newSnapshot","oldSnapshot","CHILD_CHANGED","childMovedChange","CHILD_MOVED","SyncPoint___referenceConstructor","IndexedFilter___WEBPACK_IMPORTED_MODULE_0__utils_assert__","IndexedFilter_IndexedFilter","IndexedFilter","affectedPath","optChangeAccumulator","oldChild","trackChildChange","updateFullNode","newSnap","filtersNodes","getIndexedFilter","ChildChangeAccumulator___WEBPACK_IMPORTED_MODULE_0__utils_obj__","__WEBPACK_IMPORTED_MODULE_2__utils_assert__","ChildChangeAccumulator_ChildChangeAccumulator","ChildChangeAccumulator","changeMap_","oldChange","oldType","getChanges","NoCompleteChildSource_","getCompleteChild","getChildAfterChild","NO_COMPLETE_CHILD_SOURCE","CompleteChildSource_WriteTreeCompleteChildSource","WriteTreeCompleteChildSource","writes_","viewCache_","optCompleteServerCache_","serverNode","calcCompleteChild","completeServerData","nodes","calcIndexedSlice","ProcessorResult","viewCache","changes","ViewProcessor_ViewProcessor","ViewProcessor","filter_","assertIndexed","applyOperation","oldViewCache","operation","writesCache","completeCache","newViewCache","filterServerNode","accumulator","overwrite","applyUserOverwrite_","applyServerOverwrite_","merge","applyUserMerge_","applyServerMerge_","ackUserWrite","revertUserWrite_","ackUserWrite_","listenComplete_","maybeAddValueEvent_","isLeafOrEmpty","oldCompleteSnap","generateEventCacheAfterServerEvent_","changePath","oldEventSnap","shadowingWrite","newEventCache","serverCache","completeChildren","completeEventChildren","calcCompleteEventChildren","completeNode","calcCompleteEventCache","oldEventNode","updatedPriority","calcEventCacheAfterServerOverwrite","childChangePath","newEventChild","eventChildUpdate","changedSnap","newServerCache","oldServerSnap","serverFilter","newServerNode","newEventSnap","cacheHasChild_","changedChildren","curViewCache","writePath","applyMerge_","viewMergeTree","serverChild","childMergeTree","isUnknownDeepMerge","ackPath","changedChildren_1","changedChildren_2","mergePath","serverCachePath","oldServerNode","completeServerCache","oldEventCache","serverChildren","EventGenerator___WEBPACK_IMPORTED_MODULE_2__utils_assert__","EventGenerator_EventGenerator","EventGenerator","query_","generateEventsForChanges","eventCache","eventRegistrations","events","moves","generateEventsForType_","registrations","filteredChanges","compareChanges_","materializedChange","materializeSingleChange_","registration","aWrapped","bWrapped","__WEBPACK_IMPORTED_MODULE_6__utils_assert__","View_View","View","initialViewCache","eventRegistrations_","indexFilter","getNodeFilter","processor_","initialServerCache","initialEventCache","eventGenerator_","getQuery","getCompleteServerCache","cache","loadsAllData","addEventRegistration","removeEventRegistration","cancelError","cancelEvents","path_1","maybeEvent","existing","generateEventsForChanges_","getInitialEvents","initialChanges","SyncPoint___WEBPACK_IMPORTED_MODULE_2__utils_assert__","SyncPoint___WEBPACK_IMPORTED_MODULE_3__utils_obj__","SyncPoint_SyncPoint","SyncPoint","views_","optCompleteServerCache","view","events_1","serverCacheComplete","eventCacheComplete","removed","hadCompleteView","hasCompleteView","viewQueryId","getQueryViews","viewForQuery","getCompleteView","viewExistsForQuery","CompoundWrite___WEBPACK_IMPORTED_MODULE_2__utils_obj__","__WEBPACK_IMPORTED_MODULE_5__utils_assert__","CompoundWrite_CompoundWrite","CompoundWrite","writeTree_","addWrite","rootmost","rootMostPath","addWrites","updates","newWrite","removeWrite","hasCompleteWrite","getCompleteNode","getCompleteChildren","childCompoundWrite","shadowingNode","applySubtreeWrite_","writeTree","priorityWrite_1","WriteTree___WEBPACK_IMPORTED_MODULE_0__utils_obj__","WriteTree___WEBPACK_IMPORTED_MODULE_1__utils_assert__","WriteTree_WriteTree","WriteTree","visibleWrites_","allWrites_","lastWriteId_","childWrites","WriteTreeRef","addOverwrite","writeId","visible","addMerge","getWrite","record","findIndex","writeToRemove","splice","removedWriteWasVisible","removedWriteOverlapsWithOtherWrites","currentWrite","recordContainsPath_","resetTree_","getCompleteWriteData","treePath","writeIdsToExclude","includeHiddenWrites","write","mergeAtPath","layerTree_","layeredCache","subMerge","completeServerChildren","topLevelSet","merge_1","existingEventSnap","existingServerSnap","childMerge","toIterate","writeRecord","DefaultFilter_","writes","treeRoot","compoundWrite","deepNode","treePath_","existingServerCache","SyncTree___WEBPACK_IMPORTED_MODULE_0__utils_assert__","SyncTree___WEBPACK_IMPORTED_MODULE_1__util_util__","__WEBPACK_IMPORTED_MODULE_4__utils_obj__","SyncTree_SyncTree","SyncTree","listenProvider_","syncPointTree_","pendingWriteTree_","tagToQueryMap_","queryToTagMap_","applyUserOverwrite","newData","applyOperationToSyncPoints_","applyUserMerge","changeTree","affectedTree_1","applyServerOverwrite","applyServerMerge","applyListenComplete","applyTaggedQueryOverwrite","tag","queryKey","queryKeyForTag_","r","parseQueryKey_","queryPath","op","applyTaggedOperation_","applyTaggedQueryMerge","applyTaggedListenComplete","foundAncestorDefaultView","pathToSyncPoint","sp","syncPoint","childSyncPoint","viewAlreadyExists","makeQueryKey_","getNextQueryTag_","setupListener_","maybeSyncPoint","removedAndEvents","removingDefault","covered","parentSyncPoint","newViews","collectDistinctViewsForSubTree_","newQuery","createListenerForView_","startListening","queryForListening_","tagForQuery_","hashFn","stopListening","queryToRemove","tagToRemove","removeTags_","maybeChildSyncPoint","childMap","views_1","childViews","queries","removedQuery","removedQueryKey","removedQueryTag","isDefault","queriesToStop","queries_1","childQueries","queryToStop","status","splitIndex","nextQueryTag_","applyOperationHelper_","syncPointTree","applyOperationDescendantsHelper_","childOperation","childServerCache","childWritesCache","SnapshotHolder_SnapshotHolder","SnapshotHolder","rootNode_","updateSnapshot","newSnapshotNode","AuthTokenProvider___WEBPACK_IMPORTED_MODULE_0__util_util__","AuthTokenProvider","app_","forceRefresh","addTokenChangeListener","removeTokenChangeListener","notifyForInvalidToken","errorMessage","StatsListener___WEBPACK_IMPORTED_MODULE_0__utils_obj__","StatsListener","collection_","last_","newStats","delta","stat","StatsReporter___WEBPACK_IMPORTED_MODULE_0__utils_obj__","StatsReporter___WEBPACK_IMPORTED_MODULE_1__util_util__","FIRST_STATS_MIN_TIME","FIRST_STATS_MAX_TIME","StatsReporter_StatsReporter","StatsReporter","collection","server_","statsToReport_","statsListener_","reportStats_","includeStat","stats","reportedStats","haveStatsToReport","reportStats","EventQueue___WEBPACK_IMPORTED_MODULE_0__util_util__","EventQueue","eventLists_","recursionDepth_","queueEvents","eventDataList","currList","eventPath","EventList","raiseEventsAtPath","raiseQueuedEventsMatchingPredicate_","raiseEventsForChangedPath","changedPath","sentAll","eventList","raise","events_","eventFn","EventEmitter___WEBPACK_IMPORTED_MODULE_0__utils_assert__","EventEmitter","allowedEvents_","listeners_","trigger","validateEventType_","getInitialEvent","et","VisibilityMonitor___WEBPACK_IMPORTED_MODULE_1__utils_assert__","VisibilityMonitor___extends","VisibilityMonitor","hidden","visibilityChange","visible_","getInstance","OnlineMonitor___WEBPACK_IMPORTED_MODULE_0__utils_assert__","__WEBPACK_IMPORTED_MODULE_2__utils_environment__","OnlineMonitor___extends","OnlineMonitor","online_","currentlyOnline","__WEBPACK_IMPORTED_MODULE_0__database_core_util_util__","__WEBPACK_IMPORTED_MODULE_1__json__","jwt__typeof","decode","token","header","claims","signature","isValidFormat","decoded","isAdmin","__WEBPACK_IMPORTED_MODULE_0__core_util_util__","PacketReceiver","onMessage_","pendingResponses","currentResponseNum","closeAfterResponse","onClose","closeAfter","responseNum","handleResponse","requestNum","this_1","toProcess","BrowserPollConnection___WEBPACK_IMPORTED_MODULE_0__core_util_util__","__WEBPACK_IMPORTED_MODULE_2__core_stats_StatsManager__","__WEBPACK_IMPORTED_MODULE_6__utils_environment__","FIREBASE_LONGPOLL_COMMAND_CB_NAME","FIREBASE_LONGPOLL_DATA_CB_NAME","BrowserPollConnection_BrowserPollConnection","BrowserPollConnection","urlFn","curSegmentNum","onDisconnect_","myPacketOrderer","connectTimeoutTimer_","scriptTagHolder","BrowserPollConnection_FirebaseIFrameScriptHolder","command","arg1","arg2","incrementIncomingBytes_","password","sendNewPolls","pN","uniqueCallbackIdentifier","connectURL","addTag","startLongPoll","addDisconnectPingFrame","forceAllow","forceAllow_","myDisconnFrame","base64data","MAX_URL_DATA_SIZE","enqueueSegment","pw","style","display","FirebaseIFrameScriptHolder","commandCB","onMessageCB","outstandingRequests","pendingSegs","currentSerial","myIFrame","createIFrame_","iframeContents","iframe","contentWindow","contentDocument","alive","innerHTML","myID","myPW","theURL","nodeRestRequest","newRequest_","curDataString","theSeg","seg","ts","addLongPollTag_","segnum","totalsegs","url","serial","doNewRequest","keepaliveTimeout","readyStateCB","loadCB","doNodeLongPoll","newScript_1","rstate","parentNode","__WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__","TransportManager___WEBPACK_IMPORTED_MODULE_2__core_util_util__","TransportManager_TransportManager","TransportManager","initTransports_","isWebSocketsAvailable","isSkipPollConnection","transports_","transports_1","ALL_TRANSPORTS","transport","initialTransport","upgradeTransport","Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__","__WEBPACK_IMPORTED_MODULE_1__core_storage_storage__","__WEBPACK_IMPORTED_MODULE_2__Constants__","Connection_Connection","Connection","repoInfo_","onReady_","onKill_","connectionCount","pendingDataMessages","state_","transportManager_","start_","conn","conn_","nextTransportId_","primaryResponsesRequired_","onMessageReceived","connReceiver_","onConnectionLost","disconnReceiver_","tx_","rx_","secondaryConn_","isHealthy_","healthyTimeout_ms","healthyTimeout_","everConnected","onConnectionLost_","onSecondaryConnectionLost_","onPrimaryMessageReceived_","onSecondaryMessageReceived_","sendRequest","dataMsg","msg","sendData_","tryCleanupConnection","onSecondaryControl_","controlData","cmd","upgradeIfSecondaryHealthy_","secondaryResponsesRequired_","parsedData","layer","proceedWithUpgrade_","onControl_","onDataMessage_","onPrimaryResponse_","payload","onHandshake_","onConnectionShutdown_","onReset_","sendPingOnPrimaryIfNecessary_","handshake","timestamp","h","sessionId","onConnectionEstablished_","tryStartUpgrade_","startUpgrade_","closeConnections_","ServerActions","put","refreshAuthToken","onDisconnectPut","onDisconnectMerge","PersistentConnection___WEBPACK_IMPORTED_MODULE_0__app__","PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__","__WEBPACK_IMPORTED_MODULE_2__utils_json__","PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__","__WEBPACK_IMPORTED_MODULE_4__util_util__","__WEBPACK_IMPORTED_MODULE_10__utils_constants__","__WEBPACK_IMPORTED_MODULE_11__utils_environment__","PersistentConnection__typeof","PersistentConnection___extends","RECONNECT_MIN_DELAY","RECONNECT_MAX_DELAY_DEFAULT","PersistentConnection_PersistentConnection","PersistentConnection","onDataUpdate_","onConnectStatus_","onServerInfoUpdate_","authTokenProvider_","authOverride_","nextPersistentConnectionId_","interruptReasons_","listens_","outstandingPuts_","outstandingPutCount_","onDisconnectRequestQueue_","connected_","reconnectDelay_","maxReconnectDelay_","securityDebugCallback_","establishConnectionTimer_","requestCBHash_","requestNumber_","realtime_","authToken_","forceTokenRefresh_","invalidAuthTokenCount_","firstConnection_","lastConnectionAttemptTime_","lastConnectionEstablishedTime_","scheduleConnect_","onVisible_","onOnline_","onResponse","curReqNum","listen","currentHashFn","listenSpec","sendListen_","req","warnOnListenWarnings_","removeListen_","warnings","indexSpec","indexPath","tryAuth","reduceReconnectDelayIfAdminCredential_","credential","token_1","authMethod","requestData","cred","onAuthRevoked_","unlisten","sendUnlisten_","queryObj","sendOnDisconnect_","request","response","putInternal","sendPut_","queued","errorReason","reqNum","onDataPush_","onListenRevoked_","onSecurityDebugPacket_","handleTimestamp_","sendConnectStats_","restoreState_","establishConnection_","online","onRealtimeDisconnect_","cancelSentTransactions_","shouldReconnect_","timeSinceLastConnectSucceeded","timeSinceLastConnectAttempt","reconnectDelay","onDataMessage_1","onReady_1","onDisconnect_1","connId_1","nextConnectionId_","lastSessionId_1","canceled_1","connection_1","closeFn_1","sendRequestFn","accessToken","interrupt","resume","serverTimeOffset","q","normalizedPathString","statusCode","explanation","clientName","__WEBPACK_IMPORTED_MODULE_0__obj__","querystring","querystringParams","arrayVal","ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_0__utils_assert__","ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_1__util_util__","ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_2__utils_json__","ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_3__utils_obj__","ReadonlyRestClient___extends","ReadonlyRestClient_ReadonlyRestClient","ReadonlyRestClient","getListenId_","listenId","thisListen","queryStringParamaters","toRestQueryStringParameters","restRequest_","status_1","queryStringParameters","authTokenData","authToken","xhr","XMLHttpRequest","responseText","__WEBPACK_IMPORTED_MODULE_6__utils_json__","__WEBPACK_IMPORTED_MODULE_7__util_util__","__WEBPACK_IMPORTED_MODULE_8__utils_obj__","__WEBPACK_IMPORTED_MODULE_10__stats_StatsManager__","Repo__typeof","Repo_Repo","Repo","forceRestClient","dataUpdateCount","eventQueue_","nextWriteId_","interceptServerDataCallback_","persistentConnection_","authTokenProvider","authOverride","statsReporter_","transactions_init_","infoData_","infoSyncTree_","infoEvents","updateInfo_","serverSyncTree_","serverTime","offsetNode","offset","generateServerValues","isMerge","taggedChildren","raw","taggedSnap","rerunTransactions_","interceptServerData_","connectStatus","runOnDisconnectEvents_","getNextWriteId_","newVal","newNodeUnresolved","success","clearEvents","callOnCompleteCallback","abortTransactions_","childrenToMerge","empty","changedKey","changedValue","writeId_1","resolvedOnDisconnectTree","showDelta","longestName","reduce","previousValue","currentValue","statsIncrementCounter","metric","__database","Database_Database","RangedFilter_RangedFilter","RangedFilter","indexedFilter_","startPost_","getStartPost_","endPost_","getEndPost_","getStartPost","getEndPost","startName","endName","LimitedFilter___WEBPACK_IMPORTED_MODULE_3__utils_assert__","LimitedFilter_LimitedFilter","LimitedFilter","rangedFilter_","limit_","getLimit","reverse_","isViewFromLeft","fullLimitUpdateChild_","inRange","indexCompare_1","foundStartPost","changeAccumulator","indexCmp_1","newChildNamedNode","windowBoundary","oldChildSnap","compareNext","QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__","QueryParams___WEBPACK_IMPORTED_MODULE_1__util_util__","__WEBPACK_IMPORTED_MODULE_9__utils_json__","QueryParams_QueryParams","QueryParams","limitSet_","startSet_","startNameSet_","endSet_","endNameSet_","viewFrom_","indexStartValue_","indexStartName_","indexEndValue_","indexEndName_","WIRE_PROTOCOL_CONSTANTS_","VIEW_FROM_LEFT","copy_","newLimit","VIEW_FROM_RIGHT","WIRE_PROTOCOL_CONSTANTS","INDEX_START_VALUE","INDEX_START_NAME","INDEX_END_VALUE","INDEX_END_NAME","LIMIT","viewFrom","VIEW_FROM","INDEX","REST_CONSTANTS","REST_QUERY_CONSTANTS_","qs","ORDER_BY","START_AT","END_AT","LIMIT_TO_FIRST","LIMIT_TO_LAST","DEFAULT","Reference___WEBPACK_IMPORTED_MODULE_2__core_util_util__","Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__","Reference___extends","Reference_Reference","Reference","parentPath","getRoot","databaseProp","database","transaction","transactionUpdate","applyLocally","promiseComplete","startTransaction","setPriority","thennablePushRef","pushRef","TransactionStatus","Tree___WEBPACK_IMPORTED_MODULE_0__utils_assert__","Tree___WEBPACK_IMPORTED_MODULE_2__utils_obj__","TreeNode","childCount","Tree_Tree","Tree","parent_","subTree","pathObj","setValue","updateParents_","forEachDescendant","includeSelf","childrenFirst","forEachAncestor","forEachImmediateDescendantWithValue","updateChild_","childEmpty","childExists","Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__","__WEBPACK_IMPORTED_MODULE_6__util_util__","__WEBPACK_IMPORTED_MODULE_9__utils_obj__","Repo_transaction__typeof","MAX_TRANSACTION_RETRIES_","transactionQueueTree_","valueCallback","watchRef","unwatcher","order","retryCount","abortReason","currentWriteId","currentInputSnapshot","currentOutputSnapshotRaw","currentOutputSnapshotResolved","currentState","getLatestState_","RUN","queueNode","nodeQueue","priorityForNode","sendReadyTransactions_","excludeSets","pruneCompletedTransactionsBelowNode_","buildTransactionQueue_","sendTransactionQueue_","setsToIgnore","txn","latestState","snapToSend","latestHash","SENT","dataToSend","pathToSend","COMPLETED","SENT_NEEDS_ABORT","NEEDS_ABORT","rootMostTransactionNode","getAncestorTransactionNode_","rerunTransactionQueue_","txnsToRerun","abortTransaction","currentNode","newDataNode","hasExplicitPriority","oldWriteId","newNodeResolved","lastInput","transactionNode","transactionQueue","aggregateTransactionQueuesForNode_","to","from","abortTransactionsOnNode_","lastSent","_staticInstance","RepoManager___WEBPACK_IMPORTED_MODULE_0__utils_obj__","RepoManager___WEBPACK_IMPORTED_MODULE_2__util_util__","RepoManager_RepoManager","RepoManager","repos_","useRestClient_","databaseFromApp","dbUrl","createRepo","deleteRepo","Database___WEBPACK_IMPORTED_MODULE_0__core_util_util__","Database___WEBPACK_IMPORTED_MODULE_3__utils_promise__","Database","Database_DatabaseInternals","checkDeleted_","refFromURL","apiName","parsedURL","goOffline","goOnline","ServerValue","TIMESTAMP",".sv","DatabaseInternals","internal_namespaceObject","internal_forceLongPolling","internal_forceWebSockets","setSecurityDebugCallback","internal_stats","interceptServerData","__WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__","test_access_namespaceObject","DataConnection","RealTimeConnection","test_access_hijackHash","ConnectionTarget","listens","test_access_forceRestClient","simpleListen","echo","onEcho","newHash","oldPut","opt_onComplete","opt_hash","firebaseRef","_forceRestClient","registerDatabase","instance","__WEBPACK_IMPORTED_MODULE_4__database_core_util_util__","TEST_ACCESS","originalModule","webpackPolyfill","23","toBase64","arrayBuffer","uint8Version","Uint8Array","registerMessaging","factoryMethod","sw_controller_defaultExport","window_controller_defaultExport","namespaceExports","Messaging","_a","CODES","AVAILABLE_IN_WINDOW","AVAILABLE_IN_SW","SHOULD_BE_INHERITED","BAD_SENDER_ID","INCORRECT_GCM_SENDER_ID","PERMISSION_DEFAULT","PERMISSION_BLOCKED","UNSUPPORTED_BROWSER","NOTIFICATIONS_BLOCKED","FAILED_DEFAULT_REGISTRATION","SW_REGISTRATION_EXPECTED","GET_SUBSCRIPTION_FAILED","INVALID_SAVED_TOKEN","SW_REG_REDUNDANT","TOKEN_SUBSCRIBE_FAILED","TOKEN_SUBSCRIBE_NO_TOKEN","TOKEN_SUBSCRIBE_NO_PUSH_SET","USE_SW_BEFORE_GET_TOKEN","INVALID_DELETE_TOKEN","DELETE_TOKEN_NOT_FOUND","DELETE_SCOPE_NOT_FOUND","BG_HANDLER_FUNCTION_EXPECTED","NO_WINDOW_CLIENT_TO_MSG","UNABLE_TO_RESUBSCRIBE","NO_FCM_TOKEN_FOR_RESUBSCRIBE","FAILED_TO_DELETE_TOKEN","NO_SW_IN_REG","BAD_SCOPE","BAD_VAPID_KEY","BAD_SUBSCRIPTION","BAD_TOKEN","BAD_PUSH_SET","FAILED_DELETE_VAPID_KEY","ERROR_MAP","errors_defaultExport","codes","array_buffer_to_base64_defaultExport","FCM_APPLICATION_SERVER_KEY","SUBSCRIPTION_DETAILS","userVisibleOnly","applicationServerKey","fcm_details_defaultExport","ENDPOINT","APPLICATION_SERVER_KEY","SUBSCRIPTION_OPTIONS","__WEBPACK_IMPORTED_MODULE_0__app_errors__","FCM_TOKEN_OBJ_STORE","token_manager_TokenManager","TokenManager","errorFactory_","openDbPromise_","openDatabase_","indexedDB","onsuccess","onupgradeneeded","db","objectStore","createObjectStore","keyPath","createIndex","unique","closeDatabase","getTokenDetailsFromToken","fcmToken","getTokenDetailsFromSWScope_","swScope","scopeRequest","getAllTokenDetailsForSenderId_","senderId","senderIdTokens","cursorRequest","openCursor","cursor","continue","subscribeToFCM","subscription","pushSet","p256dh","auth","fcmSubscribeBody","endpoint","Headers","append","subscribeOptions","fetch","fcmTokenResponse","isSameSubscription_","masterTokenDetails","saveTokenDetails_","swRegistration","fcmPushSet","details","fcmSenderId","getSavedToken","ServiceWorkerRegistration","allTokenDetails","tokenDetails","pushManager","getSubscription","createToken","fcmTokenDetails","sub","deleteToken","token_manager_defaultExport","controller_interface___WEBPACK_IMPORTED_MODULE_0__app_errors__","SENDER_ID_OPTION_NAME","controller_interface_ControllerInterface","ControllerInterface","messagingSenderId_","tokenManager_","currentPermission","getNotificationPermission_","notification_permission_defaultExport","getSWRegistration_","unsubscribe","requestPermission","useServiceWorker","optError","optCompleted","onTokenRefresh","setBackgroundMessageHandler","Notification","permission","getTokenManager","controller_interface_defaultExport","PARAMS","TYPE_OF_MSG","DATA","msgType","PUSH_MSG_RECEIVED","NOTIFICATION_CLICKED","createNewMsg","msgData","worker_page_message_defaultExport","TYPES_OF_MSG","default_sw_defaultExport","__WEBPACK_IMPORTED_MODULE_5__app_subscribe__","window_controller_WindowController","WindowController","registrationToUse_","manifestCheckPromise_","messageObserver_","tokenRefreshObserver_","onTokenRefresh_","setupSWMessageListener_","isSupported_","manifestCheck_","manifestTag","querySelector","manifestContent","managePermissionResult","permissionPromise","waitForRegistrationToActivate_","serviceWorker","installing","waiting","state","stateChangeListener","removeEventListener","register","browserErrorMessage","workerPageMessage","pushMessage","PushSubscription","sw_controller___extends","sw_controller_SWController","SWController","onPush_","onSubChange_","onNotificationClick_","bgMessageHandler_","msgPayload","handleMsgPromise","hasVisibleClients_","hasVisibleClients","notification","sendMessageToWindowClients_","notificationDetails","getNotificationData_","notificationTitle","showNotification","waitUntil","promiseChain","tokenManager","newSubscription","stopImmediatePropagation","clickAction","getWindowClient_","windowClient","clients","openWindow","internalMsg","attemptToMessageClient_","notificationInformation","assign","URL","matchAll","includeUncontrolled","clientList","suitableClient","focus","client","some","visibilityState","22","prependCode","unknown","FirebaseStorageError","Code","UNKNOWN","objectNotFound","OBJECT_NOT_FOUND","quotaExceeded","bucket","QUOTA_EXCEEDED","unauthenticated","UNAUTHENTICATED","unauthorized","UNAUTHORIZED","retryLimitExceeded","RETRY_LIMIT_EXCEEDED","error_canceled","CANCELED","invalidUrl","INVALID_URL","invalidDefaultBucket","INVALID_DEFAULT_BUCKET","cannotSliceBlob","CANNOT_SLICE_BLOB","serverFileWrongSize","SERVER_FILE_WRONG_SIZE","noDownloadURL","NO_DOWNLOAD_URL","invalidArgument","INVALID_ARGUMENT","invalidArgumentCount","argMin","argMax","real","countPart","plural","INVALID_ARGUMENT_COUNT","appDeleted","APP_DELETED","invalidRootOperation","INVALID_ROOT_OPERATION","invalidFormat","format","INVALID_FORMAT","internalError","INTERNAL_ERROR","formatValidator","stringFormat","StringFormat","RAW","BASE64","BASE64URL","DATA_URL","dataFromString","string","StringData","utf8Bytes_","base64Bytes_","dataURLBytes_","dataURLContentType_","valid","hi","lo","percentEncodedBytes_","hasMinus","hasUnder","invalidChar","hasPlus","hasSlash","string_DataURLParts","rest","contentType","endsWith","end","taskStateFromInternalTaskState","InternalTaskState","RUNNING","PAUSING","CANCELING","TaskState","PAUSED","SUCCESS","ERROR","make","resolver","promise_external_resolve","promise_external_reject","isDef","isJustDef","isFunction","isObject","isNonNullObject","isNonArrayObject","isString","isNumber","isNativeBlob","isNativeBlobDefined","Blob","jsonObjectOrNull","lastIndexOf","canonicalChildPath","component","lastComponent","makeNormalUrl","urlPart","domainBase","apiBaseUrl","makeDownloadUrl","downloadBase","makeUploadUrl","apiUploadBaseUrl","makeQueryString","encode","queryPart","nextPart","noXform_","metadata","xformPath","fullPath","getMappings","mappingsXformPath","xformSize","size","xformTokens","tokens","alt","mappings_","mappings","Mapping","nameMapping","xform","sizeMapping","addRef","authWrapper","generateRef","loc","location_Location","makeStorageReference","fromResource","resource","mapping","local","server","fromResourceString","resourceString","toResourceString","writable","metadataValidator","validate","specs","passed","minArgs","maxArgs","validator","and_","v1","v2","stringSpec","opt_validator","opt_optional","stringValidator","args_ArgSpec","uploadDataSpec","ArrayBuffer","metadataSpec","nonNegativeNumberSpec","looseObjectSpec","nullFunctionSpec","getBlobBuilder","BlobBuilder","WebKitBlobBuilder","getBlob","bb","sliceBlob","blob","webkitSlice","mozSlice","array_contains","elem","array_clone","arraylike","handlerCheck","cndn","metadataHandler","handler","text","sharedErrorHandler","errorHandler","newErr","getStatus","setServerResponseProp","serverResponseProp","objectErrorHandler","shared","getMetadata","fullServerUrl","maxOperationRetryTime","requestInfo","RequestInfo","updateMetadata","Content-Type","deleteObject","successCodes","determineContentType_","metadataForUpload_","opt_metadata","multipartUpload","bucketOnlyServerUrl","X-Goog-Upload-Protocol","boundary","metadataString","preBlobPart","postBlobPart","blob_FbsBlob","maxUploadRetryTime","uploadData","checkResumeHeader_","opt_allowed","getResponseHeader","createResumableUpload","X-Goog-Upload-Command","X-Goog-Upload-Header-Content-Length","X-Goog-Upload-Header-Content-Type","getResumableUploadStatus","sizeString","ResumableUploadStatus","continueResumableUpload","opt_status","opt_progressCallback","uploadStatus","newCurrent","current","bytesToUpload","total","bytesLeft","startByte","endByte","uploadCommand","X-Goog-Upload-Offset","progressCallback","argsToForward","canceled","cancelState","triggerCallback","triggeredCallback","callWithDelay","millis","timeoutId","hitTimeout","waitSeconds","waitMillis","stop","wasTimeout","stopped","addAuthHeader_","addVersionHeader_","number","makeRequest","pool","request_NetworkRequest","additionalRetryCodes","factory","unused","opt_url","service_Service","xhriopool_XhrIoPool","registerStorage","TaskEvent","Storage","reference_Reference","STORAGE_TYPE","ErrorCode","defaultMaxOperationRetryTime","defaultMaxUploadRetryTime","minSafeInteger","code_","message_","serverResponse_","codeProp","codeEquals","serverResponse","BUCKET_NOT_FOUND","PROJECT_NOT_FOUND","INVALID_CHECKSUM","INVALID_EVENT_NAME","NO_DEFAULT_BUCKET","opt_contentType","DataURLParts","STATE_CHANGED","xhrio_network_NetworkXhrIo","NetworkXhrIo","sent_","xhr_","errorCode_","NO_ERROR","sendPromise_","ABORT","NETWORK_ERROR","opt_body","opt_headers","setRequestHeader","getErrorCode","getResponseText","abort","addUploadProgressListener","upload","removeUploadProgressListener","XhrIoPool","createXhrIo","Location","makeFromBucketSpec","bucketString","bucketLocation","makeFromUrl","gsModify","httpModify","gsRegex","gsIndices","httpRegex","httpIndices","groups","regex","indices","postModify","group","captures","exec","bucketValue","pathValue","opt_local","opt_writable","opt_xform","ArgSpec","FbsBlob","opt_elideCopy","blobType","data_","byteLength","size_","type_","realBlob","sliced","buffer","blobby","uint8Arrays","finalLength_1","merged_1","index_1","observer_Observer","Observer","opt_error","opt_complete","UploadTaskSnapshot","bytesTransferred","totalBytes","urls","task_UploadTask","UploadTask","transferred_","needToFetchStatus_","needToFetchMetadata_","observers_","error_","uploadUrl_","request_","chunkMultiplier_","resolve_","reject_","authWrapper_","location_","blob_","metadata_","resumable_","shouldDoResumable_","errorHandler_","completeTransitions_","transition_","metadataErrorHandler_","promise_","makeProgressCallback_","sizeBefore","loaded","updateProgress_","createResumable_","fetchStatus_","fetchMetadata_","continueUpload_","oneShotUpload_","resolveToken_","getAuthToken","createRequest","getPromise","statusRequest","uploadRequest","newStatus","increaseMultiplier_","metadataRequest","multipartRequest","transferred","old","notifyObservers_","wasPaused","externalState","completed","typeValidator","_p","nextOrObserverValidator","nextValidator","observerValidator","nextOrObserverMessage","makeBinder","binder","addObserver_","removeObserver_","binderNextOrObserverValidator","binderSpecs","notifyObserver_","finishPromise_","triggered","pause","newRef","newPath","throwIfRoot_","putString","getDownloadURL","failrequest_FailRequest","FailRequest","appDelete","requestmap_RequestMap","RequestMap","map_","id_","addRequest","unmap","authwrapper_AuthWrapper","AuthWrapper","maker","requestMaker","bucket_","deleted_","extractBucket_","storageRefMaker_","requestMaker_","pool_","service_","maxOperationRetryTime_","maxUploadRetryTime_","requestMap_","config","_error","deleteApp","setMaxUploadRetryTime","setMaxOperationRetryTime","NetworkRequest","errorCallback","pendingXhr_","backoffId_","canceled_","appDelete_","url_","method_","headers_","body_","successCodes_","additionalRetryCodes_","errorCallback_","progressCallback_","timeout_","doTheRequest","backoffCallback","progressListener","progressEvent","lengthComputable","RequestEndStatus","hitServer","isRetryStatusCode_","wasCanceled","successCode","backoffDone","requestWentThrough","wasSuccessCode","isFiveHundredCode","extraRetryCodes","isExtraRetryCode","isRequestSpecificRetryCode","opt_canceled","Service","authWrapperBucket","internals_","service_ServiceInternals","ServiceInternals"],"mappings":"AAAA,GAAIA,UAAW,WACH,GAAIC,OAA2B,KAAXA,EAAyBC,KAAOD,CACtD,OAAgB,UAAUE,GCqCpC,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAI,EAAAJ,EACAK,GAAA,EACAH,WAUA,OANAJ,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,GAGAI,EAAAE,GAAA,EAGAF,EAAAD,QA1DA,GAAAK,GAAAX,EAAA,oBACAA,GAAA,8BAAAY,EAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAAR,EAAA,EAAAS,KACQT,EAAAI,EAAAM,OAAoBV,IAC5BO,EAAAH,EAAAJ,GACAW,EAAAJ,IACAE,EAAAG,KAAAD,EAAAJ,GAAA,IAEAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAS,GACAQ,OAAAC,UAAAC,eAAAb,KAAAG,EAAAT,KACAF,EAAAE,GAAAS,EAAAT,GAIA,KADAO,KAAAC,EAAAC,EAAAC,GACAG,EAAAC,QACAD,EAAAO,SAEA,IAAAV,EACA,IAAAN,EAAA,EAAYA,EAAAM,EAAAI,OAA2BV,IACvCQ,EAAAb,IAAAsB,EAAAX,EAAAN,GAGA,OAAAQ,GAIA,IAAAX,MAGAc,GACAO,EAAA,EAiHA,OApFAvB,GAAAwB,EAAA,SAAAZ,GA+BA,QAAAa,KAEAC,EAAAC,QAAAD,EAAAE,OAAA,KACAC,aAAAC,EACA,IAAAC,GAAAf,EAAAJ,EACA,KAAAmB,IACAA,GACAA,EAAA,GAAAC,MAAA,iBAAApB,EAAA,aAEAI,EAAAJ,OAAAqB,IAvCA,GAAAC,GAAAlB,EAAAJ,EACA,QAAAsB,EACA,UAAAC,SAAA,SAAAC,GAA0CA,KAI1C,IAAAF,EACA,MAAAA,GAAA,EAIA,IAAAG,GAAA,GAAAF,SAAA,SAAAC,EAAAE,GACAJ,EAAAlB,EAAAJ,IAAAwB,EAAAE,IAEAJ,GAAA,GAAAG,CAGA,IAAAE,GAAAC,SAAAC,qBAAA,WACAf,EAAAc,SAAAE,cAAA,SACAhB,GAAAiB,KAAA,kBACAjB,EAAAkB,QAAA,QACAlB,EAAAmB,OAAA,EACAnB,EAAAI,QAAA,KAEA9B,EAAA8C,IACApB,EAAAqB,aAAA,QAAA/C,EAAA8C,IAEApB,EAAAsB,IAAAhD,EAAAiD,EAAA,GAAArC,EAAA,KACA,IAAAkB,GAAAoB,WAAAzB,EAAA,KAgBA,OAfAC,GAAAC,QAAAD,EAAAE,OAAAH,EAaAc,EAAAY,YAAAzB,GAEAW,GAIArC,EAAAoD,EAAArD,EAGAC,EAAAqD,EAAAnD,EAGAF,EAAAsD,EAAA,SAAAnD,EAAAoD,EAAAC,GACAxD,EAAAyD,EAAAtD,EAAAoD,IACArC,OAAAwC,eAAAvD,EAAAoD,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAxD,EAAA8D,EAAA,SAAA1D,GACA,GAAAoD,GAAApD,KAAA2D,WACA,WAA2B,MAAA3D,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAJ,GAAAsD,EAAAE,EAAA,IAAAA,GACAA,GAIAxD,EAAAyD,EAAA,SAAAO,EAAAC,GAAsD,MAAA/C,QAAAC,UAAAC,eAAAb,KAAAyD,EAAAC,IAGtDjE,EAAAiD,EAAA,GAGAjD,EAAAkE,GAAA,SAAAC,GAA8D,KAApBC,SAAAC,MAAAF,GAAoBA,GAG9DnE,IAAAsB,EAAA,KDOO,CACA,CACA,CACA,CAED,SAAUlB,EAAQkE,EAAqBtE,GAE7C,YAC+BA,GAAoBsD,EAAEgB,EAAqB,IAAK,WAAa,MAAOC,KACpEvE,EAAoBsD,EAAEgB,EAAqB,IAAK,WAAa,MAAOE,KACpExE,EAAoBsD,EAAEgB,EAAqB,IAAK,WAAa,MAAOG,IEvJjG,IAAAC,GAAA1E,EAAA,IAIsBuE,EAAcG,EAAA,EAAQvC,SAAWnC,EAAqB,IAK9EwE,EAAA,WAME,QAAAA,KACE,GAAQ1E,GAAQ6E,IACZA,MAAQvC,QAAQ,KAChBuC,KAAOrC,OAAQ,KACfqC,KAAQtC,QAAA,GAAkBkC,GAAC,SAAgBnC,EAAQE,GACjDxC,EAAQsC,QAAWA,EACnBtC,EAAOwC,OACbA,IAoCJ,MA1BEkC,GAAArD,UAAYyD,aAAZ,SAA8BC,GAM5B,QAAAC,GAAmBT,EAAWU,GAClBV,EACJvE,EAAOwC,OACb+B,GACMvE,EAAQsC,QACd2C,GAC2C,kBAAhBF,KACFJ,EAAK3E,EAAUuC,SAIJ,IAAdwC,EAAO9D,OACT8D,EAClBR,GACkBQ,EAAMR,EACxBU,IApBJ,GAAQjF,GAAQ6E,IAuBV,OACRG,IACDN,KAcmCC,EAAG,SAAgBpC,GAC9CA,EAAM2C,MAAC,gBFoKV,SAAU5E,EAAQkE,EAAqBtE,GAE7C,YGgIM,SAAAiF,KAkDJ,QAAAC,GAA+B3B,GAEjB4B,EADGC,EAAO7B,GACM,gBAChB6B,GACd7B,GAKA,QAAA8B,GAA0B9B,GAKlB,MAJFA,GAAOA,GAAuB+B,EACrBC,EAAMH,EAAQ7B,IACpBc,EAAS,UAASd,KACzBA,IACY6B,EACd7B,GAOA,QAAAiC,GAA+CC,EAAelC,OACrCtB,KAAfsB,EACFA,EACN+B,EAC8B,gBAAb/B,IAA6B,KAARA,GAC7Bc,EAAe,gBAASd,KAAMA,EACrC,KAEUgC,EAAMH,EAAS7B,IACpBc,EAAgB,iBAASd,KAChCA,GAEA,IAAO8B,GAAG,GAAmBK,GAAQD,EAAOlC,EAAkCoC,EAKxE,OAHDP,GAAO7B,GAAO8B,EACPF,EAAIE,EAAY,UAG9BA,EAKA,QAAAO,KAEQ,MAAA1E,QAAY2E,KAAOT,GAAIU,IAAC,SAAKvC,GAAK,MAAK6B,GAAM7B,KAUrD,QAAAwC,GACgBxC,EACyByC,EACIC,EACxBC,EACeC,GAGrBC,EAAO7C,IACbc,EAAoB,qBAASd,KACpCA,IAGS6C,EAAM7C,GAAiByC,EAGpBE,IACFG,EAAM9C,GAAW2C,EAGhBN,IAAQU,QAAC,SAAGjB,GACZa,EAAS,SAClBb,KAIF,IAAsBkB,GAAG,SAA4BC,GAQ7C,WARkB,KAAAA,MAA2BnB,KACJ,kBAAtBmB,GAAMjD,IAGxBc,EAAuB,wBAASd,KACvCA,IAGsBiD,EACxBjD,KAgBM,YAb8BtB,KAAfgE,GACTQ,EAAA,EAAiBF,EAC7BN,GAGkBN,EAAMpC,GAAoBgD,EAG7Bb,EAAUvE,UAAMoC,GAAG,WHmC1B,IGnCmC,GAAAmD,MAAAC,EAAO,EAAPA,EAAAC,UAAO7F,OAAA4F,IAAPD,EAAAC,GAAAC,UAAOD,EAE1C,OADiBhC,MAAYkC,EAAKC,KAAKnC,KAAQpB,GAC9BwD,MAAKpC,KAAwBwB,EAAOO,OAI/DH,EAOA,QAAAS,GAAqDC,GACzCR,EAAA,EAAUd,EACtBsB,GAEA,QAAA9B,GAAsCE,EAAmB6B,GACjDhG,OAAK2E,KAAWO,GAAQE,QAAC,SAAYa,GAEzC,GAAeC,GAAeC,EAAIhC,EAAe8B,EACxB,QAAVC,GAIHf,EAAce,IAChBf,EAAae,GAAUF,EACjC7B,KAMJ,QAAAgC,GAAsChC,EAAc9B,GAC/C,GAAuB,eAAlBA,EACA,MACR,KAEA,IAAc+D,GAAQ/D,CAGhB,OAFW8B,GAASI,QAG5B6B,EAlMA,GAASlC,MACIgB,KACDC,KAGCV,GAGC5B,YAAM,EACHyB,cAAeA,EACzBH,IAAYA,EACXkC,KAAa,KACVpF,QAAaqF,EAAA,EACTC,YAAqB,oBACxBC,UACS3B,gBAAiBA,EACTd,wBAAyBA,EACjC+B,gBAAiBA,EACjBW,gBAAiBC,EAAA,EACpBC,aAAcC,EAAA,EACjB5C,UAAWA,EACXkB,UAAWA,EACRiB,aAAcA,EACnBlF,QAAaqF,EAAA,EACVO,WAEdtB,EAAA,GA0KI,OA9JOA,GAAA,EAAUd,EAAW,UAAaA,GAGzCzE,OAAewC,eAAUiC,EAAQ,QAClC9B,IACF+B,IAuBUa,EAAA,EAAIpB,EAAO,MAAmBK,GAmI7CC,EAKA,QAAAtB,GAA6B2D,EAA8BtB,GACzD,KAAeuB,GAAOC,OAAKF,EAC7BtB,GH5UAxF,OAAOwC,eAAeY,EAAqB,cAAgB6D,OAAO,GAG7C,IAAIP,GAA2C5H,EAAoB,IAC/D8H,EAAwC9H,EAAoB,IAC5DwH,EAA+CxH,EAAoB,GGrP1FyG,EAAAzG,EAAA,IA6MYuF,EAAG,SAAY6C,EAAKC,GAC1B,MAAOnH,QAAUC,UAAeC,eAAKb,KAAI6H,EACjDC,IAEwB/C,EAAe,YAIrBgD,KAMlB5C,EAAA,WAYE,QAAAA,GAAoCD,EACZlC,EACwBgF,GAA5B5D,KAAS4D,EAAmBA,EAXxC5D,KAAU6D,GAAS,EACnB7D,KAAS8D,KAWX9D,KAAM+D,EAAQnF,EACdoB,KAASgE,EAAWlC,EAAA,EAA2BhB,GAC/Cd,KAAS+C,UACHkB,OAAE,WAAM,MAAI,OACVC,SAAE,WAAM,MAAWrB,GAAA,EAAQpF,QAAM,OACrB0G,qBAAE,SAAuCC,GAC/CT,EAAKrH,KAAW8H,GAEpB7F,WAAC,WAAM,MAAQ6F,GAAM,OACjC,IACyBC,wBAAE,SAASD,GACpBT,IAAwBW,OAAC,SAAQC,GAAI,MAAQA,KAAaH,MA0GhF,MArGE7H,QAAAwC,eAAIgC,EAAAvE,UAAI,QHwDF0C,IGxDN,WAEQ,MADFc,MAAmBwE,IACZxE,KACb+D,GHyDM9E,YAAY,EACZD,cG1DL,IAEDzC,OAAAwC,eAAIgC,EAAAvE,UAAO,WH2DL0C,IG3DN,WAEQ,MADFc,MAAmBwE,IACZxE,KACbgE,GH4DM/E,YAAY,EACZD,cG7DL,IAED+B,EAAAvE,UAAMiI,OAAN,cAAAC,GAqBC1E,IApBO,WAAgB6C,GAAA,EAAC,SAAQpF,GACzBiH,EAAmBF,IAEzB/G,MACOkH,KAAC,WACAD,EAAUd,EAASb,SAAUxC,UAAKmE,EAAQX,EAC9C,IAAYa,KAMN,OALArI,QAAK2E,KAAKwD,EAAWZ,GAAQnC,QAAC,SAAWkD,GACvCtI,OAAK2E,KAAKwD,EAAUZ,EAAae,IAAQlD,QAAC,SAAYmD,GAClDF,EAAKtI,KAAKoI,EAAUZ,EAAYe,GAC1CC,QAEIjC,EAAA,EAAgBkC,IAAAH,EAAazD,IAAC,SAAQ6D,GACpC,MAAQA,GAAUjC,SAC1B0B,cAEGE,KAAC,WACAD,EAAWb,GAAQ,EACnBa,EAAUZ,QAkBpB/C,EAAAvE,UAAW0F,EAAX,SAAwBtD,EAAiDqG,GAOpE,OAPqB,KAAAA,MAA+CtE,GACnEX,KAAmBwE,IAEdxE,KAAU8D,EAAOlF,KACpBoB,KAAU8D,EAAMlF,QAGboB,KAAU8D,EAAMlF,GAAqBqG,GAAE,CAK9C,GAAuBC,GAAqBD,IAAuBtE,EAAqBsE,MAAa3H,GACxF0H,EAAOhF,KAAU4D,EAASb,SAAUtB,UAAM7C,GAAKoB,KAAMA,KAAUmF,UAAKhD,KAAMnC,MAAqBkF,EACxGlF,MAAU8D,EAAMlF,GAAoBqG,GAC1CD,EAEM,MAAKhF,MAAU8D,EAAMlF,GAC7BqG,IAMQlE,EAAAvE,UAAS2I,UAAjB,SAA8C7C,GAA9C,GAAAoC,GAmBC1E,IAjBW8B,GAAA,EAAK9B,KAASsC,GAWfA,EAASS,UAAST,EAASS,SAAsBoB,uBAC1CR,EAAQhC,QAAC,SAAQ4C,GACzBG,EAAS3B,SAAqBoB,qBACpCI,KACcZ,OAQV5C,EAAAvE,UAAegI,EAAvB,WACUxE,KAAY6D,GACbnE,EAAc,eAASd,KAAMoB,KACpC+D,KAEHhD,IAIcA,GAAUvE,UAAKoC,MACbmC,EAAUvE,UAAQsE,SAClBC,EAAUvE,UAAOiI,QACzBhF,QAAI2F,IAAO,KA0NpB,IAAUC,IACAC,SAAmD,iFAE7CC,eAA+B,6BAC9BC,gBAAiD,8CACnDC,cAAkD,+CAC5CC,oBAAyD,sDAC1DC,mBAAiD,0LAI7CC,uBAAqD,2EAIhEtC,EAAG,GAAgBH,GAAA,EAAgB,MAAY,WAAUkC,GCvkBxDpK,EAAgDqF,GAE9DX,GAAA,WJ+mBO,CACA,CACA,CACA,CAED,SAAUlE,EAAQkE,EAAqBtE,GAE7C,YKrlBAA,GAAAsD,EAAAgB,EAAA,qBAAAuD,IAAA,IAAgB2C,GAAmB,gBAMdC,EACLzI,MAAmByI,kBAuBnCC,EAAA,WAIE,QAAAA,GAA+B1C,EACG2C,GAG7B,GAJchG,KAAIqD,KAAQA,EACZrD,KAAOgG,QAAQA,EAGVF,EAEHA,EAAK9F,KAAckD,EAAU1G,UAChD+G,YAAQ,CACN,GAAO0C,GAAQ5I,MAAM+E,MAAKpC,KAAaiC,UACnCjC,MAAKpB,KAAciH,EAEjBtJ,OAAewC,eAAKiB,KAAS,SAC9Bd,IAAE,WACG,MAAI+G,GACZC,UAIR,MAACH,KAGYA,GAAUvJ,UAASD,OAAOgH,OAAMlG,MAA6Bb,WAC7DuJ,EAAUvJ,UAAY2J,YAAiBJ,EACtCA,EAAkBvJ,UAAKoC,KAAciH,CAEnD,IAAA3C,GAAA,WAIE,QAAAA,GAAmC8B,EACIxC,EACC6C,GAFpBrF,KAAOgF,QAAQA,EACfhF,KAAWwC,YAAQA,EACnBxC,KAAMqF,OAAcA,EAJjCrF,KAAOoG,QAAkB,gBA2ClC,MAnCElD,GAAA1G,UAAM+G,OAAN,SAAcF,EAAqCgD,OAC1B/I,KAAf+I,IACFA,KAGN,IAGoBL,GAHRM,EAAOtG,KAAOqF,OAAmBhC,GAEjCkD,EAAOvG,KAAQgF,QAAM,IAAQ3B,CAIhC2C,OADkB1I,KAAfgJ,EAEZ,QACSA,EAAmBE,QAAKxG,KAAQoG,QAAE,SAAMK,EAAK/C,GAClD,GAASF,GAAQ6C,EAAM3C,EACjB,YAAoBpG,KAAdkG,EAAsBA,KAC3B,IAAME,EACf,OAIKsC,EAAOhG,KAAYwC,YAAO,KAAUwD,EAAO,KAAWO,EAAQ,IACrE,IAAO/G,GAAG,GAAiBuG,GAASQ,EAAWP,EAI3C,KAAC,GAAQU,KAASL,GACXA,EAAe5J,eAAMiK,IAA2B,MAAnBA,EAAMC,OAAI,KAGpCnH,EAAMkH,GAAOL,EAC3BK,GAEM,OACRlH,IACD0D,ML8jBO,CACA,CAEF,SAAUzH,EAAQkE,EAAqBtE,GAE7C,YMlqBM,SAAA2H,GAAkD4D,EACMC,GAE5D,GAASC,GAAG,GAAiBC,GAAYH,EAAiBC,EACpD,OAAMC,GAAUE,UAAK7E,KAC7B2E,GAyMA,QAAAG,GAAsCxD,EAAmByD,GACpD,GAAyB,gBAAb,KAAAzD,EAAA,YAAA0D,EAAA1D,KAA8B,OAAVA,EAC3B,OACR,CAEI,KAAe,GAAAzB,GAAO,EAAPoF,EAAOF,EAAPlF,EAAAoF,EAAOhL,OAAA4F,IAAA,CAArB,GAAUqF,GAAAD,EAAApF,EACV,IAAOqF,IAAO5D,IAAsC,kBAAxBA,GAAQ4D,GAC/B,OACR,EAGI,OACR,EAEA,QAAAC,MNuciC3H,EAAuB,EAAIqD,CAEvC,IAAIuE,GAA+ClM,EAAoB,GACxF8L,EAA4B,kBAAXK,SAAoD,gBAApBA,QAAOC,SAAwB,SAAUhE,GAAO,aAAcA,IAAS,SAAUA,GAAO,MAAOA,IAAyB,kBAAX+D,SAAyB/D,EAAI0C,cAAgBqB,QAAU/D,IAAQ+D,OAAOhL,UAAY,eAAkBiH,IM3pBtQsD,EAAA,WAeE,QAAAA,GAAiCH,EAA6BC,GAA9D,GAAAnC,GAYC1E,IA1BOA,MAAS0H,aACT1H,KAAY2H,gBAEZ3H,KAAa4H,cAAK,EAElB5H,KAAI6H,KAAcN,EAAA,EAAW9J,UAC7BuC,KAAS8H,WAAS,EASpB9H,KAAc6G,cAAiBA,EAI/B7G,KAAK6H,KACFlD,KAAC,WACIiC,EACVlC,KACMrE,MAAC,SAAExD,GACH6H,EAAMhF,MACZ7C,KAqJN,MAlJEkK,GAAAvK,UAAIuL,KAAJ,SAAavE,GACPxD,KAAgBgI,gBAAC,SAAsBC,GACjCA,EAAKF,KACfvE,MAGFuD,EAAAvK,UAAKkD,MAAL,SAAkBA,GACZM,KAAgBgI,gBAAC,SAAsBC,GACjCA,EAAMvI,MAChBA,KACIM,KAAMkI,MACZxI,IAEAqH,EAAAvK,UAAQ2L,SAAR,WACMnI,KAAgBgI,gBAAC,SAAsBC,GACjCA,EACVE,aACInI,KACNkI,SAQAnB,EAAAvK,UAASwK,UAAT,SAAuDoB,EAC9B1I,EACMyI,GAF/B,GAI4BF,GAJ5BvD,EAuDC1E,IAjDI,QAA6B1C,KAAd8K,OAAqC9K,KAAdoC,OACdpC,KAAf6K,EACV,KAAe9K,OACjB,oBAIU4K,GADchB,EAAemB,GAAS,OAAS,QAAe,aAExEA,GAEQL,KAAsCK,EACrC1I,MAAOA,EACJyI,SAEZA,OAEgC7K,KAApB2K,EAAKF,OACPE,EAAKF,KACfT,OACiChK,KAArB2K,EAAMvI,QACRuI,EAAMvI,MAChB4H,OACoChK,KAAxB2K,EAASE,WACXF,EAASE,SACnBb,EAEA,IAASe,GAAOrI,KAAesI,eAAKnG,KAAKnC,KAAMA,KAAW0H,UAAStL,OAsB7D,OAjBE4D,MAAW8H,WACb9H,KAAK6H,KAAKlD,KAAC,WACb,IACUD,EAAY6D,WACVN,EAAMvI,MAAKgF,EACrB6D,YACUN,EACVE,WACM,MAAGtL,OAOXmD,KAAW0H,UAAKpL,KAA0B2L,GAGhDI,GAIQtB,EAAAvK,UAAc8L,eAAtB,SAAgC5M,OACE4B,KAAxB0C,KAAU0H,eAAkDpK,KAA5B0C,KAAU0H,UAAGhM,WAI1CsE,MAAU0H,UAAIhM,GAErBsE,KAAc4H,eAAM,EACI,IAApB5H,KAAc4H,mBAA2CtK,KAA7B0C,KAAc6G,eAC5C7G,KAAc6G,cACpB7G,QAGM+G,EAAAvK,UAAewL,gBAAvB,SAA2DQ,GACtD,IAAKxI,KAAW8H,UAOf,IAAC,GAAKpM,GAAI,EAAGA,EAAOsE,KAAW0H,UAAOtL,OAAKV,IACzCsE,KAAQyI,QAAE/M,EAChB8M,IAMMzB,EAAAvK,UAAOiM,QAAf,SAAyB/M,EAAqC8M,GAA9D,GAAA9D,GAgBC1E,IAdKA,MAAK6H,KAAKlD,KAAC,WACV,OAA6BrH,KAAxBoH,EAAUgD,eAAkDpK,KAA5BoH,EAAUgD,UAAGhM,GACnD,IACI8M,EAAK9D,EAAUgD,UACnBhM,IAAQ,MAAGmB,GAIyB,mBAAhB4C,UAA2BA,QAAOC,OAC3CD,QAAMC,MACf7C,OAMAkK,EAAAvK,UAAK0L,MAAb,SAAyB1I,GAAzB,GAAAkF,GAaC1E,IAZSA,MAAW8H,YAGf9H,KAAU8H,WAAQ,MACAxK,KAAfkC,IACDQ,KAAWuI,WACjB/I,GAEIQ,KAAK6H,KAAKlD,KAAC,WACTD,EAAUgD,cAAapK,GACvBoH,EAAcmC,kBACpBvJ,OAEHyJ,MN8rBK,SAAUtL,EAAQkE,EAAqBtE,GAE7C,cAC4B,SAASqN,GO/6BnCrN,EAAAsD,EAAAgB,EAAA,qBAAAgJ,IAEF,IAAUC,EAEP,QAA+B,KAAjBF,EACRE,EACTF,MAAM,IAAiC,mBAAjBvN,MACbyN,EACTzN,SACI,KACSyN,EAAWC,SACpB,iBAAQ,MAAGhM,GACP,KAAeQ,OACnB,4EAGG,GAAiBsL,GAASC,IP47BJhN,KAAK+D,EAAqBtE,EAAoB,MAIrE,SAAUI,EAAQD,GQ99BxB,GAAAsN,EAGAA,GAAA,WACA,MAAA9I,QAGA,KAEA8I,KAAAD,SAAA,qBAAAE,MAAA,QACC,MAAAlM,GAED,gBAAA3B,KACA4N,EAAA5N,GAOAO,EAAAD,QAAAsN,GRq+BM,SAAUrN,EAAQD,GS9+BxB,QAAAwN,KACA,KAAA3L,OAAA,mCAEA,QAAA4L,KACA,KAAA5L,OAAA,qCAsBA,QAAA6L,GAAAC,GACA,GAAAC,IAAA7K,WAEA,MAAAA,YAAA4K,EAAA,EAGA,KAAAC,IAAAJ,IAAAI,IAAA7K,WAEA,MADA6K,GAAA7K,WACAA,WAAA4K,EAAA,EAEA,KAEA,MAAAC,GAAAD,EAAA,GACK,MAAAtM,GACL,IAEA,MAAAuM,GAAAxN,KAAA,KAAAuN,EAAA,GACS,MAAAtM,GAET,MAAAuM,GAAAxN,KAAAoE,KAAAmJ,EAAA,KAMA,QAAAE,GAAAC,GACA,GAAAC,IAAArM,aAEA,MAAAA,cAAAoM,EAGA,KAAAC,IAAAN,IAAAM,IAAArM,aAEA,MADAqM,GAAArM,aACAA,aAAAoM,EAEA,KAEA,MAAAC,GAAAD,GACK,MAAAzM,GACL,IAEA,MAAA0M,GAAA3N,KAAA,KAAA0N,GACS,MAAAzM,GAGT,MAAA0M,GAAA3N,KAAAoE,KAAAsJ,KAYA,QAAAE,KACAC,GAAAC,IAGAD,GAAA,EACAC,EAAAtN,OACAuN,EAAAD,EAAAE,OAAAD,GAEAE,GAAA,EAEAF,EAAAvN,QACA0N,KAIA,QAAAA,KACA,IAAAL,EAAA,CAGA,GAAAtM,GAAA+L,EAAAM,EACAC,IAAA,CAGA,KADA,GAAAM,GAAAJ,EAAAvN,OACA2N,GAAA,CAGA,IAFAL,EAAAC,EACAA,OACAE,EAAAE,GACAL,GACAA,EAAAG,GAAAG,KAGAH,IAAA,EACAE,EAAAJ,EAAAvN,OAEAsN,EAAA,KACAD,GAAA,EACAJ,EAAAlM,IAiBA,QAAA8M,GAAAd,EAAAe,GACAlK,KAAAmJ,MACAnJ,KAAAkK,QAYA,QAAA5C,MAhKA,GAOA8B,GACAG,EARAY,EAAA1O,EAAAD,YAgBA,WACA,IAEA4N,EADA,kBAAA7K,YACAA,WAEAyK,EAEK,MAAAnM,GACLuM,EAAAJ,EAEA,IAEAO,EADA,kBAAArM,cACAA,aAEA+L,EAEK,MAAApM,GACL0M,EAAAN,KAuDA,IAEAS,GAFAC,KACAF,GAAA,EAEAI,GAAA,CAyCAM,GAAAC,SAAA,SAAAjB,GACA,GAAApH,GAAAsI,MAAApI,UAAA7F,OAAA,EACA,IAAA6F,UAAA7F,OAAA,EACA,OAAAV,GAAA,EAAuBA,EAAAuG,UAAA7F,OAAsBV,IAC7CqG,EAAArG,EAAA,GAAAuG,UAAAvG,EAGAiO,GAAArN,KAAA,GAAA2N,GAAAd,EAAApH,IACA,IAAA4H,EAAAvN,QAAAqN,GACAP,EAAAY,IASAG,EAAAzN,UAAAwN,IAAA,WACAhK,KAAAmJ,IAAA/G,MAAA,KAAApC,KAAAkK,QAEAC,EAAAG,MAAA,UACAH,EAAAI,SAAA,EACAJ,EAAAK,OACAL,EAAAM,QACAN,EAAAO,QAAA,GACAP,EAAAQ,YAIAR,EAAAS,GAAAtD,EACA6C,EAAAU,YAAAvD,EACA6C,EAAAW,KAAAxD,EACA6C,EAAAY,IAAAzD,EACA6C,EAAAa,eAAA1D,EACA6C,EAAAc,mBAAA3D,EACA6C,EAAAe,KAAA5D,EACA6C,EAAAgB,gBAAA7D,EACA6C,EAAAiB,oBAAA9D,EAEA6C,EAAAkB,UAAA,SAAAzM,GAAqC,UAErCuL,EAAAmB,QAAA,SAAA1M,GACA,KAAAvB,OAAA,qCAGA8M,EAAAoB,IAAA,WAA2B,WAC3BpB,EAAAqB,MAAA,SAAAC,GACA,KAAApO,OAAA,mCAEA8M,EAAAuB,MAAA,WAA4B,WTggCtB,SAAUjQ,EAAQkE,EAAqBtE,GAE7C,YUtqCM,SAAAsQ,GAA8BnI,GAC5B,MAAWJ,OAAU9F,GAC7BkG,GAcM,QAAAJ,GAAgCwI,EAAaC,GAC9C,KAASA,YAAoBtP,SACxB,MACRsP,EAEO,QAAOA,EAAe1F,aAC7B,IAAS2F,MAGP,GAAaC,GAA2BF,CAClC,OAAC,IAAQC,MAAUC,EAAYC,UAEvC,KAAWzP,YACgBe,KAAfsO,IACFA,KAEF,MAER,KAAUvB,OAEFuB,IACA,MAER,SAEQ,MACPC,GAEG,IAAC,GAAQnF,KAAWmF,GACXA,EAAepP,eAAOiK,KAG3BkF,EAAMlF,GAAatD,EAAOwI,EAAMlF,GAAQmF,EAChDnF,IAEM,OACRkF,GAGM,QAAAK,GAAgCxI,EAAciD,EAAYlD,GAC3DC,EAAMiD,GACXlD,EV8mCiC7D,EAAuB,EAAIgM,EAC3BhM,EAAuB,EAAIyD,EU7qC1DzD,EAAA,EAAAsM,GVmwCM,CAEF,SAAUxQ,EAAQD,EAASH,IWnxCjC,SAAA6Q,IAAA,SAAAC,GAMA,QAAA7E,MAGA,QAAAnF,GAAAqG,EAAA4D,GACA,kBACA5D,EAAApG,MAAAgK,EAAAnK,YAIA,QAAAzE,GAAAgL,GACA,mBAAAxI,MAAA,SAAAqM,WAAA,uCACA,sBAAA7D,GAAA,SAAA6D,WAAA,iBACArM,MAAAsM,EAAA,EACAtM,KAAAuM,GAAA,EACAvM,KAAAwM,MAAAlP,GACA0C,KAAAyM,KAEAC,EAAAlE,EAAAxI,MAGA,QAAA2M,GAAAxR,EAAAyR,GACA,SAAAzR,EAAAmR,GACAnR,IAAAqR,CAEA,QAAArR,EAAAmR,EAEA,WADAnR,GAAAsR,EAAAnQ,KAAAsQ,EAGAzR,GAAAoR,GAAA,EACA/O,EAAAqP,EAAA,WACA,GAAAC,GAAA,IAAA3R,EAAAmR,EAAAM,EAAAG,YAAAH,EAAAI,UACA,WAAAF,EAEA,YADA,IAAA3R,EAAAmR,EAAA7O,EAAAE,GAAAiP,EAAAlP,QAAAvC,EAAAqR,EAGA,IAAAS,EACA,KACAA,EAAAH,EAAA3R,EAAAqR,GACO,MAAA3P,GAEP,WADAc,GAAAiP,EAAAlP,QAAAb,GAGAY,EAAAmP,EAAAlP,QAAAuP,KAIA,QAAAxP,GAAAtC,EAAA+R,GACA,IAEA,GAAAA,IAAA/R,EAAA,SAAAkR,WAAA,4CACA,IAAAa,IAAA,gBAAAA,IAAA,kBAAAA,IAAA,CACA,GAAAvI,GAAAuI,EAAAvI,IACA,IAAAuI,YAAA1P,GAIA,MAHArC,GAAAmR,EAAA,EACAnR,EAAAqR,EAAAU,MACAC,GAAAhS,EAES,sBAAAwJ,GAET,WADA+H,GAAAvK,EAAAwC,EAAAuI,GAAA/R,GAIAA,EAAAmR,EAAA,EACAnR,EAAAqR,EAAAU,EACAC,EAAAhS,GACK,MAAA0B,GACLc,EAAAxC,EAAA0B,IAIA,QAAAc,GAAAxC,EAAA+R,GACA/R,EAAAmR,EAAA,EACAnR,EAAAqR,EAAAU,EACAC,EAAAhS,GAGA,QAAAgS,GAAAhS,GACA,IAAAA,EAAAmR,GAAA,IAAAnR,EAAAsR,EAAArQ,QACAoB,EAAAqP,EAAA,WACA1R,EAAAoR,GACA/O,EAAA4P,EAAAjS,EAAAqR,IAKA,QAAA9Q,GAAA,EAAAqO,EAAA5O,EAAAsR,EAAArQ,OAAiDV,EAAAqO,EAASrO,IAC1DiR,EAAAxR,IAAAsR,EAAA/Q,GAEAP,GAAAsR,EAAA,KAGA,QAAAY,GAAAN,EAAAC,EAAAtP,GACAsC,KAAA+M,YAAA,kBAAAA,KAAA,KACA/M,KAAAgN,WAAA,kBAAAA,KAAA,KACAhN,KAAAtC,UASA,QAAAgP,GAAAlE,EAAArN,GACA,GAAAmS,IAAA,CACA,KACA9E,EAAA,SAAAhF,GACA8J,IACAA,GAAA,EACA7P,EAAAtC,EAAAqI,KACO,SAAA+J,GACPD,IACAA,GAAA,EACA3P,EAAAxC,EAAAoS,MAEK,MAAAC,GACL,GAAAF,EAAA,MACAA,IAAA,EACA3P,EAAAxC,EAAAqS,IAxHA,GAAAC,GAAAlP,UA4HAf,GAAAhB,UAAA,eAAAwQ,GACA,MAAAhN,MAAA2E,KAAA,KAAAqI,IAGAxP,EAAAhB,UAAAmI,KAAA,SAAAoI,EAAAC,GACA,GAAAU,GAAA,GAAA1N,MAAA,YAAAsH,EAGA,OADAqF,GAAA3M,KAAA,GAAAqN,GAAAN,EAAAC,EAAAU,IACAA,GAGAlQ,EAAAuH,IAAA,SAAA4I,GACA,GAAA5L,GAAAsI,MAAA7N,UAAAmK,MAAA/K,KAAA+R,EAEA,WAAAnQ,GAAA,SAAAC,EAAAE,GAIA,QAAAiQ,GAAAlS,EAAAmS,GACA,IACA,GAAAA,IAAA,gBAAAA,IAAA,kBAAAA,IAAA,CACA,GAAAlJ,GAAAkJ,EAAAlJ,IACA,sBAAAA,GAIA,WAHAA,GAAA/I,KAAAiS,EAAA,SAAAA,GACAD,EAAAlS,EAAAmS,IACelQ,GAIfoE,EAAArG,GAAAmS,EACA,KAAAC,GACArQ,EAAAsE,GAES,MAAAyL,GACT7P,EAAA6P,IAnBA,OAAAzL,EAAA3F,OAAA,MAAAqB,MAuBA,QAtBAqQ,GAAA/L,EAAA3F,OAsBAV,EAAA,EAAqBA,EAAAqG,EAAA3F,OAAiBV,IACtCkS,EAAAlS,EAAAqG,EAAArG,OAKA8B,EAAAC,QAAA,SAAA+F,GACA,MAAAA,IAAA,gBAAAA,MAAA2C,cAAA3I,EACAgG,EAGA,GAAAhG,GAAA,SAAAC,GACAA,EAAA+F,MAIAhG,EAAAG,OAAA,SAAA6F,GACA,UAAAhG,GAAA,SAAAC,EAAAE,GACAA,EAAA6F,MAIAhG,EAAAuQ,KAAA,SAAAC,GACA,UAAAxQ,GAAA,SAAAC,EAAAE,GACA,OAAAjC,GAAA,EAAAqO,EAAAiE,EAAA5R,OAA0CV,EAAAqO,EAASrO,IACnDsS,EAAAtS,GAAAiJ,KAAAlH,EAAAE,MAMAH,EAAAqP,EAAA,kBAAAX,IAAA,SAAA1D,GAA+E0D,EAAA1D,KAC/E,SAAAA,GACAiF,EAAAjF,EAAA,IAGAhL,EAAA4P,EAAA,SAAA5N,GACA,mBAAAC,mBACAA,QAAAwO,KAAA,wCAAAzO,IASAhC,EAAA0Q,EAAA,SAAA1F,GACAhL,EAAAqP,EAAArE,GAQAhL,EAAA2Q,EAAA,SAAA3F,GACAhL,EAAA4P,EAAA5E,OAGA,KAAA/M,KAAAD,QACAC,EAAAD,QAAAgC,EACG2O,EAAA3O,UACH2O,EAAA3O,YAGCwC,QXuxC4BpE,KAAKJ,EAASH,EAAoB,IAAI6Q,eAI7D,SAAUzQ,EAAQD,EAASH,GYl/CjC,QAAA+S,GAAAC,EAAAC,GACAtO,KAAAuO,EAAAF,EACArO,KAAAwO,EAAAF,EAnBA,GAAAlM,GAAAyG,SAAArM,UAAA4F,KAIA5G,GAAA+C,WAAA,WACA,UAAA6P,GAAAhM,EAAAxG,KAAA2C,WAAArD,EAAA+G,WAAA/E,eAEA1B,EAAAiT,YAAA,WACA,UAAAL,GAAAhM,EAAAxG,KAAA6S,YAAAvT,EAAA+G,WAAAyM,gBAEAlT,EAAA0B,aACA1B,EAAAkT,cAAA,SAAAvR,GACAA,GACAA,EAAA+K,SAQAkG,EAAA5R,UAAAmS,MAAAP,EAAA5R,UAAAoS,IAAA,aACAR,EAAA5R,UAAA0L,MAAA,WACAlI,KAAAwO,EAAA5S,KAAAV,EAAA8E,KAAAuO,IAIA/S,EAAAqT,OAAA,SAAAC,EAAAC,GACA7R,aAAA4R,EAAAE,GACAF,EAAAG,EAAAF,GAGAvT,EAAA0T,SAAA,SAAAJ,GACA5R,aAAA4R,EAAAE,GACAF,EAAAG,GAAA,GAGAzT,EAAA2T,EAAA3T,EAAA4T,OAAA,SAAAN,GACA5R,aAAA4R,EAAAE,EAEA,IAAAD,GAAAD,EAAAG,CACAF,IAAA,IACAD,EAAAE,EAAAzQ,WAAA,WACAuQ,EAAAO,GACAP,EAAAO,KACKN,KAKL1T,EAAA,IACAG,EAAA0Q,0BACA1Q,EAAA8T,+BZ0gDM,SAAU7T,EAAQD,EAASH,Ia9jDjC,SAAAqN,EAAAyB,IAAA,SAAAzB,EAAApL,GACA,YAYA,SAAA4O,GAAA9H,GAEA,kBAAAA,KACAA,EAAAyE,SAAA,GAAAzE,GAIA,QADArC,GAAAsI,MAAApI,UAAA7F,OAAA,GACAV,EAAA,EAAqBA,EAAAqG,EAAA3F,OAAiBV,IACtCqG,EAAArG,GAAAuG,UAAAvG,EAAA,EAGA,IAAAmM,IAAkBzD,WAAArC,OAGlB,OAFAwN,GAAAC,GAAA3H,EACA4H,EAAAD,GACAA,IAGA,QAAAF,GAAA3C,SACA4C,GAAA5C,GAGA,QAAA3C,GAAAnC,GACA,GAAAzD,GAAAyD,EAAAzD,SACArC,EAAA8F,EAAA9F,IACA,QAAAA,EAAA3F,QACA,OACAgI,GACA,MACA,QACAA,EAAArC,EAAA,GACA,MACA,QACAqC,EAAArC,EAAA,GAAAA,EAAA,GACA,MACA,QACAqC,EAAArC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GACA,MACA,SACAqC,EAAAhC,MAAA9E,EAAAyE,IAKA,QAAA2N,GAAA/C,GAGA,GAAAgD,EAGApR,WAAAmR,EAAA,EAAA/C,OACS,CACT,GAAA9E,GAAA0H,EAAA5C,EACA,IAAA9E,EAAA,CACA8H,GAAA,CACA,KACA3F,EAAAnC,GACiB,QACjByH,EAAA3C,GACAgD,GAAA,KApEA,IAAAjH,EAAAwD,aAAA,CAIA,GAIAuD,GAJAD,EAAA,EACAD,KACAI,GAAA,EACAC,EAAAlH,EAAA7K,SAoJAgS,EAAAtT,OAAAuT,gBAAAvT,OAAAuT,eAAApH,EACAmH,QAAAtR,WAAAsR,EAAAnH,EAGU,wBAAAqH,SAAAnU,KAAA8M,EAAAyB,SArFV,WACAsF,EAAA,SAAA9C,GACAxC,EAAAC,SAAA,WAA0CsF,EAAA/C,SAI1C,WAGA,GAAAjE,EAAAsH,cAAAtH,EAAAuH,cAAA,CACA,GAAAC,IAAA,EACAC,EAAAzH,EAAA0H,SAMA,OALA1H,GAAA0H,UAAA,WACAF,GAAA,GAEAxH,EAAAsH,YAAA,QACAtH,EAAA0H,UAAAD,EACAD,MAIA,WAKA,GAAAG,GAAA,gBAAAC,KAAAC,SAAA,IACAC,EAAA,SAAAC,GACAA,EAAA5E,SAAAnD,GACA,gBAAA+H,GAAApK,MACA,IAAAoK,EAAApK,KAAAqK,QAAAL,IACAX,GAAAe,EAAApK,KAAAM,MAAA0J,EAAAjU,SAIAsM,GAAAiI,iBACAjI,EAAAiI,iBAAA,UAAAH,GAAA,GAEA9H,EAAAkI,YAAA,YAAAJ,GAGAf,EAAA,SAAA9C,GACAjE,EAAAsH,YAAAK,EAAA1D,EAAA,SAmDKjE,EAAAmI,eA/CL,WACA,GAAAC,GAAA,GAAAD,eACAC,GAAAC,MAAAX,UAAA,SAAAK,GAEAf,EADAe,EAAApK,OAIAoJ,EAAA,SAAA9C,GACAmE,EAAAE,MAAAhB,YAAArD,OA2CKiD,GAAA,sBAAAA,GAAA7R,cAAA,UAvCL,WACA,GAAAkT,GAAArB,EAAAsB,eACAzB,GAAA,SAAA9C,GAGA,GAAA5P,GAAA6S,EAAA7R,cAAA,SACAhB,GAAAoU,mBAAA,WACAzB,EAAA/C,GACA5P,EAAAoU,mBAAA,KACAF,EAAAG,YAAArU,GACAA,EAAA,MAEAkU,EAAAzS,YAAAzB,OAIA,WACA0S,EAAA,SAAA9C,GACApO,WAAAmR,EAAA,EAAA/C,OA8BAkD,EAAA3D,eACA2D,EAAAP,mBACC,mBAAAnU,UAAA,KAAAuN,EAAA1I,KAAA0I,EAAAvN,QbkkD4BS,KAAKJ,EAASH,EAAoB,IAAKA,EAAoB,WAIzEgW;;Ac/vDf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChRA,IACUC,sBAAsB,IAE1B,SAAU7V,EAAQkE,EAAqBtE,GAE7C,YAC+BA,GAAoBsD,EAAEgB,EAAqB,IAAK,WAAa,MAAO4R,KACpElW,EAAoBsD,EAAEgB,EAAqB,IAAK,WAAa,MAAO6R,ICOjG,IAAAC,GAAApW,EAAA,GASiBkW,EAAG,SAAkBG,EAAS1L,GAC5C,IAAY0L,EACb,KAAoBF,GACtBxL,IAQyBwL,EAAG,SAAgBxL,GACtC,MAAU3I,OAAsB,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","file":"firebase.js","sourcesContent":["var firebase = (function() {\n var window = typeof window === 'undefined' ? self : window;\n return /******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonpFirebase\"];\n/******/ \twindow[\"webpackJsonpFirebase\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId]) {\n/******/ \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n/******/ \t\t\t}\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n/******/ \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n/******/ \t\twhile(resolves.length) {\n/******/ \t\t\tresolves.shift()();\n/******/ \t\t}\n/******/ \t\tif(executeModules) {\n/******/ \t\t\tfor(i=0; i < executeModules.length; i++) {\n/******/ \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\treturn result;\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// objects to store loaded and loading chunks\n/******/ \tvar installedChunks = {\n/******/ \t\t3: 0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId) {\n/******/ \t\tvar installedChunkData = installedChunks[chunkId];\n/******/ \t\tif(installedChunkData === 0) {\n/******/ \t\t\treturn new Promise(function(resolve) { resolve(); });\n/******/ \t\t}\n/******/\n/******/ \t\t// a Promise means \"currently loading\".\n/******/ \t\tif(installedChunkData) {\n/******/ \t\t\treturn installedChunkData[2];\n/******/ \t\t}\n/******/\n/******/ \t\t// setup Promise in chunk cache\n/******/ \t\tvar promise = new Promise(function(resolve, reject) {\n/******/ \t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n/******/ \t\t});\n/******/ \t\tinstalledChunkData[2] = promise;\n/******/\n/******/ \t\t// start chunk loading\n/******/ \t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\tvar script = document.createElement('script');\n/******/ \t\tscript.type = 'text/javascript';\n/******/ \t\tscript.charset = 'utf-8';\n/******/ \t\tscript.async = true;\n/******/ \t\tscript.timeout = 120000;\n/******/\n/******/ \t\tif (__webpack_require__.nc) {\n/******/ \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n/******/ \t\t}\n/******/ \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".js\";\n/******/ \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n/******/ \t\tscript.onerror = script.onload = onScriptComplete;\n/******/ \t\tfunction onScriptComplete() {\n/******/ \t\t\t// avoid mem leaks in IE.\n/******/ \t\t\tscript.onerror = script.onload = null;\n/******/ \t\t\tclearTimeout(timeout);\n/******/ \t\t\tvar chunk = installedChunks[chunkId];\n/******/ \t\t\tif(chunk !== 0) {\n/******/ \t\t\t\tif(chunk) {\n/******/ \t\t\t\t\tchunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n/******/ \t\t\t\t}\n/******/ \t\t\t\tinstalledChunks[chunkId] = undefined;\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t\thead.appendChild(script);\n/******/\n/******/ \t\treturn promise;\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// on error function for async loading\n/******/ \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 5);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */,\n/* 1 */,\n/* 2 */,\n/* 3 */,\n/* 4 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return PromiseImpl; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Deferred; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return attachDummyErrorHandler; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_globalScope__ = __webpack_require__(14);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\nvar PromiseImpl = __WEBPACK_IMPORTED_MODULE_0__utils_globalScope__[\"a\" /* globalScope */].Promise || __webpack_require__(19);\n/**\r\n * A deferred promise implementation.\r\n */\nvar Deferred = function () {\n /** @constructor */\n function Deferred() {\n var self = this;\n this.resolve = null;\n this.reject = null;\n this.promise = new PromiseImpl(function (resolve, reject) {\n self.resolve = resolve;\n self.reject = reject;\n });\n }\n /**\r\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\r\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\r\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\r\n * @param {((?function(?(Error)): (?|undefined))| (?function(?(Error),?=): (?|undefined)))=} opt_nodeCallback\r\n * @return {!function(?(Error), ?=)}\r\n */\n Deferred.prototype.wrapCallback = function (opt_nodeCallback) {\n var self = this;\n /**\r\n * @param {?Error} error\r\n * @param {?=} opt_value\r\n */\n function meta(error, opt_value) {\n if (error) {\n self.reject(error);\n } else {\n self.resolve(opt_value);\n }\n if (typeof opt_nodeCallback === 'function') {\n attachDummyErrorHandler(self.promise);\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (opt_nodeCallback.length === 1) {\n opt_nodeCallback(error);\n } else {\n opt_nodeCallback(error, opt_value);\n }\n }\n }\n return meta;\n };\n return Deferred;\n}();\n\n;\n/**\r\n * Chrome (and maybe other browsers) report an Error in the console if you reject a promise\r\n * and nobody handles the error. This is normally a good thing, but this will confuse devs who\r\n * never intended to use promises in the first place. So in some cases (in particular, if the\r\n * developer attached a callback), we should attach a dummy resolver to the promise to suppress\r\n * this error.\r\n *\r\n * Note: We can't do this all the time, since it breaks the Promise spec (though in the obscure\r\n * 3.3.3 section related to upgrading non-compliant promises).\r\n * @param {!firebase.Promise} promise\r\n */\nvar attachDummyErrorHandler = function attachDummyErrorHandler(promise) {\n promise.catch(function () {});\n};\n\n/***/ }),\n/* 5 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n\n// CONCATENATED MODULE: ./src/app/firebase_app.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__subscribe__ = __webpack_require__(13);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__errors__ = __webpack_require__(10);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_promise__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__ = __webpack_require__(17);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\nvar contains = function contains(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n};\nvar DEFAULT_ENTRY_NAME = '[DEFAULT]';\n// An array to capture listeners before the true auth functions\n// exist\nvar tokenListeners = [];\n/**\r\n * Global context object for a collection of services using\r\n * a shared authentication state.\r\n */\nvar FirebaseAppImpl = function () {\n function FirebaseAppImpl(options, name, firebase_) {\n this.firebase_ = firebase_;\n this.isDeleted_ = false;\n this.services_ = {};\n this.name_ = name;\n this.options_ = __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"a\" /* deepCopy */](options);\n this.INTERNAL = {\n 'getUid': function getUid() {\n return null;\n },\n 'getToken': function getToken() {\n return __WEBPACK_IMPORTED_MODULE_2__utils_promise__[\"b\" /* PromiseImpl */].resolve(null);\n },\n 'addAuthTokenListener': function addAuthTokenListener(callback) {\n tokenListeners.push(callback);\n // Make sure callback is called, asynchronously, in the absence of the auth module\n setTimeout(function () {\n return callback(null);\n }, 0);\n },\n 'removeAuthTokenListener': function removeAuthTokenListener(callback) {\n tokenListeners = tokenListeners.filter(function (listener) {\n return listener !== callback;\n });\n }\n };\n }\n Object.defineProperty(FirebaseAppImpl.prototype, \"name\", {\n get: function get() {\n this.checkDestroyed_();\n return this.name_;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(FirebaseAppImpl.prototype, \"options\", {\n get: function get() {\n this.checkDestroyed_();\n return this.options_;\n },\n enumerable: true,\n configurable: true\n });\n FirebaseAppImpl.prototype.delete = function () {\n var _this = this;\n return new __WEBPACK_IMPORTED_MODULE_2__utils_promise__[\"b\" /* PromiseImpl */](function (resolve) {\n _this.checkDestroyed_();\n resolve();\n }).then(function () {\n _this.firebase_.INTERNAL.removeApp(_this.name_);\n var services = [];\n Object.keys(_this.services_).forEach(function (serviceKey) {\n Object.keys(_this.services_[serviceKey]).forEach(function (instanceKey) {\n services.push(_this.services_[serviceKey][instanceKey]);\n });\n });\n return __WEBPACK_IMPORTED_MODULE_2__utils_promise__[\"b\" /* PromiseImpl */].all(services.map(function (service) {\n return service.INTERNAL.delete();\n }));\n }).then(function () {\n _this.isDeleted_ = true;\n _this.services_ = {};\n });\n };\n /**\r\n * Return a service instance associated with this app (creating it\r\n * on demand), identified by the passed instanceIdentifier.\r\n *\r\n * NOTE: Currently storage is the only one that is leveraging this\r\n * functionality. They invoke it by calling:\r\n *\r\n * ```javascript\r\n * firebase.app().storage('STORAGE BUCKET ID')\r\n * ```\r\n *\r\n * The service name is passed to this already\r\n * @internal\r\n */\n FirebaseAppImpl.prototype._getService = function (name, instanceIdentifier) {\n if (instanceIdentifier === void 0) {\n instanceIdentifier = DEFAULT_ENTRY_NAME;\n }\n this.checkDestroyed_();\n if (!this.services_[name]) {\n this.services_[name] = {};\n }\n if (!this.services_[name][instanceIdentifier]) {\n /**\r\n * If a custom instance has been defined (i.e. not '[DEFAULT]')\r\n * then we will pass that instance on, otherwise we pass `null`\r\n */\n var instanceSpecifier = instanceIdentifier !== DEFAULT_ENTRY_NAME ? instanceIdentifier : undefined;\n var service = this.firebase_.INTERNAL.factories[name](this, this.extendApp.bind(this), instanceSpecifier);\n this.services_[name][instanceIdentifier] = service;\n }\n return this.services_[name][instanceIdentifier];\n };\n /**\r\n * Callback function used to extend an App instance at the time\r\n * of service instance creation.\r\n */\n FirebaseAppImpl.prototype.extendApp = function (props) {\n var _this = this;\n // Copy the object onto the FirebaseAppImpl prototype\n __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"b\" /* deepExtend */](this, props);\n /**\r\n * If the app has overwritten the addAuthTokenListener stub, forward\r\n * the active token listeners on to the true fxn.\r\n *\r\n * TODO: This function is required due to our current module\r\n * structure. Once we are able to rely strictly upon a single module\r\n * implementation, this code should be refactored and Auth should\r\n * provide these stubs and the upgrade logic\r\n */\n if (props.INTERNAL && props.INTERNAL.addAuthTokenListener) {\n tokenListeners.forEach(function (listener) {\n _this.INTERNAL.addAuthTokenListener(listener);\n });\n tokenListeners = [];\n }\n };\n /**\r\n * This function will throw an Error if the App has already been deleted -\r\n * use before performing API actions on the App.\r\n */\n FirebaseAppImpl.prototype.checkDestroyed_ = function () {\n if (this.isDeleted_) {\n error('app-deleted', { 'name': this.name_ });\n }\n };\n return FirebaseAppImpl;\n}();\n;\n// Prevent dead-code elimination of these methods w/o invalid property\n// copying.\nFirebaseAppImpl.prototype.name && FirebaseAppImpl.prototype.options || FirebaseAppImpl.prototype.delete || console.log(\"dc\");\n/**\r\n * Return a firebase namespace object.\r\n *\r\n * In production, this will be called exactly once and the result\r\n * assigned to the 'firebase' global. It may be called multiple times\r\n * in unit tests.\r\n */\nfunction createFirebaseNamespace() {\n var apps_ = {};\n var factories = {};\n var appHooks = {};\n // A namespace is a plain JavaScript Object.\n var namespace = {\n // Hack to prevent Babel from modifying the object returned\n // as the firebase namespace.\n '__esModule': true,\n 'initializeApp': initializeApp,\n 'app': app,\n 'apps': null,\n 'Promise': __WEBPACK_IMPORTED_MODULE_2__utils_promise__[\"b\" /* PromiseImpl */],\n 'SDK_VERSION': '4.1.4',\n 'INTERNAL': {\n 'registerService': registerService,\n 'createFirebaseNamespace': createFirebaseNamespace,\n 'extendNamespace': extendNamespace,\n 'createSubscribe': __WEBPACK_IMPORTED_MODULE_0__subscribe__[\"a\" /* createSubscribe */],\n 'ErrorFactory': __WEBPACK_IMPORTED_MODULE_1__errors__[\"a\" /* ErrorFactory */],\n 'removeApp': removeApp,\n 'factories': factories,\n 'useAsService': useAsService,\n 'Promise': __WEBPACK_IMPORTED_MODULE_2__utils_promise__[\"b\" /* PromiseImpl */],\n 'deepExtend': __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"b\" /* deepExtend */]\n }\n };\n // Inject a circular default export to allow Babel users who were previously\n // using:\n //\n // import firebase from 'firebase';\n // which becomes: var firebase = require('firebase').default;\n //\n // instead of\n //\n // import * as firebase from 'firebase';\n // which becomes: var firebase = require('firebase');\n __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"c\" /* patchProperty */](namespace, 'default', namespace);\n // firebase.apps is a read-only getter.\n Object.defineProperty(namespace, 'apps', {\n get: getApps\n });\n /**\r\n * Called by App.delete() - but before any services associated with the App\r\n * are deleted.\r\n */\n function removeApp(name) {\n var app = apps_[name];\n callAppHooks(app, 'delete');\n delete apps_[name];\n }\n /**\r\n * Get the App object for a given name (or DEFAULT).\r\n */\n function app(name) {\n name = name || DEFAULT_ENTRY_NAME;\n if (!contains(apps_, name)) {\n error('no-app', { 'name': name });\n }\n return apps_[name];\n }\n __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"c\" /* patchProperty */](app, 'App', FirebaseAppImpl);\n /**\r\n * Create a new App instance (name must be unique).\r\n */\n function initializeApp(options, name) {\n if (name === undefined) {\n name = DEFAULT_ENTRY_NAME;\n } else {\n if (typeof name !== 'string' || name === '') {\n error('bad-app-name', { 'name': name + '' });\n }\n }\n if (contains(apps_, name)) {\n error('duplicate-app', { 'name': name });\n }\n var app = new FirebaseAppImpl(options, name, namespace);\n apps_[name] = app;\n callAppHooks(app, 'create');\n return app;\n }\n /*\r\n * Return an array of all the non-deleted FirebaseApps.\r\n */\n function getApps() {\n // Make a copy so caller cannot mutate the apps list.\n return Object.keys(apps_).map(function (name) {\n return apps_[name];\n });\n }\n /*\r\n * Register a Firebase Service.\r\n *\r\n * firebase.INTERNAL.registerService()\r\n *\r\n * TODO: Implement serviceProperties.\r\n */\n function registerService(name, createService, serviceProperties, appHook, allowMultipleInstances) {\n // Cannot re-register a service that already exists\n if (factories[name]) {\n error('duplicate-service', { 'name': name });\n }\n // Capture the service factory for later service instantiation\n factories[name] = createService;\n // Capture the appHook, if passed\n if (appHook) {\n appHooks[name] = appHook;\n // Run the **new** app hook on all existing apps\n getApps().forEach(function (app) {\n appHook('create', app);\n });\n }\n // The Service namespace is an accessor function ...\n var serviceNamespace = function serviceNamespace(appArg) {\n if (appArg === void 0) {\n appArg = app();\n }\n if (typeof appArg[name] !== 'function') {\n // Invalid argument.\n // This happens in the following case: firebase.storage('gs:/')\n error('invalid-app-argument', { 'name': name });\n }\n // Forward service instance lookup to the FirebaseApp.\n return appArg[name]();\n };\n // ... and a container for service-level properties.\n if (serviceProperties !== undefined) {\n __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"b\" /* deepExtend */](serviceNamespace, serviceProperties);\n }\n // Monkey-patch the serviceNamespace onto the firebase namespace\n namespace[name] = serviceNamespace;\n // Patch the FirebaseAppImpl prototype\n FirebaseAppImpl.prototype[name] = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var serviceFxn = this._getService.bind(this, name);\n return serviceFxn.apply(this, allowMultipleInstances ? args : []);\n };\n return serviceNamespace;\n }\n /**\r\n * Patch the top-level firebase namespace with additional properties.\r\n *\r\n * firebase.INTERNAL.extendNamespace()\r\n */\n function extendNamespace(props) {\n __WEBPACK_IMPORTED_MODULE_3__utils_deep_copy__[\"b\" /* deepExtend */](namespace, props);\n }\n function callAppHooks(app, eventName) {\n Object.keys(factories).forEach(function (serviceName) {\n // Ignore virtual services\n var factoryName = useAsService(app, serviceName);\n if (factoryName === null) {\n return;\n }\n if (appHooks[factoryName]) {\n appHooks[factoryName](eventName, app);\n }\n });\n }\n // Map the requested service to a registered service name\n // (used to map auth to serverAuth service when needed).\n function useAsService(app, name) {\n if (name === 'serverAuth') {\n return null;\n }\n var useService = name;\n var options = app.options;\n return useService;\n }\n return namespace;\n}\nfunction error(code, args) {\n throw appErrors.create(code, args);\n}\n// TypeScript does not support non-string indexes!\n// let errors: {[code: AppError: string} = {\nvar errors = {\n 'no-app': 'No Firebase App \\'{$name}\\' has been created - ' + 'call Firebase App.initializeApp()',\n 'bad-app-name': 'Illegal App name: \\'{$name}',\n 'duplicate-app': 'Firebase App named \\'{$name}\\' already exists',\n 'app-deleted': 'Firebase App named \\'{$name}\\' already deleted',\n 'duplicate-service': 'Firebase service named \\'{$name}\\' already registered',\n 'sa-not-supported': 'Initializing the Firebase SDK with a service ' + 'account is only allowed in a Node.js environment. On client ' + 'devices, you should instead initialize the SDK with an api key and ' + 'auth domain',\n 'invalid-app-argument': 'firebase.{$name}() takes either no argument or a ' + 'Firebase App instance.'\n};\nvar appErrors = new __WEBPACK_IMPORTED_MODULE_1__errors__[\"a\" /* ErrorFactory */]('app', 'Firebase', errors);\n// CONCATENATED MODULE: ./src/app.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n// Import the createFirebaseNamespace function\n\n// Export a single instance of firebase app\nvar firebase = createFirebaseNamespace();\n/* harmony default export */ __webpack_exports__[\"default\"] = (firebase);\n\n/***/ }),\n/* 6 */,\n/* 7 */,\n/* 8 */,\n/* 9 */,\n/* 10 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* unused harmony export patchCapture */\n/* unused harmony export FirebaseError */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return ErrorFactory; });\nvar ERROR_NAME = 'FirebaseError';\nvar captureStackTrace = Error.captureStackTrace;\n// Export for faking in tests\nfunction patchCapture(captureFake) {\n var result = captureStackTrace;\n captureStackTrace = captureFake;\n return result;\n}\nvar FirebaseError = function () {\n function FirebaseError(code, message) {\n this.code = code;\n this.message = message;\n var stack;\n // We want the stack value, if implemented by Error\n if (captureStackTrace) {\n // Patches this.stack, omitted calls above ErrorFactory#create\n captureStackTrace(this, ErrorFactory.prototype.create);\n } else {\n var err_1 = Error.apply(this, arguments);\n this.name = ERROR_NAME;\n // Make non-enumerable getter for the property.\n Object.defineProperty(this, 'stack', {\n get: function get() {\n return err_1.stack;\n }\n });\n }\n }\n return FirebaseError;\n}();\n\n// Back-door inheritance\nFirebaseError.prototype = Object.create(Error.prototype);\nFirebaseError.prototype.constructor = FirebaseError;\nFirebaseError.prototype.name = ERROR_NAME;\nvar ErrorFactory = function () {\n function ErrorFactory(service, serviceName, errors) {\n this.service = service;\n this.serviceName = serviceName;\n this.errors = errors;\n // Matches {$name}, by default.\n this.pattern = /\\{\\$([^}]+)}/g;\n // empty\n }\n ErrorFactory.prototype.create = function (code, data) {\n if (data === undefined) {\n data = {};\n }\n var template = this.errors[code];\n var fullCode = this.service + '/' + code;\n var message;\n if (template === undefined) {\n message = \"Error\";\n } else {\n message = template.replace(this.pattern, function (match, key) {\n var value = data[key];\n return value !== undefined ? value.toString() : '<' + key + '?>';\n });\n }\n // Service: Error message (service/code).\n message = this.serviceName + ': ' + message + ' (' + fullCode + ').';\n var err = new FirebaseError(fullCode, message);\n // Populate the Error object with message parts for programmatic\n // accesses (e.g., e.file).\n for (var prop in data) {\n if (!data.hasOwnProperty(prop) || prop.slice(-1) === '_') {\n continue;\n }\n err[prop] = data[prop];\n }\n return err;\n };\n return ErrorFactory;\n}();\n\n\n/***/ }),\n/* 11 */,\n/* 12 */,\n/* 13 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = createSubscribe;\n/* unused harmony export async */\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_promise__ = __webpack_require__(4);\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n\n/**\r\n * Helper to make a Subscribe function (just like Promise helps make a\r\n * Thenable).\r\n *\r\n * @param executor Function which can make calls to a single Observer\r\n * as a proxy.\r\n * @param onNoObservers Callback when count of Observers goes to zero.\r\n */\nfunction createSubscribe(executor, onNoObservers) {\n var proxy = new ObserverProxy(executor, onNoObservers);\n return proxy.subscribe.bind(proxy);\n}\n/**\r\n * Implement fan-out for any number of Observers attached via a subscribe\r\n * function.\r\n */\nvar ObserverProxy = function () {\n /**\r\n * @param executor Function which can make calls to a single Observer\r\n * as a proxy.\r\n * @param onNoObservers Callback when count of Observers goes to zero.\r\n */\n function ObserverProxy(executor, onNoObservers) {\n var _this = this;\n this.observers = [];\n this.unsubscribes = [];\n this.observerCount = 0;\n // Micro-task scheduling by calling task.then().\n this.task = __WEBPACK_IMPORTED_MODULE_0__utils_promise__[\"b\" /* PromiseImpl */].resolve();\n this.finalized = false;\n this.onNoObservers = onNoObservers;\n // Call the executor asynchronously so subscribers that are called\n // synchronously after the creation of the subscribe function\n // can still receive the very first value generated in the executor.\n this.task.then(function () {\n executor(_this);\n }).catch(function (e) {\n _this.error(e);\n });\n }\n ObserverProxy.prototype.next = function (value) {\n this.forEachObserver(function (observer) {\n observer.next(value);\n });\n };\n ObserverProxy.prototype.error = function (error) {\n this.forEachObserver(function (observer) {\n observer.error(error);\n });\n this.close(error);\n };\n ObserverProxy.prototype.complete = function () {\n this.forEachObserver(function (observer) {\n observer.complete();\n });\n this.close();\n };\n /**\r\n * Subscribe function that can be used to add an Observer to the fan-out list.\r\n *\r\n * - We require that no event is sent to a subscriber sychronously to their\r\n * call to subscribe().\r\n */\n ObserverProxy.prototype.subscribe = function (nextOrObserver, error, complete) {\n var _this = this;\n var observer;\n if (nextOrObserver === undefined && error === undefined && complete === undefined) {\n throw new Error(\"Missing Observer.\");\n }\n // Assemble an Observer object when passed as callback functions.\n if (implementsAnyMethods(nextOrObserver, ['next', 'error', 'complete'])) {\n observer = nextOrObserver;\n } else {\n observer = {\n next: nextOrObserver,\n error: error,\n complete: complete\n };\n }\n if (observer.next === undefined) {\n observer.next = noop;\n }\n if (observer.error === undefined) {\n observer.error = noop;\n }\n if (observer.complete === undefined) {\n observer.complete = noop;\n }\n var unsub = this.unsubscribeOne.bind(this, this.observers.length);\n // Attempt to subscribe to a terminated Observable - we\n // just respond to the Observer with the final error or complete\n // event.\n if (this.finalized) {\n this.task.then(function () {\n try {\n if (_this.finalError) {\n observer.error(_this.finalError);\n } else {\n observer.complete();\n }\n } catch (e) {\n // nothing\n }\n return;\n });\n }\n this.observers.push(observer);\n return unsub;\n };\n // Unsubscribe is synchronous - we guarantee that no events are sent to\n // any unsubscribed Observer.\n ObserverProxy.prototype.unsubscribeOne = function (i) {\n if (this.observers === undefined || this.observers[i] === undefined) {\n return;\n }\n delete this.observers[i];\n this.observerCount -= 1;\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\n this.onNoObservers(this);\n }\n };\n ObserverProxy.prototype.forEachObserver = function (fn) {\n if (this.finalized) {\n // Already closed by previous event....just eat the additional values.\n return;\n }\n // Since sendOne calls asynchronously - there is no chance that\n // this.observers will become undefined.\n for (var i = 0; i < this.observers.length; i++) {\n this.sendOne(i, fn);\n }\n };\n // Call the Observer via one of it's callback function. We are careful to\n // confirm that the observe has not been unsubscribed since this asynchronous\n // function had been queued.\n ObserverProxy.prototype.sendOne = function (i, fn) {\n var _this = this;\n // Execute the callback asynchronously\n this.task.then(function () {\n if (_this.observers !== undefined && _this.observers[i] !== undefined) {\n try {\n fn(_this.observers[i]);\n } catch (e) {\n // Ignore exceptions raised in Observers or missing methods of an\n // Observer.\n // Log error to console. b/31404806\n if (typeof console !== \"undefined\" && console.error) {\n console.error(e);\n }\n }\n }\n });\n };\n ObserverProxy.prototype.close = function (err) {\n var _this = this;\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n if (err !== undefined) {\n this.finalError = err;\n }\n // Proxy is no longer needed - garbage collect references\n this.task.then(function () {\n _this.observers = undefined;\n _this.onNoObservers = undefined;\n });\n };\n return ObserverProxy;\n}();\n/** Turn synchronous function into one called asynchronously. */\nfunction async(fn, onError) {\n return function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n __WEBPACK_IMPORTED_MODULE_0__utils_promise__[\"b\" /* PromiseImpl */].resolve(true).then(function () {\n fn.apply(void 0, args);\n }).catch(function (error) {\n if (onError) {\n onError(error);\n }\n });\n };\n}\n/**\r\n * Return true if the object passed in implements any of the named methods.\r\n */\nfunction implementsAnyMethods(obj, methods) {\n if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || obj === null) {\n return false;\n }\n for (var _i = 0, methods_1 = methods; _i < methods_1.length; _i++) {\n var method = methods_1[_i];\n if (method in obj && typeof obj[method] === 'function') {\n return true;\n }\n }\n return false;\n}\nfunction noop() {\n // do nothing\n}\n\n/***/ }),\n/* 14 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return globalScope; });\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\nvar scope;\nif (typeof global !== 'undefined') {\n scope = global;\n} else if (typeof self !== 'undefined') {\n scope = self;\n} else {\n try {\n scope = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n}\nvar globalScope = scope;\n/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(15)))\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\nvar g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports) {\n\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n/***/ }),\n/* 17 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = deepCopy;\n/* harmony export (immutable) */ __webpack_exports__[\"b\"] = deepExtend;\n/* harmony export (immutable) */ __webpack_exports__[\"c\"] = patchProperty;\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * Do a deep-copy of basic JavaScript Objects or Arrays.\r\n */\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/function deepCopy(value) {\n return deepExtend(undefined, value);\n}\n/**\r\n * Copy properties from source to target (recursively allows extension\r\n * of Objects and Arrays). Scalar values in the target are over-written.\r\n * If target is undefined, an object of the appropriate type will be created\r\n * (and returned).\r\n *\r\n * We recursively copy all child properties of plain Objects in the source- so\r\n * that namespace- like dictionaries are merged.\r\n *\r\n * Note that the target can be a function, in which case the properties in\r\n * the source Object are copied onto it as static properties of the Function.\r\n */\nfunction deepExtend(target, source) {\n if (!(source instanceof Object)) {\n return source;\n }\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n var dateValue = source;\n return new Date(dateValue.getTime());\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n for (var prop in source) {\n if (!source.hasOwnProperty(prop)) {\n continue;\n }\n target[prop] = deepExtend(target[prop], source[prop]);\n }\n return target;\n}\n// TODO: Really needed (for JSCompiler type checking)?\nfunction patchProperty(obj, prop, value) {\n obj[prop] = value;\n}\n\n/***/ }),\n/* 18 */,\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(setImmediate) {(function (root) {\n\n // Store setTimeout reference so promise-polyfill will be unaffected by\n // other code modifying setTimeout (like sinon.useFakeTimers())\n var setTimeoutFunc = setTimeout;\n\n function noop() {}\n \n // Polyfill for Function.prototype.bind\n function bind(fn, thisArg) {\n return function () {\n fn.apply(thisArg, arguments);\n };\n }\n\n function Promise(fn) {\n if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new');\n if (typeof fn !== 'function') throw new TypeError('not a function');\n this._state = 0;\n this._handled = false;\n this._value = undefined;\n this._deferreds = [];\n\n doResolve(fn, this);\n }\n\n function handle(self, deferred) {\n while (self._state === 3) {\n self = self._value;\n }\n if (self._state === 0) {\n self._deferreds.push(deferred);\n return;\n }\n self._handled = true;\n Promise._immediateFn(function () {\n var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n if (cb === null) {\n (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n return;\n }\n var ret;\n try {\n ret = cb(self._value);\n } catch (e) {\n reject(deferred.promise, e);\n return;\n }\n resolve(deferred.promise, ret);\n });\n }\n\n function resolve(self, newValue) {\n try {\n // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.');\n if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {\n var then = newValue.then;\n if (newValue instanceof Promise) {\n self._state = 3;\n self._value = newValue;\n finale(self);\n return;\n } else if (typeof then === 'function') {\n doResolve(bind(then, newValue), self);\n return;\n }\n }\n self._state = 1;\n self._value = newValue;\n finale(self);\n } catch (e) {\n reject(self, e);\n }\n }\n\n function reject(self, newValue) {\n self._state = 2;\n self._value = newValue;\n finale(self);\n }\n\n function finale(self) {\n if (self._state === 2 && self._deferreds.length === 0) {\n Promise._immediateFn(function() {\n if (!self._handled) {\n Promise._unhandledRejectionFn(self._value);\n }\n });\n }\n\n for (var i = 0, len = self._deferreds.length; i < len; i++) {\n handle(self, self._deferreds[i]);\n }\n self._deferreds = null;\n }\n\n function Handler(onFulfilled, onRejected, promise) {\n this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n this.promise = promise;\n }\n\n /**\n * Take a potentially misbehaving resolver function and make sure\n * onFulfilled and onRejected are only called once.\n *\n * Makes no guarantees about asynchrony.\n */\n function doResolve(fn, self) {\n var done = false;\n try {\n fn(function (value) {\n if (done) return;\n done = true;\n resolve(self, value);\n }, function (reason) {\n if (done) return;\n done = true;\n reject(self, reason);\n });\n } catch (ex) {\n if (done) return;\n done = true;\n reject(self, ex);\n }\n }\n\n Promise.prototype['catch'] = function (onRejected) {\n return this.then(null, onRejected);\n };\n\n Promise.prototype.then = function (onFulfilled, onRejected) {\n var prom = new (this.constructor)(noop);\n\n handle(this, new Handler(onFulfilled, onRejected, prom));\n return prom;\n };\n\n Promise.all = function (arr) {\n var args = Array.prototype.slice.call(arr);\n\n return new Promise(function (resolve, reject) {\n if (args.length === 0) return resolve([]);\n var remaining = args.length;\n\n function res(i, val) {\n try {\n if (val && (typeof val === 'object' || typeof val === 'function')) {\n var then = val.then;\n if (typeof then === 'function') {\n then.call(val, function (val) {\n res(i, val);\n }, reject);\n return;\n }\n }\n args[i] = val;\n if (--remaining === 0) {\n resolve(args);\n }\n } catch (ex) {\n reject(ex);\n }\n }\n\n for (var i = 0; i < args.length; i++) {\n res(i, args[i]);\n }\n });\n };\n\n Promise.resolve = function (value) {\n if (value && typeof value === 'object' && value.constructor === Promise) {\n return value;\n }\n\n return new Promise(function (resolve) {\n resolve(value);\n });\n };\n\n Promise.reject = function (value) {\n return new Promise(function (resolve, reject) {\n reject(value);\n });\n };\n\n Promise.race = function (values) {\n return new Promise(function (resolve, reject) {\n for (var i = 0, len = values.length; i < len; i++) {\n values[i].then(resolve, reject);\n }\n });\n };\n\n // Use polyfill for setImmediate for performance gains\n Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) ||\n function (fn) {\n setTimeoutFunc(fn, 0);\n };\n\n Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n if (typeof console !== 'undefined' && console) {\n console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console\n }\n };\n\n /**\n * Set the immediate function to execute callbacks\n * @param fn {function} Function to execute\n * @deprecated\n */\n Promise._setImmediateFn = function _setImmediateFn(fn) {\n Promise._immediateFn = fn;\n };\n\n /**\n * Change the function to execute on unhandled rejection\n * @param {function} fn Function to execute on unhandled rejection\n * @deprecated\n */\n Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {\n Promise._unhandledRejectionFn = fn;\n };\n \n if (typeof module !== 'undefined' && module.exports) {\n module.exports = Promise;\n } else if (!root.Promise) {\n root.Promise = Promise;\n }\n\n})(this);\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(20).setImmediate))\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar apply = Function.prototype.apply;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) {\n if (timeout) {\n timeout.close();\n }\n};\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\n__webpack_require__(21);\nexports.setImmediate = setImmediate;\nexports.clearImmediate = clearImmediate;\n\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a ';\n }\n var iframeContents = '' + script + '';\n try {\n this.myIFrame.doc.open();\n this.myIFrame.doc.write(iframeContents);\n this.myIFrame.doc.close();\n } catch (e) {\n BrowserPollConnection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"s\" /* log */]('frame writing exception');\n if (e.stack) {\n BrowserPollConnection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"s\" /* log */](e.stack);\n }\n BrowserPollConnection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"s\" /* log */](e);\n }\n } else {\n this.commandCB = commandCB;\n this.onMessageCB = onMessageCB;\n }\n }\n /**\r\n * Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can\r\n * actually use.\r\n * @private\r\n * @return {Element}\r\n */\n FirebaseIFrameScriptHolder.createIFrame_ = function () {\n var iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n // This is necessary in order to initialize the document inside the iframe\n if (document.body) {\n document.body.appendChild(iframe);\n try {\n // If document.domain has been modified in IE, this will throw an error, and we need to set the\n // domain of the iframe's document manually. We can do this via a javascript: url as the src attribute\n // Also note that we must do this *after* the iframe has been appended to the page. Otherwise it doesn't work.\n var a = iframe.contentWindow.document;\n if (!a) {\n // Apologies for the log-spam, I need to do something to keep closure from optimizing out the assignment above.\n BrowserPollConnection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"s\" /* log */]('No IE domain setting required');\n }\n } catch (e) {\n var domain = document.domain;\n iframe.src = 'javascript:void((function(){document.open();document.domain=\\'' + domain + '\\';document.close();})())';\n }\n } else {\n // LongPollConnection attempts to delay initialization until the document is ready, so hopefully this\n // never gets hit.\n throw 'Document body has not initialized. Wait to initialize Firebase until after the document is ready.';\n }\n // Get the document of the iframe in a browser-specific way.\n if (iframe.contentDocument) {\n iframe.doc = iframe.contentDocument; // Firefox, Opera, Safari\n } else if (iframe.contentWindow) {\n iframe.doc = iframe.contentWindow.document; // Internet Explorer\n } else if (iframe.document) {\n iframe.doc = iframe.document; //others?\n }\n return iframe;\n };\n /**\r\n * Cancel all outstanding queries and remove the frame.\r\n */\n FirebaseIFrameScriptHolder.prototype.close = function () {\n var _this = this;\n //Mark this iframe as dead, so no new requests are sent.\n this.alive = false;\n if (this.myIFrame) {\n //We have to actually remove all of the html inside this iframe before removing it from the\n //window, or IE will continue loading and executing the script tags we've already added, which\n //can lead to some errors being thrown. Setting innerHTML seems to be the easiest way to do this.\n this.myIFrame.doc.body.innerHTML = '';\n setTimeout(function () {\n if (_this.myIFrame !== null) {\n document.body.removeChild(_this.myIFrame);\n _this.myIFrame = null;\n }\n }, Math.floor(0));\n }\n if (__WEBPACK_IMPORTED_MODULE_6__utils_environment__[\"b\" /* isNodeSdk */]() && this.myID) {\n var urlParams = {};\n urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM] = 't';\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\n var theURL = this.urlFn(urlParams);\n FirebaseIFrameScriptHolder.nodeRestRequest(theURL);\n }\n // Protect from being called recursively.\n var onDisconnect = this.onDisconnect;\n if (onDisconnect) {\n this.onDisconnect = null;\n onDisconnect();\n }\n };\n /**\r\n * Actually start the long-polling session by adding the first script tag(s) to the iframe.\r\n * @param {!string} id - The ID of this connection\r\n * @param {!string} pw - The password for this connection\r\n */\n FirebaseIFrameScriptHolder.prototype.startLongPoll = function (id, pw) {\n this.myID = id;\n this.myPW = pw;\n this.alive = true;\n //send the initial request. If there are requests queued, make sure that we transmit as many as we are currently able to.\n while (this.newRequest_()) {}\n };\n ;\n /**\r\n * This is called any time someone might want a script tag to be added. It adds a script tag when there aren't\r\n * too many outstanding requests and we are still alive.\r\n *\r\n * If there are outstanding packet segments to send, it sends one. If there aren't, it sends a long-poll anyways if\r\n * needed.\r\n */\n FirebaseIFrameScriptHolder.prototype.newRequest_ = function () {\n // We keep one outstanding request open all the time to receive data, but if we need to send data\n // (pendingSegs.length > 0) then we create a new request to send the data. The server will automatically\n // close the old request.\n if (this.alive && this.sendNewPolls && this.outstandingRequests.count() < (this.pendingSegs.length > 0 ? 2 : 1)) {\n //construct our url\n this.currentSerial++;\n var urlParams = {};\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\n urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial;\n var theURL = this.urlFn(urlParams);\n //Now add as much data as we can.\n var curDataString = '';\n var i = 0;\n while (this.pendingSegs.length > 0) {\n //first, lets see if the next segment will fit.\n var nextSeg = this.pendingSegs[0];\n if (nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <= MAX_URL_DATA_SIZE) {\n //great, the segment will fit. Lets append it.\n var theSeg = this.pendingSegs.shift();\n curDataString = curDataString + '&' + FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM + i + '=' + theSeg.seg + '&' + FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET + i + '=' + theSeg.ts + '&' + FIREBASE_LONGPOLL_DATA_PARAM + i + '=' + theSeg.d;\n i++;\n } else {\n break;\n }\n }\n theURL = theURL + curDataString;\n this.addLongPollTag_(theURL, this.currentSerial);\n return true;\n } else {\n return false;\n }\n };\n ;\n /**\r\n * Queue a packet for transmission to the server.\r\n * @param segnum - A sequential id for this packet segment used for reassembly\r\n * @param totalsegs - The total number of segments in this packet\r\n * @param data - The data for this segment.\r\n */\n FirebaseIFrameScriptHolder.prototype.enqueueSegment = function (segnum, totalsegs, data) {\n //add this to the queue of segments to send.\n this.pendingSegs.push({ seg: segnum, ts: totalsegs, d: data });\n //send the data immediately if there isn't already data being transmitted, unless\n //startLongPoll hasn't been called yet.\n if (this.alive) {\n this.newRequest_();\n }\n };\n ;\n /**\r\n * Add a script tag for a regular long-poll request.\r\n * @param {!string} url - The URL of the script tag.\r\n * @param {!number} serial - The serial number of the request.\r\n * @private\r\n */\n FirebaseIFrameScriptHolder.prototype.addLongPollTag_ = function (url, serial) {\n var _this = this;\n //remember that we sent this request.\n this.outstandingRequests.add(serial, 1);\n var doNewRequest = function doNewRequest() {\n _this.outstandingRequests.remove(serial);\n _this.newRequest_();\n };\n // If this request doesn't return on its own accord (by the server sending us some data), we'll\n // create a new one after the KEEPALIVE interval to make sure we always keep a fresh request open.\n var keepaliveTimeout = setTimeout(doNewRequest, Math.floor(KEEPALIVE_REQUEST_INTERVAL));\n var readyStateCB = function readyStateCB() {\n // Request completed. Cancel the keepalive.\n clearTimeout(keepaliveTimeout);\n // Trigger a new request so we can continue receiving data.\n doNewRequest();\n };\n this.addTag(url, readyStateCB);\n };\n ;\n /**\r\n * Add an arbitrary script tag to the iframe.\r\n * @param {!string} url - The URL for the script tag source.\r\n * @param {!function()} loadCB - A callback to be triggered once the script has loaded.\r\n */\n FirebaseIFrameScriptHolder.prototype.addTag = function (url, loadCB) {\n var _this = this;\n if (__WEBPACK_IMPORTED_MODULE_6__utils_environment__[\"b\" /* isNodeSdk */]()) {\n this.doNodeLongPoll(url, loadCB);\n } else {\n setTimeout(function () {\n try {\n // if we're already closed, don't add this poll\n if (!_this.sendNewPolls) return;\n var newScript_1 = _this.myIFrame.doc.createElement('script');\n newScript_1.type = 'text/javascript';\n newScript_1.async = true;\n newScript_1.src = url;\n newScript_1.onload = newScript_1.onreadystatechange = function () {\n var rstate = newScript_1.readyState;\n if (!rstate || rstate === 'loaded' || rstate === 'complete') {\n newScript_1.onload = newScript_1.onreadystatechange = null;\n if (newScript_1.parentNode) {\n newScript_1.parentNode.removeChild(newScript_1);\n }\n loadCB();\n }\n };\n newScript_1.onerror = function () {\n BrowserPollConnection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"s\" /* log */]('Long-poll script failed to load: ' + url);\n _this.sendNewPolls = false;\n _this.close();\n };\n _this.myIFrame.doc.body.appendChild(newScript_1);\n } catch (e) {\n // TODO: we should make this error visible somehow\n }\n }, Math.floor(1));\n }\n };\n return FirebaseIFrameScriptHolder;\n}();\n\n// CONCATENATED MODULE: ./src/database/realtime/TransportManager.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__ = __webpack_require__(18);\n/* harmony import */ var TransportManager___WEBPACK_IMPORTED_MODULE_2__core_util_util__ = __webpack_require__(1);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n/**\r\n * Currently simplistic, this class manages what transport a Connection should use at various stages of its\r\n * lifecycle.\r\n *\r\n * It starts with longpolling in a browser, and httppolling on node. It then upgrades to websockets if\r\n * they are available.\r\n * @constructor\r\n */\nvar TransportManager_TransportManager = function () {\n /**\r\n * @param {!RepoInfo} repoInfo Metadata around the namespace we're connecting to\r\n */\n function TransportManager(repoInfo) {\n this.initTransports_(repoInfo);\n }\n Object.defineProperty(TransportManager, \"ALL_TRANSPORTS\", {\n /**\r\n * @const\r\n * @type {!Array.}\r\n */\n get: function get() {\n return [BrowserPollConnection_BrowserPollConnection, __WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__[\"a\" /* WebSocketConnection */]];\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * @param {!RepoInfo} repoInfo\r\n * @private\r\n */\n TransportManager.prototype.initTransports_ = function (repoInfo) {\n var isWebSocketsAvailable = __WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__[\"a\" /* WebSocketConnection */] && __WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__[\"a\" /* WebSocketConnection */]['isAvailable']();\n var isSkipPollConnection = isWebSocketsAvailable && !__WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__[\"a\" /* WebSocketConnection */].previouslyFailed();\n if (repoInfo.webSocketOnly) {\n if (!isWebSocketsAvailable) TransportManager___WEBPACK_IMPORTED_MODULE_2__core_util_util__[\"B\" /* warn */]('wss:// URL used, but browser isn\\'t known to support websockets. Trying anyway.');\n isSkipPollConnection = true;\n }\n if (isSkipPollConnection) {\n this.transports_ = [__WEBPACK_IMPORTED_MODULE_1__WebSocketConnection__[\"a\" /* WebSocketConnection */]];\n } else {\n var transports_1 = this.transports_ = [];\n TransportManager___WEBPACK_IMPORTED_MODULE_2__core_util_util__[\"i\" /* each */](TransportManager.ALL_TRANSPORTS, function (i, transport) {\n if (transport && transport['isAvailable']()) {\n transports_1.push(transport);\n }\n });\n }\n };\n /**\r\n * @return {function(new:Transport, !string, !RepoInfo, string=, string=)} The constructor for the\r\n * initial transport to use\r\n */\n TransportManager.prototype.initialTransport = function () {\n if (this.transports_.length > 0) {\n return this.transports_[0];\n } else {\n throw new Error('No transports available');\n }\n };\n /**\r\n * @return {?function(new:Transport, function(),function(), string=)} The constructor for the next\r\n * transport, or null\r\n */\n TransportManager.prototype.upgradeTransport = function () {\n if (this.transports_.length > 1) {\n return this.transports_[1];\n } else {\n return null;\n }\n };\n return TransportManager;\n}();\n\n// CONCATENATED MODULE: ./src/database/realtime/Connection.ts\n/* harmony import */ var Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_storage_storage__ = __webpack_require__(8);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Constants__ = __webpack_require__(9);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n// Abort upgrade attempt if it takes longer than 60s.\nvar UPGRADE_TIMEOUT = 60000;\n// For some transports (WebSockets), we need to \"validate\" the transport by exchanging a few requests and responses.\n// If we haven't sent enough requests within 5s, we'll start sending noop ping requests.\nvar DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5000;\n// If the initial data sent triggers a lot of bandwidth (i.e. it's a large put or a listen for a large amount of data)\n// then we may not be able to exchange our ping/pong requests within the healthy timeout. So if we reach the timeout\n// but we've sent/received enough bytes, we don't cancel the connection.\nvar BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024;\nvar BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024;\nvar MESSAGE_TYPE = 't';\nvar MESSAGE_DATA = 'd';\nvar CONTROL_SHUTDOWN = 's';\nvar CONTROL_RESET = 'r';\nvar CONTROL_ERROR = 'e';\nvar CONTROL_PONG = 'o';\nvar SWITCH_ACK = 'a';\nvar END_TRANSMISSION = 'n';\nvar PING = 'p';\nvar SERVER_HELLO = 'h';\n/**\r\n * Creates a new real-time connection to the server using whichever method works\r\n * best in the current browser.\r\n *\r\n * @constructor\r\n */\nvar Connection_Connection = function () {\n /**\r\n * @param {!string} id - an id for this connection\r\n * @param {!RepoInfo} repoInfo_ - the info for the endpoint to connect to\r\n * @param {function(Object)} onMessage_ - the callback to be triggered when a server-push message arrives\r\n * @param {function(number, string)} onReady_ - the callback to be triggered when this connection is ready to send messages.\r\n * @param {function()} onDisconnect_ - the callback to be triggered when a connection was lost\r\n * @param {function(string)} onKill_ - the callback to be triggered when this connection has permanently shut down.\r\n * @param {string=} lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server\r\n */\n function Connection(id, repoInfo_, onMessage_, onReady_, onDisconnect_, onKill_, lastSessionId) {\n this.id = id;\n this.repoInfo_ = repoInfo_;\n this.onMessage_ = onMessage_;\n this.onReady_ = onReady_;\n this.onDisconnect_ = onDisconnect_;\n this.onKill_ = onKill_;\n this.lastSessionId = lastSessionId;\n this.connectionCount = 0;\n this.pendingDataMessages = [];\n this.state_ = 0 /* CONNECTING */;\n this.log_ = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"t\" /* logWrapper */]('c:' + this.id + ':');\n this.transportManager_ = new TransportManager_TransportManager(repoInfo_);\n this.log_('Connection created');\n this.start_();\n }\n /**\r\n * Starts a connection attempt\r\n * @private\r\n */\n Connection.prototype.start_ = function () {\n var _this = this;\n var conn = this.transportManager_.initialTransport();\n this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_, undefined, this.lastSessionId);\n // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\n // can consider the transport healthy.\n this.primaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0;\n var onMessageReceived = this.connReceiver_(this.conn_);\n var onConnectionLost = this.disconnReceiver_(this.conn_);\n this.tx_ = this.conn_;\n this.rx_ = this.conn_;\n this.secondaryConn_ = null;\n this.isHealthy_ = false;\n /*\r\n * Firefox doesn't like when code from one iframe tries to create another iframe by way of the parent frame.\r\n * This can occur in the case of a redirect, i.e. we guessed wrong on what server to connect to and received a reset.\r\n * Somehow, setTimeout seems to make this ok. That doesn't make sense from a security perspective, since you should\r\n * still have the context of your originating frame.\r\n */\n setTimeout(function () {\n // this.conn_ gets set to null in some of the tests. Check to make sure it still exists before using it\n _this.conn_ && _this.conn_.open(onMessageReceived, onConnectionLost);\n }, Math.floor(0));\n var healthyTimeout_ms = conn['healthyTimeout'] || 0;\n if (healthyTimeout_ms > 0) {\n this.healthyTimeout_ = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"x\" /* setTimeoutNonBlocking */](function () {\n _this.healthyTimeout_ = null;\n if (!_this.isHealthy_) {\n if (_this.conn_ && _this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE) {\n _this.log_('Connection exceeded healthy timeout but has received ' + _this.conn_.bytesReceived + ' bytes. Marking connection healthy.');\n _this.isHealthy_ = true;\n _this.conn_.markConnectionHealthy();\n } else if (_this.conn_ && _this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE) {\n _this.log_('Connection exceeded healthy timeout but has sent ' + _this.conn_.bytesSent + ' bytes. Leaving connection alive.');\n // NOTE: We don't want to mark it healthy, since we have no guarantee that the bytes have made it to\n // the server.\n } else {\n _this.log_('Closing unhealthy connection after timeout.');\n _this.close();\n }\n }\n }, Math.floor(healthyTimeout_ms));\n }\n };\n /**\r\n * @return {!string}\r\n * @private\r\n */\n Connection.prototype.nextTransportId_ = function () {\n return 'c:' + this.id + ':' + this.connectionCount++;\n };\n ;\n Connection.prototype.disconnReceiver_ = function (conn) {\n var _this = this;\n return function (everConnected) {\n if (conn === _this.conn_) {\n _this.onConnectionLost_(everConnected);\n } else if (conn === _this.secondaryConn_) {\n _this.log_('Secondary connection lost.');\n _this.onSecondaryConnectionLost_();\n } else {\n _this.log_('closing an old connection');\n }\n };\n };\n Connection.prototype.connReceiver_ = function (conn) {\n var _this = this;\n return function (message) {\n if (_this.state_ != 2 /* DISCONNECTED */) {\n if (conn === _this.rx_) {\n _this.onPrimaryMessageReceived_(message);\n } else if (conn === _this.secondaryConn_) {\n _this.onSecondaryMessageReceived_(message);\n } else {\n _this.log_('message on old connection');\n }\n }\n };\n };\n /**\r\n *\r\n * @param {Object} dataMsg An arbitrary data message to be sent to the server\r\n */\n Connection.prototype.sendRequest = function (dataMsg) {\n // wrap in a data message envelope and send it on\n var msg = { 't': 'd', 'd': dataMsg };\n this.sendData_(msg);\n };\n Connection.prototype.tryCleanupConnection = function () {\n if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) {\n this.log_('cleaning up and promoting a connection: ' + this.secondaryConn_.connId);\n this.conn_ = this.secondaryConn_;\n this.secondaryConn_ = null;\n // the server will shutdown the old connection\n }\n };\n Connection.prototype.onSecondaryControl_ = function (controlData) {\n if (MESSAGE_TYPE in controlData) {\n var cmd = controlData[MESSAGE_TYPE];\n if (cmd === SWITCH_ACK) {\n this.upgradeIfSecondaryHealthy_();\n } else if (cmd === CONTROL_RESET) {\n // Most likely the session wasn't valid. Abandon the switch attempt\n this.log_('Got a reset on secondary, closing it');\n this.secondaryConn_.close();\n // If we were already using this connection for something, than we need to fully close\n if (this.tx_ === this.secondaryConn_ || this.rx_ === this.secondaryConn_) {\n this.close();\n }\n } else if (cmd === CONTROL_PONG) {\n this.log_('got pong on secondary.');\n this.secondaryResponsesRequired_--;\n this.upgradeIfSecondaryHealthy_();\n }\n }\n };\n Connection.prototype.onSecondaryMessageReceived_ = function (parsedData) {\n var layer = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"w\" /* requireKey */]('t', parsedData);\n var data = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"w\" /* requireKey */]('d', parsedData);\n if (layer == 'c') {\n this.onSecondaryControl_(data);\n } else if (layer == 'd') {\n // got a data message, but we're still second connection. Need to buffer it up\n this.pendingDataMessages.push(data);\n } else {\n throw new Error('Unknown protocol layer: ' + layer);\n }\n };\n Connection.prototype.upgradeIfSecondaryHealthy_ = function () {\n if (this.secondaryResponsesRequired_ <= 0) {\n this.log_('Secondary connection is healthy.');\n this.isHealthy_ = true;\n this.secondaryConn_.markConnectionHealthy();\n this.proceedWithUpgrade_();\n } else {\n // Send a ping to make sure the connection is healthy.\n this.log_('sending ping on secondary.');\n this.secondaryConn_.send({ 't': 'c', 'd': { 't': PING, 'd': {} } });\n }\n };\n Connection.prototype.proceedWithUpgrade_ = function () {\n // tell this connection to consider itself open\n this.secondaryConn_.start();\n // send ack\n this.log_('sending client ack on secondary');\n this.secondaryConn_.send({ 't': 'c', 'd': { 't': SWITCH_ACK, 'd': {} } });\n // send end packet on primary transport, switch to sending on this one\n // can receive on this one, buffer responses until end received on primary transport\n this.log_('Ending transmission on primary');\n this.conn_.send({ 't': 'c', 'd': { 't': END_TRANSMISSION, 'd': {} } });\n this.tx_ = this.secondaryConn_;\n this.tryCleanupConnection();\n };\n Connection.prototype.onPrimaryMessageReceived_ = function (parsedData) {\n // Must refer to parsedData properties in quotes, so closure doesn't touch them.\n var layer = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"w\" /* requireKey */]('t', parsedData);\n var data = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"w\" /* requireKey */]('d', parsedData);\n if (layer == 'c') {\n this.onControl_(data);\n } else if (layer == 'd') {\n this.onDataMessage_(data);\n }\n };\n Connection.prototype.onDataMessage_ = function (message) {\n this.onPrimaryResponse_();\n // We don't do anything with data messages, just kick them up a level\n this.onMessage_(message);\n };\n Connection.prototype.onPrimaryResponse_ = function () {\n if (!this.isHealthy_) {\n this.primaryResponsesRequired_--;\n if (this.primaryResponsesRequired_ <= 0) {\n this.log_('Primary connection is healthy.');\n this.isHealthy_ = true;\n this.conn_.markConnectionHealthy();\n }\n }\n };\n ;\n Connection.prototype.onControl_ = function (controlData) {\n var cmd = Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"w\" /* requireKey */](MESSAGE_TYPE, controlData);\n if (MESSAGE_DATA in controlData) {\n var payload = controlData[MESSAGE_DATA];\n if (cmd === SERVER_HELLO) {\n this.onHandshake_(payload);\n } else if (cmd === END_TRANSMISSION) {\n this.log_('recvd end transmission on primary');\n this.rx_ = this.secondaryConn_;\n for (var i = 0; i < this.pendingDataMessages.length; ++i) {\n this.onDataMessage_(this.pendingDataMessages[i]);\n }\n this.pendingDataMessages = [];\n this.tryCleanupConnection();\n } else if (cmd === CONTROL_SHUTDOWN) {\n // This was previously the 'onKill' callback passed to the lower-level connection\n // payload in this case is the reason for the shutdown. Generally a human-readable error\n this.onConnectionShutdown_(payload);\n } else if (cmd === CONTROL_RESET) {\n // payload in this case is the host we should contact\n this.onReset_(payload);\n } else if (cmd === CONTROL_ERROR) {\n Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"k\" /* error */]('Server Error: ' + payload);\n } else if (cmd === CONTROL_PONG) {\n this.log_('got pong on primary.');\n this.onPrimaryResponse_();\n this.sendPingOnPrimaryIfNecessary_();\n } else {\n Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"k\" /* error */]('Unknown control packet command: ' + cmd);\n }\n }\n };\n /**\r\n *\r\n * @param {Object} handshake The handshake data returned from the server\r\n * @private\r\n */\n Connection.prototype.onHandshake_ = function (handshake) {\n var timestamp = handshake.ts;\n var version = handshake.v;\n var host = handshake.h;\n this.sessionId = handshake.s;\n this.repoInfo_.updateHost(host);\n // if we've already closed the connection, then don't bother trying to progress further\n if (this.state_ == 0 /* CONNECTING */) {\n this.conn_.start();\n this.onConnectionEstablished_(this.conn_, timestamp);\n if (__WEBPACK_IMPORTED_MODULE_2__Constants__[\"e\" /* PROTOCOL_VERSION */] !== version) {\n Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"B\" /* warn */]('Protocol version mismatch detected');\n }\n // TODO: do we want to upgrade? when? maybe a delay?\n this.tryStartUpgrade_();\n }\n };\n Connection.prototype.tryStartUpgrade_ = function () {\n var conn = this.transportManager_.upgradeTransport();\n if (conn) {\n this.startUpgrade_(conn);\n }\n };\n Connection.prototype.startUpgrade_ = function (conn) {\n var _this = this;\n this.secondaryConn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.sessionId);\n // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\n // can consider the transport healthy.\n this.secondaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0;\n var onMessage = this.connReceiver_(this.secondaryConn_);\n var onDisconnect = this.disconnReceiver_(this.secondaryConn_);\n this.secondaryConn_.open(onMessage, onDisconnect);\n // If we haven't successfully upgraded after UPGRADE_TIMEOUT, give up and kill the secondary.\n Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"x\" /* setTimeoutNonBlocking */](function () {\n if (_this.secondaryConn_) {\n _this.log_('Timed out trying to upgrade.');\n _this.secondaryConn_.close();\n }\n }, Math.floor(UPGRADE_TIMEOUT));\n };\n Connection.prototype.onReset_ = function (host) {\n this.log_('Reset packet received. New host: ' + host);\n this.repoInfo_.updateHost(host);\n // TODO: if we're already \"connected\", we need to trigger a disconnect at the next layer up.\n // We don't currently support resets after the connection has already been established\n if (this.state_ === 1 /* CONNECTED */) {\n this.close();\n } else {\n // Close whatever connections we have open and start again.\n this.closeConnections_();\n this.start_();\n }\n };\n Connection.prototype.onConnectionEstablished_ = function (conn, timestamp) {\n var _this = this;\n this.log_('Realtime connection established.');\n this.conn_ = conn;\n this.state_ = 1 /* CONNECTED */;\n if (this.onReady_) {\n this.onReady_(timestamp, this.sessionId);\n this.onReady_ = null;\n }\n // If after 5 seconds we haven't sent enough requests to the server to get the connection healthy,\n // send some pings.\n if (this.primaryResponsesRequired_ === 0) {\n this.log_('Primary connection is healthy.');\n this.isHealthy_ = true;\n } else {\n Connection___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"x\" /* setTimeoutNonBlocking */](function () {\n _this.sendPingOnPrimaryIfNecessary_();\n }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS));\n }\n };\n Connection.prototype.sendPingOnPrimaryIfNecessary_ = function () {\n // If the connection isn't considered healthy yet, we'll send a noop ping packet request.\n if (!this.isHealthy_ && this.state_ === 1 /* CONNECTED */) {\n this.log_('sending ping on primary.');\n this.sendData_({ 't': 'c', 'd': { 't': PING, 'd': {} } });\n }\n };\n Connection.prototype.onSecondaryConnectionLost_ = function () {\n var conn = this.secondaryConn_;\n this.secondaryConn_ = null;\n if (this.tx_ === conn || this.rx_ === conn) {\n // we are relying on this connection already in some capacity. Therefore, a failure is real\n this.close();\n }\n };\n /**\r\n *\r\n * @param {boolean} everConnected Whether or not the connection ever reached a server. Used to determine if\r\n * we should flush the host cache\r\n * @private\r\n */\n Connection.prototype.onConnectionLost_ = function (everConnected) {\n this.conn_ = null;\n // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting\n // called on window close and RealtimeState.CONNECTING is no longer defined. Just a guess.\n if (!everConnected && this.state_ === 0 /* CONNECTING */) {\n this.log_('Realtime connection failed.');\n // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away\n if (this.repoInfo_.isCacheableHost()) {\n __WEBPACK_IMPORTED_MODULE_1__core_storage_storage__[\"a\" /* PersistentStorage */].remove('host:' + this.repoInfo_.host);\n // reset the internal host to what we would show the user, i.e. .firebaseio.com\n this.repoInfo_.internalHost = this.repoInfo_.host;\n }\n } else if (this.state_ === 1 /* CONNECTED */) {\n this.log_('Realtime connection lost.');\n }\n this.close();\n };\n /**\r\n *\r\n * @param {string} reason\r\n * @private\r\n */\n Connection.prototype.onConnectionShutdown_ = function (reason) {\n this.log_('Connection shutdown command received. Shutting down...');\n if (this.onKill_) {\n this.onKill_(reason);\n this.onKill_ = null;\n }\n // We intentionally don't want to fire onDisconnect (kill is a different case),\n // so clear the callback.\n this.onDisconnect_ = null;\n this.close();\n };\n Connection.prototype.sendData_ = function (data) {\n if (this.state_ !== 1 /* CONNECTED */) {\n throw 'Connection is not connected';\n } else {\n this.tx_.send(data);\n }\n };\n /**\r\n * Cleans up this connection, calling the appropriate callbacks\r\n */\n Connection.prototype.close = function () {\n if (this.state_ !== 2 /* DISCONNECTED */) {\n this.log_('Closing realtime connection.');\n this.state_ = 2 /* DISCONNECTED */;\n this.closeConnections_();\n if (this.onDisconnect_) {\n this.onDisconnect_();\n this.onDisconnect_ = null;\n }\n }\n };\n /**\r\n *\r\n * @private\r\n */\n Connection.prototype.closeConnections_ = function () {\n this.log_('Shutting down all connections');\n if (this.conn_) {\n this.conn_.close();\n this.conn_ = null;\n }\n if (this.secondaryConn_) {\n this.secondaryConn_.close();\n this.secondaryConn_ = null;\n }\n if (this.healthyTimeout_) {\n clearTimeout(this.healthyTimeout_);\n this.healthyTimeout_ = null;\n }\n };\n return Connection;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/ServerActions.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * Interface defining the set of actions that can be performed against the Firebase server\r\n * (basically corresponds to our wire protocol).\r\n *\r\n * @interface\r\n */\nvar ServerActions = function () {\n function ServerActions() {}\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, string)=} onComplete\r\n * @param {string=} hash\r\n */\n ServerActions.prototype.put = function (pathString, data, onComplete, hash) {};\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, ?string)} onComplete\r\n * @param {string=} hash\r\n */\n ServerActions.prototype.merge = function (pathString, data, onComplete, hash) {};\n /**\r\n * Refreshes the auth token for the current connection.\r\n * @param {string} token The authentication token\r\n */\n ServerActions.prototype.refreshAuthToken = function (token) {};\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, string)=} onComplete\r\n */\n ServerActions.prototype.onDisconnectPut = function (pathString, data, onComplete) {};\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, string)=} onComplete\r\n */\n ServerActions.prototype.onDisconnectMerge = function (pathString, data, onComplete) {};\n /**\r\n * @param {string} pathString\r\n * @param {function(string, string)=} onComplete\r\n */\n ServerActions.prototype.onDisconnectCancel = function (pathString, onComplete) {};\n /**\r\n * @param {Object.} stats\r\n */\n ServerActions.prototype.reportStats = function (stats) {};\n return ServerActions;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/PersistentConnection.ts\n/* harmony import */ var PersistentConnection___WEBPACK_IMPORTED_MODULE_0__app__ = __webpack_require__(5);\n/* harmony import */ var PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_json__ = __webpack_require__(3);\n/* harmony import */ var PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__utils_constants__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__utils_environment__ = __webpack_require__(6);\nvar PersistentConnection__typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\nvar PersistentConnection___extends = this && this.__extends || function () {\n var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (b.hasOwnProperty(p)) d[p] = b[p];\n }\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar RECONNECT_MIN_DELAY = 1000;\nvar RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1000; // 5 minutes in milliseconds (Case: 1858)\nvar RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1000; // 30 seconds for admin clients (likely to be a backend server)\nvar RECONNECT_DELAY_MULTIPLIER = 1.3;\nvar RECONNECT_DELAY_RESET_TIMEOUT = 30000; // Reset delay back to MIN_DELAY after being connected for 30sec.\nvar SERVER_KILL_INTERRUPT_REASON = 'server_kill';\n// If auth fails repeatedly, we'll assume something is wrong and log a warning / back off.\nvar INVALID_AUTH_TOKEN_THRESHOLD = 3;\n/**\r\n * Firebase connection. Abstracts wire protocol and handles reconnecting.\r\n *\r\n * NOTE: All JSON objects sent to the realtime connection must have property names enclosed\r\n * in quotes to make sure the closure compiler does not minify them.\r\n */\nvar PersistentConnection_PersistentConnection = function (_super) {\n PersistentConnection___extends(PersistentConnection, _super);\n /**\r\n * @implements {ServerActions}\r\n * @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to\r\n * @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server\r\n * @param onConnectStatus_\r\n * @param onServerInfoUpdate_\r\n * @param authTokenProvider_\r\n * @param authOverride_\r\n */\n function PersistentConnection(repoInfo_, onDataUpdate_, onConnectStatus_, onServerInfoUpdate_, authTokenProvider_, authOverride_) {\n var _this = _super.call(this) || this;\n _this.repoInfo_ = repoInfo_;\n _this.onDataUpdate_ = onDataUpdate_;\n _this.onConnectStatus_ = onConnectStatus_;\n _this.onServerInfoUpdate_ = onServerInfoUpdate_;\n _this.authTokenProvider_ = authTokenProvider_;\n _this.authOverride_ = authOverride_;\n // Used for diagnostic logging.\n _this.id = PersistentConnection.nextPersistentConnectionId_++;\n _this.log_ = __WEBPACK_IMPORTED_MODULE_4__util_util__[\"t\" /* logWrapper */]('p:' + _this.id + ':');\n /** @private {Object} */\n _this.interruptReasons_ = {};\n _this.listens_ = {};\n _this.outstandingPuts_ = [];\n _this.outstandingPutCount_ = 0;\n _this.onDisconnectRequestQueue_ = [];\n _this.connected_ = false;\n _this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n _this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT;\n _this.securityDebugCallback_ = null;\n _this.lastSessionId = null;\n /** @private {number|null} */\n _this.establishConnectionTimer_ = null;\n /** @private {boolean} */\n _this.visible_ = false;\n // Before we get connected, we keep a queue of pending messages to send.\n _this.requestCBHash_ = {};\n _this.requestNumber_ = 0;\n /** @private {?{\r\n * sendRequest(Object),\r\n * close()\r\n * }} */\n _this.realtime_ = null;\n /** @private {string|null} */\n _this.authToken_ = null;\n _this.forceTokenRefresh_ = false;\n _this.invalidAuthTokenCount_ = 0;\n _this.firstConnection_ = true;\n _this.lastConnectionAttemptTime_ = null;\n _this.lastConnectionEstablishedTime_ = null;\n if (authOverride_ && !__WEBPACK_IMPORTED_MODULE_11__utils_environment__[\"b\" /* isNodeSdk */]()) {\n throw new Error('Auth override specified in options, but not supported on non Node.js platforms');\n }\n _this.scheduleConnect_(0);\n VisibilityMonitor.getInstance().on('visible', _this.onVisible_, _this);\n if (repoInfo_.host.indexOf('fblocal') === -1) {\n OnlineMonitor.getInstance().on('online', _this.onOnline_, _this);\n }\n return _this;\n }\n /**\r\n * @param {!string} action\r\n * @param {*} body\r\n * @param {function(*)=} onResponse\r\n * @protected\r\n */\n PersistentConnection.prototype.sendRequest = function (action, body, onResponse) {\n var curReqNum = ++this.requestNumber_;\n var msg = { 'r': curReqNum, 'a': action, 'b': body };\n this.log_(__WEBPACK_IMPORTED_MODULE_2__utils_json__[\"b\" /* stringify */](msg));\n PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](this.connected_, 'sendRequest call when we\\'re not connected not allowed.');\n this.realtime_.sendRequest(msg);\n if (onResponse) {\n this.requestCBHash_[curReqNum] = onResponse;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.listen = function (query, currentHashFn, tag, onComplete) {\n var queryId = query.queryIdentifier();\n var pathString = query.path.toString();\n this.log_('Listen called for ' + pathString + ' ' + queryId);\n this.listens_[pathString] = this.listens_[pathString] || {};\n PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), 'listen() called for non-default but complete query');\n PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](!this.listens_[pathString][queryId], 'listen() called twice for same path/queryId.');\n var listenSpec = {\n onComplete: onComplete,\n hashFn: currentHashFn,\n query: query,\n tag: tag\n };\n this.listens_[pathString][queryId] = listenSpec;\n if (this.connected_) {\n this.sendListen_(listenSpec);\n }\n };\n /**\r\n * @param {!{onComplete(),\r\n * hashFn():!string,\r\n * query: !Query,\r\n * tag: ?number}} listenSpec\r\n * @private\r\n */\n PersistentConnection.prototype.sendListen_ = function (listenSpec) {\n var _this = this;\n var query = listenSpec.query;\n var pathString = query.path.toString();\n var queryId = query.queryIdentifier();\n this.log_('Listen on ' + pathString + ' for ' + queryId);\n var req = { /*path*/'p': pathString };\n var action = 'q';\n // Only bother to send query if it's non-default.\n if (listenSpec.tag) {\n req['q'] = query.queryObject();\n req['t'] = listenSpec.tag;\n }\n req['h'] = listenSpec.hashFn();\n this.sendRequest(action, req, function (message) {\n var payload = message['d'];\n var status = message['s'];\n // print warnings in any case...\n PersistentConnection.warnOnListenWarnings_(payload, query);\n var currentListenSpec = _this.listens_[pathString] && _this.listens_[pathString][queryId];\n // only trigger actions if the listen hasn't been removed and readded\n if (currentListenSpec === listenSpec) {\n _this.log_('listen response', message);\n if (status !== 'ok') {\n _this.removeListen_(pathString, queryId);\n }\n if (listenSpec.onComplete) {\n listenSpec.onComplete(status, payload);\n }\n }\n });\n };\n /**\r\n * @param {*} payload\r\n * @param {!Query} query\r\n * @private\r\n */\n PersistentConnection.warnOnListenWarnings_ = function (payload, query) {\n if (payload && (typeof payload === 'undefined' ? 'undefined' : PersistentConnection__typeof(payload)) === 'object' && PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"b\" /* contains */](payload, 'w')) {\n var warnings = PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"l\" /* safeGet */](payload, 'w');\n if (Array.isArray(warnings) && ~warnings.indexOf('no_index')) {\n var indexSpec = '\".indexOn\": \"' + query.getQueryParams().getIndex().toString() + '\"';\n var indexPath = query.path.toString();\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"B\" /* warn */]('Using an unspecified index. Consider adding ' + indexSpec + ' at ' + indexPath + ' to your security rules for better performance');\n }\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.refreshAuthToken = function (token) {\n this.authToken_ = token;\n this.log_('Auth token refreshed');\n if (this.authToken_) {\n this.tryAuth();\n } else {\n //If we're connected we want to let the server know to unauthenticate us. If we're not connected, simply delete\n //the credential so we dont become authenticated next time we connect.\n if (this.connected_) {\n this.sendRequest('unauth', {}, function () {});\n }\n }\n this.reduceReconnectDelayIfAdminCredential_(token);\n };\n /**\r\n * @param {!string} credential\r\n * @private\r\n */\n PersistentConnection.prototype.reduceReconnectDelayIfAdminCredential_ = function (credential) {\n // NOTE: This isn't intended to be bulletproof (a malicious developer can always just modify the client).\n // Additionally, we don't bother resetting the max delay back to the default if auth fails / expires.\n var isFirebaseSecret = credential && credential.length === 40;\n if (isFirebaseSecret || isAdmin(credential)) {\n this.log_('Admin auth credential detected. Reducing max reconnect time.');\n this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\n }\n };\n /**\r\n * Attempts to authenticate with the given credentials. If the authentication attempt fails, it's triggered like\r\n * a auth revoked (the connection is closed).\r\n */\n PersistentConnection.prototype.tryAuth = function () {\n var _this = this;\n if (this.connected_ && this.authToken_) {\n var token_1 = this.authToken_;\n var authMethod = isValidFormat(token_1) ? 'auth' : 'gauth';\n var requestData = { 'cred': token_1 };\n if (this.authOverride_ === null) {\n requestData['noauth'] = true;\n } else if (PersistentConnection__typeof(this.authOverride_) === 'object') {\n requestData['authvar'] = this.authOverride_;\n }\n this.sendRequest(authMethod, requestData, function (res) {\n var status = res['s'];\n var data = res['d'] || 'error';\n if (_this.authToken_ === token_1) {\n if (status === 'ok') {\n _this.invalidAuthTokenCount_ = 0;\n } else {\n // Triggers reconnect and force refresh for auth token\n _this.onAuthRevoked_(status, data);\n }\n }\n });\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.unlisten = function (query, tag) {\n var pathString = query.path.toString();\n var queryId = query.queryIdentifier();\n this.log_('Unlisten called for ' + pathString + ' ' + queryId);\n PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), 'unlisten() called for non-default but complete query');\n var listen = this.removeListen_(pathString, queryId);\n if (listen && this.connected_) {\n this.sendUnlisten_(pathString, queryId, query.queryObject(), tag);\n }\n };\n PersistentConnection.prototype.sendUnlisten_ = function (pathString, queryId, queryObj, tag) {\n this.log_('Unlisten on ' + pathString + ' for ' + queryId);\n var req = { /*path*/'p': pathString };\n var action = 'n';\n // Only bother sending queryId if it's non-default.\n if (tag) {\n req['q'] = queryObj;\n req['t'] = tag;\n }\n this.sendRequest(action, req);\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.onDisconnectPut = function (pathString, data, onComplete) {\n if (this.connected_) {\n this.sendOnDisconnect_('o', pathString, data, onComplete);\n } else {\n this.onDisconnectRequestQueue_.push({\n pathString: pathString,\n action: 'o',\n data: data,\n onComplete: onComplete\n });\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.onDisconnectMerge = function (pathString, data, onComplete) {\n if (this.connected_) {\n this.sendOnDisconnect_('om', pathString, data, onComplete);\n } else {\n this.onDisconnectRequestQueue_.push({\n pathString: pathString,\n action: 'om',\n data: data,\n onComplete: onComplete\n });\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.onDisconnectCancel = function (pathString, onComplete) {\n if (this.connected_) {\n this.sendOnDisconnect_('oc', pathString, null, onComplete);\n } else {\n this.onDisconnectRequestQueue_.push({\n pathString: pathString,\n action: 'oc',\n data: null,\n onComplete: onComplete\n });\n }\n };\n PersistentConnection.prototype.sendOnDisconnect_ = function (action, pathString, data, onComplete) {\n var request = { /*path*/'p': pathString, /*data*/'d': data };\n this.log_('onDisconnect ' + action, request);\n this.sendRequest(action, request, function (response) {\n if (onComplete) {\n setTimeout(function () {\n onComplete(response['s'], response['d']);\n }, Math.floor(0));\n }\n });\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.put = function (pathString, data, onComplete, hash) {\n this.putInternal('p', pathString, data, onComplete, hash);\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.merge = function (pathString, data, onComplete, hash) {\n this.putInternal('m', pathString, data, onComplete, hash);\n };\n PersistentConnection.prototype.putInternal = function (action, pathString, data, onComplete, hash) {\n var request = { /*path*/'p': pathString, /*data*/'d': data };\n if (hash !== undefined) request['h'] = hash;\n // TODO: Only keep track of the most recent put for a given path?\n this.outstandingPuts_.push({\n action: action,\n request: request,\n onComplete: onComplete\n });\n this.outstandingPutCount_++;\n var index = this.outstandingPuts_.length - 1;\n if (this.connected_) {\n this.sendPut_(index);\n } else {\n this.log_('Buffering put: ' + pathString);\n }\n };\n PersistentConnection.prototype.sendPut_ = function (index) {\n var _this = this;\n var action = this.outstandingPuts_[index].action;\n var request = this.outstandingPuts_[index].request;\n var onComplete = this.outstandingPuts_[index].onComplete;\n this.outstandingPuts_[index].queued = this.connected_;\n this.sendRequest(action, request, function (message) {\n _this.log_(action + ' response', message);\n delete _this.outstandingPuts_[index];\n _this.outstandingPutCount_--;\n // Clean up array occasionally.\n if (_this.outstandingPutCount_ === 0) {\n _this.outstandingPuts_ = [];\n }\n if (onComplete) onComplete(message['s'], message['d']);\n });\n };\n /**\r\n * @inheritDoc\r\n */\n PersistentConnection.prototype.reportStats = function (stats) {\n var _this = this;\n // If we're not connected, we just drop the stats.\n if (this.connected_) {\n var request = { /*counters*/'c': stats };\n this.log_('reportStats', request);\n this.sendRequest( /*stats*/'s', request, function (result) {\n var status = result['s'];\n if (status !== 'ok') {\n var errorReason = result['d'];\n _this.log_('reportStats', 'Error sending stats: ' + errorReason);\n }\n });\n }\n };\n /**\r\n * @param {*} message\r\n * @private\r\n */\n PersistentConnection.prototype.onDataMessage_ = function (message) {\n if ('r' in message) {\n // this is a response\n this.log_('from server: ' + __WEBPACK_IMPORTED_MODULE_2__utils_json__[\"b\" /* stringify */](message));\n var reqNum = message['r'];\n var onResponse = this.requestCBHash_[reqNum];\n if (onResponse) {\n delete this.requestCBHash_[reqNum];\n onResponse(message['b']);\n }\n } else if ('error' in message) {\n throw 'A server-side error has occurred: ' + message['error'];\n } else if ('a' in message) {\n // a and b are action and body, respectively\n this.onDataPush_(message['a'], message['b']);\n }\n };\n PersistentConnection.prototype.onDataPush_ = function (action, body) {\n this.log_('handleServerMessage', action, body);\n if (action === 'd') this.onDataUpdate_(body['p'], body['d'], /*isMerge*/false, body['t']);else if (action === 'm') this.onDataUpdate_(body['p'], body['d'], /*isMerge=*/true, body['t']);else if (action === 'c') this.onListenRevoked_(body['p'], body['q']);else if (action === 'ac') this.onAuthRevoked_(body['s'], body['d']);else if (action === 'sd') this.onSecurityDebugPacket_(body);else __WEBPACK_IMPORTED_MODULE_4__util_util__[\"k\" /* error */]('Unrecognized action received from server: ' + __WEBPACK_IMPORTED_MODULE_2__utils_json__[\"b\" /* stringify */](action) + '\\nAre you using the latest client?');\n };\n PersistentConnection.prototype.onReady_ = function (timestamp, sessionId) {\n this.log_('connection ready');\n this.connected_ = true;\n this.lastConnectionEstablishedTime_ = new Date().getTime();\n this.handleTimestamp_(timestamp);\n this.lastSessionId = sessionId;\n if (this.firstConnection_) {\n this.sendConnectStats_();\n }\n this.restoreState_();\n this.firstConnection_ = false;\n this.onConnectStatus_(true);\n };\n PersistentConnection.prototype.scheduleConnect_ = function (timeout) {\n var _this = this;\n PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](!this.realtime_, 'Scheduling a connect when we\\'re already connected/ing?');\n if (this.establishConnectionTimer_) {\n clearTimeout(this.establishConnectionTimer_);\n }\n // NOTE: Even when timeout is 0, it's important to do a setTimeout to work around an infuriating \"Security Error\" in\n // Firefox when trying to write to our long-polling iframe in some scenarios (e.g. Forge or our unit tests).\n this.establishConnectionTimer_ = setTimeout(function () {\n _this.establishConnectionTimer_ = null;\n _this.establishConnection_();\n }, Math.floor(timeout));\n };\n /**\r\n * @param {boolean} visible\r\n * @private\r\n */\n PersistentConnection.prototype.onVisible_ = function (visible) {\n // NOTE: Tabbing away and back to a window will defeat our reconnect backoff, but I think that's fine.\n if (visible && !this.visible_ && this.reconnectDelay_ === this.maxReconnectDelay_) {\n this.log_('Window became visible. Reducing delay.');\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n if (!this.realtime_) {\n this.scheduleConnect_(0);\n }\n }\n this.visible_ = visible;\n };\n PersistentConnection.prototype.onOnline_ = function (online) {\n if (online) {\n this.log_('Browser went online.');\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n if (!this.realtime_) {\n this.scheduleConnect_(0);\n }\n } else {\n this.log_('Browser went offline. Killing connection.');\n if (this.realtime_) {\n this.realtime_.close();\n }\n }\n };\n PersistentConnection.prototype.onRealtimeDisconnect_ = function () {\n this.log_('data client disconnected');\n this.connected_ = false;\n this.realtime_ = null;\n // Since we don't know if our sent transactions succeeded or not, we need to cancel them.\n this.cancelSentTransactions_();\n // Clear out the pending requests.\n this.requestCBHash_ = {};\n if (this.shouldReconnect_()) {\n if (!this.visible_) {\n this.log_('Window isn\\'t visible. Delaying reconnect.');\n this.reconnectDelay_ = this.maxReconnectDelay_;\n this.lastConnectionAttemptTime_ = new Date().getTime();\n } else if (this.lastConnectionEstablishedTime_) {\n // If we've been connected long enough, reset reconnect delay to minimum.\n var timeSinceLastConnectSucceeded = new Date().getTime() - this.lastConnectionEstablishedTime_;\n if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT) this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n this.lastConnectionEstablishedTime_ = null;\n }\n var timeSinceLastConnectAttempt = new Date().getTime() - this.lastConnectionAttemptTime_;\n var reconnectDelay = Math.max(0, this.reconnectDelay_ - timeSinceLastConnectAttempt);\n reconnectDelay = Math.random() * reconnectDelay;\n this.log_('Trying to reconnect in ' + reconnectDelay + 'ms');\n this.scheduleConnect_(reconnectDelay);\n // Adjust reconnect delay for next time.\n this.reconnectDelay_ = Math.min(this.maxReconnectDelay_, this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER);\n }\n this.onConnectStatus_(false);\n };\n PersistentConnection.prototype.establishConnection_ = function () {\n if (this.shouldReconnect_()) {\n this.log_('Making a connection attempt');\n this.lastConnectionAttemptTime_ = new Date().getTime();\n this.lastConnectionEstablishedTime_ = null;\n var onDataMessage_1 = this.onDataMessage_.bind(this);\n var onReady_1 = this.onReady_.bind(this);\n var onDisconnect_1 = this.onRealtimeDisconnect_.bind(this);\n var connId_1 = this.id + ':' + PersistentConnection.nextConnectionId_++;\n var self_1 = this;\n var lastSessionId_1 = this.lastSessionId;\n var canceled_1 = false;\n var connection_1 = null;\n var closeFn_1 = function closeFn_1() {\n if (connection_1) {\n connection_1.close();\n } else {\n canceled_1 = true;\n onDisconnect_1();\n }\n };\n var sendRequestFn = function sendRequestFn(msg) {\n PersistentConnection___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](connection_1, 'sendRequest call when we\\'re not connected not allowed.');\n connection_1.sendRequest(msg);\n };\n this.realtime_ = {\n close: closeFn_1,\n sendRequest: sendRequestFn\n };\n var forceRefresh = this.forceTokenRefresh_;\n this.forceTokenRefresh_ = false;\n // First fetch auth token, and establish connection after fetching the token was successful\n this.authTokenProvider_.getToken(forceRefresh).then(function (result) {\n if (!canceled_1) {\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"s\" /* log */]('getToken() completed. Creating connection.');\n self_1.authToken_ = result && result.accessToken;\n connection_1 = new Connection_Connection(connId_1, self_1.repoInfo_, onDataMessage_1, onReady_1, onDisconnect_1, /* onKill= */function (reason) {\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"B\" /* warn */](reason + ' (' + self_1.repoInfo_.toString() + ')');\n self_1.interrupt(SERVER_KILL_INTERRUPT_REASON);\n }, lastSessionId_1);\n } else {\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"s\" /* log */]('getToken() completed but was canceled');\n }\n }).then(null, function (error) {\n self_1.log_('Failed to get token: ' + error);\n if (!canceled_1) {\n if (__WEBPACK_IMPORTED_MODULE_10__utils_constants__[\"a\" /* CONSTANTS */].NODE_ADMIN) {\n // This may be a critical error for the Admin Node.js SDK, so log a warning.\n // But getToken() may also just have temporarily failed, so we still want to\n // continue retrying.\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"B\" /* warn */](error);\n }\n closeFn_1();\n }\n });\n }\n };\n /**\r\n * @param {string} reason\r\n */\n PersistentConnection.prototype.interrupt = function (reason) {\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"s\" /* log */]('Interrupting connection for reason: ' + reason);\n this.interruptReasons_[reason] = true;\n if (this.realtime_) {\n this.realtime_.close();\n } else {\n if (this.establishConnectionTimer_) {\n clearTimeout(this.establishConnectionTimer_);\n this.establishConnectionTimer_ = null;\n }\n if (this.connected_) {\n this.onRealtimeDisconnect_();\n }\n }\n };\n /**\r\n * @param {string} reason\r\n */\n PersistentConnection.prototype.resume = function (reason) {\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"s\" /* log */]('Resuming connection for reason: ' + reason);\n delete this.interruptReasons_[reason];\n if (PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"j\" /* isEmpty */](this.interruptReasons_)) {\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n if (!this.realtime_) {\n this.scheduleConnect_(0);\n }\n }\n };\n PersistentConnection.prototype.handleTimestamp_ = function (timestamp) {\n var delta = timestamp - new Date().getTime();\n this.onServerInfoUpdate_({ 'serverTimeOffset': delta });\n };\n PersistentConnection.prototype.cancelSentTransactions_ = function () {\n for (var i = 0; i < this.outstandingPuts_.length; i++) {\n var put = this.outstandingPuts_[i];\n if (put && 'h' in put.request && put.queued) {\n if (put.onComplete) put.onComplete('disconnect');\n delete this.outstandingPuts_[i];\n this.outstandingPutCount_--;\n }\n }\n // Clean up array occasionally.\n if (this.outstandingPutCount_ === 0) this.outstandingPuts_ = [];\n };\n /**\r\n * @param {!string} pathString\r\n * @param {Array.<*>=} query\r\n * @private\r\n */\n PersistentConnection.prototype.onListenRevoked_ = function (pathString, query) {\n // Remove the listen and manufacture a \"permission_denied\" error for the failed listen.\n var queryId;\n if (!query) {\n queryId = 'default';\n } else {\n queryId = query.map(function (q) {\n return __WEBPACK_IMPORTED_MODULE_4__util_util__[\"d\" /* ObjectToUniqueKey */](q);\n }).join('$');\n }\n var listen = this.removeListen_(pathString, queryId);\n if (listen && listen.onComplete) listen.onComplete('permission_denied');\n };\n /**\r\n * @param {!string} pathString\r\n * @param {!string} queryId\r\n * @return {{queries:Array., onComplete:function(string)}}\r\n * @private\r\n */\n PersistentConnection.prototype.removeListen_ = function (pathString, queryId) {\n var normalizedPathString = new Path(pathString).toString(); // normalize path.\n var listen;\n if (this.listens_[normalizedPathString] !== undefined) {\n listen = this.listens_[normalizedPathString][queryId];\n delete this.listens_[normalizedPathString][queryId];\n if (PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"h\" /* getCount */](this.listens_[normalizedPathString]) === 0) {\n delete this.listens_[normalizedPathString];\n }\n } else {\n // all listens for this path has already been removed\n listen = undefined;\n }\n return listen;\n };\n PersistentConnection.prototype.onAuthRevoked_ = function (statusCode, explanation) {\n __WEBPACK_IMPORTED_MODULE_4__util_util__[\"s\" /* log */]('Auth token revoked: ' + statusCode + '/' + explanation);\n this.authToken_ = null;\n this.forceTokenRefresh_ = true;\n this.realtime_.close();\n if (statusCode === 'invalid_token' || statusCode === 'permission_denied') {\n // We'll wait a couple times before logging the warning / increasing the\n // retry period since oauth tokens will report as \"invalid\" if they're\n // just expired. Plus there may be transient issues that resolve themselves.\n this.invalidAuthTokenCount_++;\n if (this.invalidAuthTokenCount_ >= INVALID_AUTH_TOKEN_THRESHOLD) {\n // Set a long reconnect delay because recovery is unlikely\n this.reconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\n // Notify the auth token provider that the token is invalid, which will log\n // a warning\n this.authTokenProvider_.notifyForInvalidToken();\n }\n }\n };\n PersistentConnection.prototype.onSecurityDebugPacket_ = function (body) {\n if (this.securityDebugCallback_) {\n this.securityDebugCallback_(body);\n } else {\n if ('msg' in body && typeof console !== 'undefined') {\n console.log('FIREBASE: ' + body['msg'].replace('\\n', '\\nFIREBASE: '));\n }\n }\n };\n PersistentConnection.prototype.restoreState_ = function () {\n var _this = this;\n //Re-authenticate ourselves if we have a credential stored.\n this.tryAuth();\n // Puts depend on having received the corresponding data update from the server before they complete, so we must\n // make sure to send listens before puts.\n PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"f\" /* forEach */](this.listens_, function (pathString, queries) {\n PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"f\" /* forEach */](queries, function (key, listenSpec) {\n _this.sendListen_(listenSpec);\n });\n });\n for (var i = 0; i < this.outstandingPuts_.length; i++) {\n if (this.outstandingPuts_[i]) this.sendPut_(i);\n }\n while (this.onDisconnectRequestQueue_.length) {\n var request = this.onDisconnectRequestQueue_.shift();\n this.sendOnDisconnect_(request.action, request.pathString, request.data, request.onComplete);\n }\n };\n /**\r\n * Sends client stats for first connection\r\n * @private\r\n */\n PersistentConnection.prototype.sendConnectStats_ = function () {\n var stats = {};\n var clientName = 'js';\n if (__WEBPACK_IMPORTED_MODULE_10__utils_constants__[\"a\" /* CONSTANTS */].NODE_ADMIN) {\n clientName = 'admin_node';\n } else if (__WEBPACK_IMPORTED_MODULE_10__utils_constants__[\"a\" /* CONSTANTS */].NODE_CLIENT) {\n clientName = 'node';\n }\n stats['sdk.' + clientName + '.' + PersistentConnection___WEBPACK_IMPORTED_MODULE_0__app__[\"default\"].SDK_VERSION.replace(/\\./g, '-')] = 1;\n if (__WEBPACK_IMPORTED_MODULE_11__utils_environment__[\"a\" /* isMobileCordova */]()) {\n stats['framework.cordova'] = 1;\n } else if (__WEBPACK_IMPORTED_MODULE_11__utils_environment__[\"c\" /* isReactNative */]()) {\n stats['framework.reactnative'] = 1;\n }\n this.reportStats(stats);\n };\n /**\r\n * @return {boolean}\r\n * @private\r\n */\n PersistentConnection.prototype.shouldReconnect_ = function () {\n var online = OnlineMonitor.getInstance().currentlyOnline();\n return PersistentConnection___WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"j\" /* isEmpty */](this.interruptReasons_) && online;\n };\n return PersistentConnection;\n}(ServerActions);\n\n/**\r\n * @private\r\n */\nPersistentConnection_PersistentConnection.nextPersistentConnectionId_ = 0;\n/**\r\n * Counter for number of connections created. Mainly used for tagging in the logs\r\n * @type {number}\r\n * @private\r\n */\nPersistentConnection_PersistentConnection.nextConnectionId_ = 0;\n// CONCATENATED MODULE: ./src/utils/util.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__obj__ = __webpack_require__(2);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n/**\r\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a params\r\n * object (e.g. {arg: 'val', arg2: 'val2'})\r\n * Note: You must prepend it with ? when adding it to a URL.\r\n *\r\n * @param {!Object} querystringParams\r\n * @return {string}\r\n */\nvar querystring = function querystring(querystringParams) {\n var params = [];\n __WEBPACK_IMPORTED_MODULE_0__obj__[\"f\" /* forEach */](querystringParams, function (key, value) {\n if (Array.isArray(value)) {\n value.forEach(function (arrayVal) {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal));\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return params.length ? '&' + params.join('&') : '';\n};\n/**\r\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object (e.g. {arg: 'val', arg2: 'val2'})\r\n *\r\n * @param {string} querystring\r\n * @return {!Object}\r\n */\nvar querystringDecode = function querystringDecode(querystring) {\n var obj = {};\n var tokens = querystring.replace(/^\\?/, '').split('&');\n tokens.forEach(function (token) {\n if (token) {\n var key = token.split('=');\n obj[key[0]] = key[1];\n }\n });\n return obj;\n};\n// CONCATENATED MODULE: ./src/database/core/ReadonlyRestClient.ts\n/* harmony import */ var ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_2__utils_json__ = __webpack_require__(3);\n/* harmony import */ var ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_3__utils_obj__ = __webpack_require__(2);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\nvar ReadonlyRestClient___extends = this && this.__extends || function () {\n var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (b.hasOwnProperty(p)) d[p] = b[p];\n }\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n/**\r\n * An implementation of ServerActions that communicates with the server via REST requests.\r\n * This is mostly useful for compatibility with crawlers, where we don't want to spin up a full\r\n * persistent connection (using WebSockets or long-polling)\r\n */\nvar ReadonlyRestClient_ReadonlyRestClient = function (_super) {\n ReadonlyRestClient___extends(ReadonlyRestClient, _super);\n /**\r\n * @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to\r\n * @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server\r\n * @param {AuthTokenProvider} authTokenProvider_\r\n * @implements {ServerActions}\r\n */\n function ReadonlyRestClient(repoInfo_, onDataUpdate_, authTokenProvider_) {\n var _this = _super.call(this) || this;\n _this.repoInfo_ = repoInfo_;\n _this.onDataUpdate_ = onDataUpdate_;\n _this.authTokenProvider_ = authTokenProvider_;\n /** @private {function(...[*])} */\n _this.log_ = ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_1__util_util__[\"t\" /* logWrapper */]('p:rest:');\n /**\r\n * We don't actually need to track listens, except to prevent us calling an onComplete for a listen\r\n * that's been removed. :-/\r\n *\r\n * @private {!Object.}\r\n */\n _this.listens_ = {};\n return _this;\n }\n ReadonlyRestClient.prototype.reportStats = function (stats) {\n throw new Error('Method not implemented.');\n };\n /**\r\n * @param {!Query} query\r\n * @param {?number=} tag\r\n * @return {string}\r\n * @private\r\n */\n ReadonlyRestClient.getListenId_ = function (query, tag) {\n if (tag !== undefined) {\n return 'tag$' + tag;\n } else {\n ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](query.getQueryParams().isDefault(), 'should have a tag if it\\'s not a default query.');\n return query.path.toString();\n }\n };\n /** @inheritDoc */\n ReadonlyRestClient.prototype.listen = function (query, currentHashFn, tag, onComplete) {\n var _this = this;\n var pathString = query.path.toString();\n this.log_('Listen called for ' + pathString + ' ' + query.queryIdentifier());\n // Mark this listener so we can tell if it's removed.\n var listenId = ReadonlyRestClient.getListenId_(query, tag);\n var thisListen = {};\n this.listens_[listenId] = thisListen;\n var queryStringParamaters = query.getQueryParams().toRestQueryStringParameters();\n this.restRequest_(pathString + '.json', queryStringParamaters, function (error, result) {\n var data = result;\n if (error === 404) {\n data = null;\n error = null;\n }\n if (error === null) {\n _this.onDataUpdate_(pathString, data, /*isMerge=*/false, tag);\n }\n if (ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_3__utils_obj__[\"l\" /* safeGet */](_this.listens_, listenId) === thisListen) {\n var status_1;\n if (!error) {\n status_1 = 'ok';\n } else if (error == 401) {\n status_1 = 'permission_denied';\n } else {\n status_1 = 'rest_error:' + error;\n }\n onComplete(status_1, null);\n }\n });\n };\n /** @inheritDoc */\n ReadonlyRestClient.prototype.unlisten = function (query, tag) {\n var listenId = ReadonlyRestClient.getListenId_(query, tag);\n delete this.listens_[listenId];\n };\n /** @inheritDoc */\n ReadonlyRestClient.prototype.refreshAuthToken = function (token) {\n // no-op since we just always call getToken.\n };\n /**\r\n * Performs a REST request to the given path, with the provided query string parameters,\r\n * and any auth credentials we have.\r\n *\r\n * @param {!string} pathString\r\n * @param {!Object.} queryStringParameters\r\n * @param {?function(?number, *=)} callback\r\n * @private\r\n */\n ReadonlyRestClient.prototype.restRequest_ = function (pathString, queryStringParameters, callback) {\n var _this = this;\n if (queryStringParameters === void 0) {\n queryStringParameters = {};\n }\n queryStringParameters['format'] = 'export';\n this.authTokenProvider_.getToken( /*forceRefresh=*/false).then(function (authTokenData) {\n var authToken = authTokenData && authTokenData.accessToken;\n if (authToken) {\n queryStringParameters['auth'] = authToken;\n }\n var url = (_this.repoInfo_.secure ? 'https://' : 'http://') + _this.repoInfo_.host + pathString + '?' + querystring(queryStringParameters);\n _this.log_('Sending REST request for ' + url);\n var xhr = new XMLHttpRequest();\n xhr.onreadystatechange = function () {\n if (callback && xhr.readyState === 4) {\n _this.log_('REST Response for ' + url + ' received. status:', xhr.status, 'response:', xhr.responseText);\n var res = null;\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n res = ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_2__utils_json__[\"a\" /* jsonEval */](xhr.responseText);\n } catch (e) {\n ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_1__util_util__[\"B\" /* warn */]('Failed to parse JSON response for ' + url + ': ' + xhr.responseText);\n }\n callback(null, res);\n } else {\n // 401 and 404 are expected.\n if (xhr.status !== 401 && xhr.status !== 404) {\n ReadonlyRestClient___WEBPACK_IMPORTED_MODULE_1__util_util__[\"B\" /* warn */]('Got unsuccessful REST response for ' + url + ' Status: ' + xhr.status);\n }\n callback(xhr.status);\n }\n callback = null;\n }\n };\n xhr.open('GET', url, /*asynchronous=*/true);\n xhr.send();\n });\n };\n return ReadonlyRestClient;\n}(ServerActions);\n\n// CONCATENATED MODULE: ./src/database/core/Repo.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_json__ = __webpack_require__(3);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__stats_StatsManager__ = __webpack_require__(12);\nvar Repo__typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar INTERRUPT_REASON = 'repo_interrupt';\n/**\r\n * A connection to a single data repository.\r\n */\nvar Repo_Repo = function () {\n /**\r\n * @param {!RepoInfo} repoInfo_\r\n * @param {boolean} forceRestClient\r\n * @param {!FirebaseApp} app\r\n */\n function Repo(repoInfo_, forceRestClient, app) {\n var _this = this;\n this.repoInfo_ = repoInfo_;\n this.app = app;\n this.dataUpdateCount = 0;\n this.statsListener_ = null;\n this.eventQueue_ = new EventQueue();\n this.nextWriteId_ = 1;\n this.interceptServerDataCallback_ = null;\n // A list of data pieces and paths to be set when this client disconnects.\n this.onDisconnect_ = new SparseSnapshotTree_SparseSnapshotTree();\n /**\r\n * TODO: This should be @private but it's used by test_access.js and internal.js\r\n * @type {?PersistentConnection}\r\n */\n this.persistentConnection_ = null;\n /** @type {!AuthTokenProvider} */\n var authTokenProvider = new AuthTokenProvider(app);\n this.stats_ = __WEBPACK_IMPORTED_MODULE_10__stats_StatsManager__[\"a\" /* StatsManager */].getCollection(repoInfo_);\n if (forceRestClient || __WEBPACK_IMPORTED_MODULE_7__util_util__[\"g\" /* beingCrawled */]()) {\n this.server_ = new ReadonlyRestClient_ReadonlyRestClient(this.repoInfo_, this.onDataUpdate_.bind(this), authTokenProvider);\n // Minor hack: Fire onConnect immediately, since there's no actual connection.\n setTimeout(this.onConnectStatus_.bind(this, true), 0);\n } else {\n var authOverride = app.options['databaseAuthVariableOverride'];\n // Validate authOverride\n if (typeof authOverride !== 'undefined' && authOverride !== null) {\n if ((typeof authOverride === 'undefined' ? 'undefined' : Repo__typeof(authOverride)) !== 'object') {\n throw new Error('Only objects are supported for option databaseAuthVariableOverride');\n }\n try {\n __WEBPACK_IMPORTED_MODULE_6__utils_json__[\"b\" /* stringify */](authOverride);\n } catch (e) {\n throw new Error('Invalid authOverride provided: ' + e);\n }\n }\n this.persistentConnection_ = new PersistentConnection_PersistentConnection(this.repoInfo_, this.onDataUpdate_.bind(this), this.onConnectStatus_.bind(this), this.onServerInfoUpdate_.bind(this), authTokenProvider, authOverride);\n this.server_ = this.persistentConnection_;\n }\n authTokenProvider.addTokenChangeListener(function (token) {\n _this.server_.refreshAuthToken(token);\n });\n // In the case of multiple Repos for the same repoInfo (i.e. there are multiple Firebase.Contexts being used),\n // we only want to create one StatsReporter. As such, we'll report stats over the first Repo created.\n this.statsReporter_ = __WEBPACK_IMPORTED_MODULE_10__stats_StatsManager__[\"a\" /* StatsManager */].getOrCreateReporter(repoInfo_, function () {\n return new StatsReporter_StatsReporter(_this.stats_, _this.server_);\n });\n this.transactions_init_();\n // Used for .info.\n this.infoData_ = new SnapshotHolder_SnapshotHolder();\n this.infoSyncTree_ = new SyncTree_SyncTree({\n startListening: function startListening(query, tag, currentHashFn, onComplete) {\n var infoEvents = [];\n var node = _this.infoData_.getNode(query.path);\n // This is possibly a hack, but we have different semantics for .info endpoints. We don't raise null events\n // on initial data...\n if (!node.isEmpty()) {\n infoEvents = _this.infoSyncTree_.applyServerOverwrite(query.path, node);\n setTimeout(function () {\n onComplete('ok');\n }, 0);\n }\n return infoEvents;\n },\n stopListening: function stopListening() {}\n });\n this.updateInfo_('connected', false);\n this.serverSyncTree_ = new SyncTree_SyncTree({\n startListening: function startListening(query, tag, currentHashFn, onComplete) {\n _this.server_.listen(query, currentHashFn, tag, function (status, data) {\n var events = onComplete(status, data);\n _this.eventQueue_.raiseEventsForChangedPath(query.path, events);\n });\n // No synchronous events for network-backed sync trees\n return [];\n },\n stopListening: function stopListening(query, tag) {\n _this.server_.unlisten(query, tag);\n }\n });\n }\n /**\r\n * @return {string} The URL corresponding to the root of this Firebase.\r\n */\n Repo.prototype.toString = function () {\n return (this.repoInfo_.secure ? 'https://' : 'http://') + this.repoInfo_.host;\n };\n /**\r\n * @return {!string} The namespace represented by the repo.\r\n */\n Repo.prototype.name = function () {\n return this.repoInfo_.namespace;\n };\n /**\r\n * @return {!number} The time in milliseconds, taking the server offset into account if we have one.\r\n */\n Repo.prototype.serverTime = function () {\n var offsetNode = this.infoData_.getNode(new Path('.info/serverTimeOffset'));\n var offset = offsetNode.val() || 0;\n return new Date().getTime() + offset;\n };\n /**\r\n * Generate ServerValues using some variables from the repo object.\r\n * @return {!Object}\r\n */\n Repo.prototype.generateServerValues = function () {\n return generateWithValues({\n 'timestamp': this.serverTime()\n });\n };\n /**\r\n * Called by realtime when we get new messages from the server.\r\n *\r\n * @private\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {boolean} isMerge\r\n * @param {?number} tag\r\n */\n Repo.prototype.onDataUpdate_ = function (pathString, data, isMerge, tag) {\n // For testing.\n this.dataUpdateCount++;\n var path = new Path(pathString);\n data = this.interceptServerDataCallback_ ? this.interceptServerDataCallback_(pathString, data) : data;\n var events = [];\n if (tag) {\n if (isMerge) {\n var taggedChildren = __WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"k\" /* map */](data, function (raw) {\n return nodeFromJSON_nodeFromJSON(raw);\n });\n events = this.serverSyncTree_.applyTaggedQueryMerge(path, taggedChildren, tag);\n } else {\n var taggedSnap = nodeFromJSON_nodeFromJSON(data);\n events = this.serverSyncTree_.applyTaggedQueryOverwrite(path, taggedSnap, tag);\n }\n } else if (isMerge) {\n var changedChildren = __WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"k\" /* map */](data, function (raw) {\n return nodeFromJSON_nodeFromJSON(raw);\n });\n events = this.serverSyncTree_.applyServerMerge(path, changedChildren);\n } else {\n var snap = nodeFromJSON_nodeFromJSON(data);\n events = this.serverSyncTree_.applyServerOverwrite(path, snap);\n }\n var affectedPath = path;\n if (events.length > 0) {\n // Since we have a listener outstanding for each transaction, receiving any events\n // is a proxy for some change having occurred.\n affectedPath = this.rerunTransactions_(path);\n }\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, events);\n };\n /**\r\n * TODO: This should be @private but it's used by test_access.js and internal.js\r\n * @param {?function(!string, *):*} callback\r\n * @private\r\n */\n Repo.prototype.interceptServerData_ = function (callback) {\n this.interceptServerDataCallback_ = callback;\n };\n /**\r\n * @param {!boolean} connectStatus\r\n * @private\r\n */\n Repo.prototype.onConnectStatus_ = function (connectStatus) {\n this.updateInfo_('connected', connectStatus);\n if (connectStatus === false) {\n this.runOnDisconnectEvents_();\n }\n };\n /**\r\n * @param {!Object} updates\r\n * @private\r\n */\n Repo.prototype.onServerInfoUpdate_ = function (updates) {\n var _this = this;\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"i\" /* each */](updates, function (value, key) {\n _this.updateInfo_(key, value);\n });\n };\n /**\r\n *\r\n * @param {!string} pathString\r\n * @param {*} value\r\n * @private\r\n */\n Repo.prototype.updateInfo_ = function (pathString, value) {\n var path = new Path('/.info/' + pathString);\n var newNode = nodeFromJSON_nodeFromJSON(value);\n this.infoData_.updateSnapshot(path, newNode);\n var events = this.infoSyncTree_.applyServerOverwrite(path, newNode);\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n };\n /**\r\n * @return {!number}\r\n * @private\r\n */\n Repo.prototype.getNextWriteId_ = function () {\n return this.nextWriteId_++;\n };\n /**\r\n * @param {!Path} path\r\n * @param {*} newVal\r\n * @param {number|string|null} newPriority\r\n * @param {?function(?Error, *=)} onComplete\r\n */\n Repo.prototype.setWithPriority = function (path, newVal, newPriority, onComplete) {\n var _this = this;\n this.log_('set', { path: path.toString(), value: newVal, priority: newPriority });\n // TODO: Optimize this behavior to either (a) store flag to skip resolving where possible and / or\n // (b) store unresolved paths on JSON parse\n var serverValues = this.generateServerValues();\n var newNodeUnresolved = nodeFromJSON_nodeFromJSON(newVal, newPriority);\n var newNode = ServerValues_resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\n var writeId = this.getNextWriteId_();\n var events = this.serverSyncTree_.applyUserOverwrite(path, newNode, writeId, true);\n this.eventQueue_.queueEvents(events);\n this.server_.put(path.toString(), newNodeUnresolved.val( /*export=*/true), function (status, errorReason) {\n var success = status === 'ok';\n if (!success) {\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"B\" /* warn */]('set at ' + path + ' failed: ' + status);\n }\n var clearEvents = _this.serverSyncTree_.ackUserWrite(writeId, !success);\n _this.eventQueue_.raiseEventsForChangedPath(path, clearEvents);\n _this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n var affectedPath = this.abortTransactions_(path);\n this.rerunTransactions_(affectedPath);\n // We queued the events above, so just flush the queue here\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, []);\n };\n /**\r\n * @param {!Path} path\r\n * @param {!Object} childrenToMerge\r\n * @param {?function(?Error, *=)} onComplete\r\n */\n Repo.prototype.update = function (path, childrenToMerge, onComplete) {\n var _this = this;\n this.log_('update', { path: path.toString(), value: childrenToMerge });\n // Start with our existing data and merge each child into it.\n var empty = true;\n var serverValues = this.generateServerValues();\n var changedChildren = {};\n __WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"f\" /* forEach */](childrenToMerge, function (changedKey, changedValue) {\n empty = false;\n var newNodeUnresolved = nodeFromJSON_nodeFromJSON(changedValue);\n changedChildren[changedKey] = ServerValues_resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\n });\n if (!empty) {\n var writeId_1 = this.getNextWriteId_();\n var events = this.serverSyncTree_.applyUserMerge(path, changedChildren, writeId_1);\n this.eventQueue_.queueEvents(events);\n this.server_.merge(path.toString(), childrenToMerge, function (status, errorReason) {\n var success = status === 'ok';\n if (!success) {\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"B\" /* warn */]('update at ' + path + ' failed: ' + status);\n }\n var clearEvents = _this.serverSyncTree_.ackUserWrite(writeId_1, !success);\n var affectedPath = clearEvents.length > 0 ? _this.rerunTransactions_(path) : path;\n _this.eventQueue_.raiseEventsForChangedPath(affectedPath, clearEvents);\n _this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n __WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"f\" /* forEach */](childrenToMerge, function (changedPath) {\n var affectedPath = _this.abortTransactions_(path.child(changedPath));\n _this.rerunTransactions_(affectedPath);\n });\n // We queued the events above, so just flush the queue here\n this.eventQueue_.raiseEventsForChangedPath(path, []);\n } else {\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"s\" /* log */]('update() called with empty data. Don\\'t do anything.');\n this.callOnCompleteCallback(onComplete, 'ok');\n }\n };\n /**\r\n * Applies all of the changes stored up in the onDisconnect_ tree.\r\n * @private\r\n */\n Repo.prototype.runOnDisconnectEvents_ = function () {\n var _this = this;\n this.log_('onDisconnectEvents');\n var serverValues = this.generateServerValues();\n var resolvedOnDisconnectTree = ServerValues_resolveDeferredValueTree(this.onDisconnect_, serverValues);\n var events = [];\n resolvedOnDisconnectTree.forEachTree(Path.Empty, function (path, snap) {\n events = events.concat(_this.serverSyncTree_.applyServerOverwrite(path, snap));\n var affectedPath = _this.abortTransactions_(path);\n _this.rerunTransactions_(affectedPath);\n });\n this.onDisconnect_ = new SparseSnapshotTree_SparseSnapshotTree();\n this.eventQueue_.raiseEventsForChangedPath(Path.Empty, events);\n };\n /**\r\n * @param {!Path} path\r\n * @param {?function(?Error, *=)} onComplete\r\n */\n Repo.prototype.onDisconnectCancel = function (path, onComplete) {\n var _this = this;\n this.server_.onDisconnectCancel(path.toString(), function (status, errorReason) {\n if (status === 'ok') {\n _this.onDisconnect_.forget(path);\n }\n _this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n };\n /**\r\n * @param {!Path} path\r\n * @param {*} value\r\n * @param {?function(?Error, *=)} onComplete\r\n */\n Repo.prototype.onDisconnectSet = function (path, value, onComplete) {\n var _this = this;\n var newNode = nodeFromJSON_nodeFromJSON(value);\n this.server_.onDisconnectPut(path.toString(), newNode.val( /*export=*/true), function (status, errorReason) {\n if (status === 'ok') {\n _this.onDisconnect_.remember(path, newNode);\n }\n _this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n };\n /**\r\n * @param {!Path} path\r\n * @param {*} value\r\n * @param {*} priority\r\n * @param {?function(?Error, *=)} onComplete\r\n */\n Repo.prototype.onDisconnectSetWithPriority = function (path, value, priority, onComplete) {\n var _this = this;\n var newNode = nodeFromJSON_nodeFromJSON(value, priority);\n this.server_.onDisconnectPut(path.toString(), newNode.val( /*export=*/true), function (status, errorReason) {\n if (status === 'ok') {\n _this.onDisconnect_.remember(path, newNode);\n }\n _this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n };\n /**\r\n * @param {!Path} path\r\n * @param {*} childrenToMerge\r\n * @param {?function(?Error, *=)} onComplete\r\n */\n Repo.prototype.onDisconnectUpdate = function (path, childrenToMerge, onComplete) {\n var _this = this;\n if (__WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"j\" /* isEmpty */](childrenToMerge)) {\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"s\" /* log */]('onDisconnect().update() called with empty data. Don\\'t do anything.');\n this.callOnCompleteCallback(onComplete, 'ok');\n return;\n }\n this.server_.onDisconnectMerge(path.toString(), childrenToMerge, function (status, errorReason) {\n if (status === 'ok') {\n __WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"f\" /* forEach */](childrenToMerge, function (childName, childNode) {\n var newChildNode = nodeFromJSON_nodeFromJSON(childNode);\n _this.onDisconnect_.remember(path.child(childName), newChildNode);\n });\n }\n _this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n };\n /**\r\n * @param {!Query} query\r\n * @param {!EventRegistration} eventRegistration\r\n */\n Repo.prototype.addEventCallbackForQuery = function (query, eventRegistration) {\n var events;\n if (query.path.getFront() === '.info') {\n events = this.infoSyncTree_.addEventRegistration(query, eventRegistration);\n } else {\n events = this.serverSyncTree_.addEventRegistration(query, eventRegistration);\n }\n this.eventQueue_.raiseEventsAtPath(query.path, events);\n };\n /**\r\n * @param {!Query} query\r\n * @param {?EventRegistration} eventRegistration\r\n */\n Repo.prototype.removeEventCallbackForQuery = function (query, eventRegistration) {\n // These are guaranteed not to raise events, since we're not passing in a cancelError. However, we can future-proof\n // a little bit by handling the return values anyways.\n var events;\n if (query.path.getFront() === '.info') {\n events = this.infoSyncTree_.removeEventRegistration(query, eventRegistration);\n } else {\n events = this.serverSyncTree_.removeEventRegistration(query, eventRegistration);\n }\n this.eventQueue_.raiseEventsAtPath(query.path, events);\n };\n Repo.prototype.interrupt = function () {\n if (this.persistentConnection_) {\n this.persistentConnection_.interrupt(INTERRUPT_REASON);\n }\n };\n Repo.prototype.resume = function () {\n if (this.persistentConnection_) {\n this.persistentConnection_.resume(INTERRUPT_REASON);\n }\n };\n Repo.prototype.stats = function (showDelta) {\n if (showDelta === void 0) {\n showDelta = false;\n }\n if (typeof console === 'undefined') return;\n var stats;\n if (showDelta) {\n if (!this.statsListener_) this.statsListener_ = new StatsListener(this.stats_);\n stats = this.statsListener_.get();\n } else {\n stats = this.stats_.get();\n }\n var longestName = Object.keys(stats).reduce(function (previousValue, currentValue) {\n return Math.max(currentValue.length, previousValue);\n }, 0);\n __WEBPACK_IMPORTED_MODULE_8__utils_obj__[\"f\" /* forEach */](stats, function (stat, value) {\n // pad stat names to be the same length (plus 2 extra spaces).\n for (var i = stat.length; i < longestName + 2; i++) {\n stat += ' ';\n }console.log(stat + value);\n });\n };\n Repo.prototype.statsIncrementCounter = function (metric) {\n this.stats_.incrementCounter(metric);\n this.statsReporter_.includeStat(metric);\n };\n /**\r\n * @param {...*} var_args\r\n * @private\r\n */\n Repo.prototype.log_ = function () {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n var prefix = '';\n if (this.persistentConnection_) {\n prefix = this.persistentConnection_.id + ':';\n }\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"s\" /* log */].apply(void 0, [prefix].concat(var_args));\n };\n /**\r\n * @param {?function(?Error, *=)} callback\r\n * @param {!string} status\r\n * @param {?string=} errorReason\r\n */\n Repo.prototype.callOnCompleteCallback = function (callback, status, errorReason) {\n if (callback) {\n __WEBPACK_IMPORTED_MODULE_7__util_util__[\"m\" /* exceptionGuard */](function () {\n if (status == 'ok') {\n callback(null);\n } else {\n var code = (status || 'error').toUpperCase();\n var message = code;\n if (errorReason) message += ': ' + errorReason;\n var error = new Error(message);\n error.code = code;\n callback(error);\n }\n });\n }\n };\n Object.defineProperty(Repo.prototype, \"database\", {\n get: function get() {\n return this.__database || (this.__database = new Database_Database(this));\n },\n enumerable: true,\n configurable: true\n });\n return Repo;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/view/filter/RangedFilter.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n/**\r\n * Filters nodes by range and uses an IndexFilter to track any changes after filtering the node\r\n *\r\n * @constructor\r\n * @implements {NodeFilter}\r\n */\nvar RangedFilter_RangedFilter = function () {\n /**\r\n * @param {!QueryParams} params\r\n */\n function RangedFilter(params) {\n this.indexedFilter_ = new IndexedFilter_IndexedFilter(params.getIndex());\n this.index_ = params.getIndex();\n this.startPost_ = RangedFilter.getStartPost_(params);\n this.endPost_ = RangedFilter.getEndPost_(params);\n }\n /**\r\n * @return {!NamedNode}\r\n */\n RangedFilter.prototype.getStartPost = function () {\n return this.startPost_;\n };\n /**\r\n * @return {!NamedNode}\r\n */\n RangedFilter.prototype.getEndPost = function () {\n return this.endPost_;\n };\n /**\r\n * @param {!NamedNode} node\r\n * @return {boolean}\r\n */\n RangedFilter.prototype.matches = function (node) {\n return this.index_.compare(this.getStartPost(), node) <= 0 && this.index_.compare(node, this.getEndPost()) <= 0;\n };\n /**\r\n * @inheritDoc\r\n */\n RangedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {\n if (!this.matches(new NamedNode(key, newChild))) {\n newChild = ChildrenNode_ChildrenNode.EMPTY_NODE;\n }\n return this.indexedFilter_.updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator);\n };\n /**\r\n * @inheritDoc\r\n */\n RangedFilter.prototype.updateFullNode = function (oldSnap, newSnap, optChangeAccumulator) {\n if (newSnap.isLeafNode()) {\n // Make sure we have a children node with the correct index, not a leaf node;\n newSnap = ChildrenNode_ChildrenNode.EMPTY_NODE;\n }\n var filtered = newSnap.withIndex(this.index_);\n // Don't support priorities on queries\n filtered = filtered.updatePriority(ChildrenNode_ChildrenNode.EMPTY_NODE);\n var self = this;\n newSnap.forEachChild(PRIORITY_INDEX, function (key, childNode) {\n if (!self.matches(new NamedNode(key, childNode))) {\n filtered = filtered.updateImmediateChild(key, ChildrenNode_ChildrenNode.EMPTY_NODE);\n }\n });\n return this.indexedFilter_.updateFullNode(oldSnap, filtered, optChangeAccumulator);\n };\n /**\r\n * @inheritDoc\r\n */\n RangedFilter.prototype.updatePriority = function (oldSnap, newPriority) {\n // Don't support priorities on queries\n return oldSnap;\n };\n /**\r\n * @inheritDoc\r\n */\n RangedFilter.prototype.filtersNodes = function () {\n return true;\n };\n /**\r\n * @inheritDoc\r\n */\n RangedFilter.prototype.getIndexedFilter = function () {\n return this.indexedFilter_;\n };\n /**\r\n * @inheritDoc\r\n */\n RangedFilter.prototype.getIndex = function () {\n return this.index_;\n };\n /**\r\n * @param {!QueryParams} params\r\n * @return {!NamedNode}\r\n * @private\r\n */\n RangedFilter.getStartPost_ = function (params) {\n if (params.hasStart()) {\n var startName = params.getIndexStartName();\n return params.getIndex().makePost(params.getIndexStartValue(), startName);\n } else {\n return params.getIndex().minPost();\n }\n };\n /**\r\n * @param {!QueryParams} params\r\n * @return {!NamedNode}\r\n * @private\r\n */\n RangedFilter.getEndPost_ = function (params) {\n if (params.hasEnd()) {\n var endName = params.getIndexEndName();\n return params.getIndex().makePost(params.getIndexEndValue(), endName);\n } else {\n return params.getIndex().maxPost();\n }\n };\n return RangedFilter;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/view/filter/LimitedFilter.ts\n/* harmony import */ var LimitedFilter___WEBPACK_IMPORTED_MODULE_3__utils_assert__ = __webpack_require__(0);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n/**\r\n * Applies a limit and a range to a node and uses RangedFilter to do the heavy lifting where possible\r\n *\r\n * @constructor\r\n * @implements {NodeFilter}\r\n */\nvar LimitedFilter_LimitedFilter = function () {\n /**\r\n * @param {!QueryParams} params\r\n */\n function LimitedFilter(params) {\n this.rangedFilter_ = new RangedFilter_RangedFilter(params);\n this.index_ = params.getIndex();\n this.limit_ = params.getLimit();\n this.reverse_ = !params.isViewFromLeft();\n }\n /**\r\n * @inheritDoc\r\n */\n LimitedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {\n if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {\n newChild = ChildrenNode_ChildrenNode.EMPTY_NODE;\n }\n if (snap.getImmediateChild(key).equals(newChild)) {\n // No change\n return snap;\n } else if (snap.numChildren() < this.limit_) {\n return this.rangedFilter_.getIndexedFilter().updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator);\n } else {\n return this.fullLimitUpdateChild_(snap, key, newChild, source, optChangeAccumulator);\n }\n };\n /**\r\n * @inheritDoc\r\n */\n LimitedFilter.prototype.updateFullNode = function (oldSnap, newSnap, optChangeAccumulator) {\n var filtered;\n if (newSnap.isLeafNode() || newSnap.isEmpty()) {\n // Make sure we have a children node with the correct index, not a leaf node;\n filtered = ChildrenNode_ChildrenNode.EMPTY_NODE.withIndex(this.index_);\n } else {\n if (this.limit_ * 2 < newSnap.numChildren() && newSnap.isIndexed(this.index_)) {\n // Easier to build up a snapshot, since what we're given has more than twice the elements we want\n filtered = ChildrenNode_ChildrenNode.EMPTY_NODE.withIndex(this.index_);\n // anchor to the startPost, endPost, or last element as appropriate\n var iterator = void 0;\n if (this.reverse_) {\n iterator = newSnap.getReverseIteratorFrom(this.rangedFilter_.getEndPost(), this.index_);\n } else {\n iterator = newSnap.getIteratorFrom(this.rangedFilter_.getStartPost(), this.index_);\n }\n var count = 0;\n while (iterator.hasNext() && count < this.limit_) {\n var next = iterator.getNext();\n var inRange = void 0;\n if (this.reverse_) {\n inRange = this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;\n } else {\n inRange = this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;\n }\n if (inRange) {\n filtered = filtered.updateImmediateChild(next.name, next.node);\n count++;\n } else {\n // if we have reached the end post, we cannot keep adding elemments\n break;\n }\n }\n } else {\n // The snap contains less than twice the limit. Faster to delete from the snap than build up a new one\n filtered = newSnap.withIndex(this.index_);\n // Don't support priorities on queries\n filtered = filtered.updatePriority(ChildrenNode_ChildrenNode.EMPTY_NODE);\n var startPost = void 0;\n var endPost = void 0;\n var cmp = void 0;\n var iterator = void 0;\n if (this.reverse_) {\n iterator = filtered.getReverseIterator(this.index_);\n startPost = this.rangedFilter_.getEndPost();\n endPost = this.rangedFilter_.getStartPost();\n var indexCompare_1 = this.index_.getCompare();\n cmp = function cmp(a, b) {\n return indexCompare_1(b, a);\n };\n } else {\n iterator = filtered.getIterator(this.index_);\n startPost = this.rangedFilter_.getStartPost();\n endPost = this.rangedFilter_.getEndPost();\n cmp = this.index_.getCompare();\n }\n var count = 0;\n var foundStartPost = false;\n while (iterator.hasNext()) {\n var next = iterator.getNext();\n if (!foundStartPost && cmp(startPost, next) <= 0) {\n // start adding\n foundStartPost = true;\n }\n var inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;\n if (inRange) {\n count++;\n } else {\n filtered = filtered.updateImmediateChild(next.name, ChildrenNode_ChildrenNode.EMPTY_NODE);\n }\n }\n }\n }\n return this.rangedFilter_.getIndexedFilter().updateFullNode(oldSnap, filtered, optChangeAccumulator);\n };\n /**\r\n * @inheritDoc\r\n */\n LimitedFilter.prototype.updatePriority = function (oldSnap, newPriority) {\n // Don't support priorities on queries\n return oldSnap;\n };\n /**\r\n * @inheritDoc\r\n */\n LimitedFilter.prototype.filtersNodes = function () {\n return true;\n };\n /**\r\n * @inheritDoc\r\n */\n LimitedFilter.prototype.getIndexedFilter = function () {\n return this.rangedFilter_.getIndexedFilter();\n };\n /**\r\n * @inheritDoc\r\n */\n LimitedFilter.prototype.getIndex = function () {\n return this.index_;\n };\n /**\r\n * @param {!Node} snap\r\n * @param {string} childKey\r\n * @param {!Node} childSnap\r\n * @param {!CompleteChildSource} source\r\n * @param {?ChildChangeAccumulator} changeAccumulator\r\n * @return {!Node}\r\n * @private\r\n */\n LimitedFilter.prototype.fullLimitUpdateChild_ = function (snap, childKey, childSnap, source, changeAccumulator) {\n // TODO: rename all cache stuff etc to general snap terminology\n var cmp;\n if (this.reverse_) {\n var indexCmp_1 = this.index_.getCompare();\n cmp = function cmp(a, b) {\n return indexCmp_1(b, a);\n };\n } else {\n cmp = this.index_.getCompare();\n }\n var oldEventCache = snap;\n LimitedFilter___WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* assert */](oldEventCache.numChildren() == this.limit_, '');\n var newChildNamedNode = new NamedNode(childKey, childSnap);\n var windowBoundary = this.reverse_ ? oldEventCache.getFirstChild(this.index_) : oldEventCache.getLastChild(this.index_);\n var inRange = this.rangedFilter_.matches(newChildNamedNode);\n if (oldEventCache.hasChild(childKey)) {\n var oldChildSnap = oldEventCache.getImmediateChild(childKey);\n var nextChild = source.getChildAfterChild(this.index_, windowBoundary, this.reverse_);\n while (nextChild != null && (nextChild.name == childKey || oldEventCache.hasChild(nextChild.name))) {\n // There is a weird edge case where a node is updated as part of a merge in the write tree, but hasn't\n // been applied to the limited filter yet. Ignore this next child which will be updated later in\n // the limited filter...\n nextChild = source.getChildAfterChild(this.index_, nextChild, this.reverse_);\n }\n var compareNext = nextChild == null ? 1 : cmp(nextChild, newChildNamedNode);\n var remainsInWindow = inRange && !childSnap.isEmpty() && compareNext >= 0;\n if (remainsInWindow) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childChangedChange(childKey, childSnap, oldChildSnap));\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap);\n } else {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childRemovedChange(childKey, oldChildSnap));\n }\n var newEventCache = oldEventCache.updateImmediateChild(childKey, ChildrenNode_ChildrenNode.EMPTY_NODE);\n var nextChildInRange = nextChild != null && this.rangedFilter_.matches(nextChild);\n if (nextChildInRange) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childAddedChange(nextChild.name, nextChild.node));\n }\n return newEventCache.updateImmediateChild(nextChild.name, nextChild.node);\n } else {\n return newEventCache;\n }\n }\n } else if (childSnap.isEmpty()) {\n // we're deleting a node, but it was not in the window, so ignore it\n return snap;\n } else if (inRange) {\n if (cmp(windowBoundary, newChildNamedNode) >= 0) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childRemovedChange(windowBoundary.name, windowBoundary.node));\n changeAccumulator.trackChildChange(Change.childAddedChange(childKey, childSnap));\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap).updateImmediateChild(windowBoundary.name, ChildrenNode_ChildrenNode.EMPTY_NODE);\n } else {\n return snap;\n }\n } else {\n return snap;\n }\n };\n return LimitedFilter;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/view/QueryParams.ts\n/* harmony import */ var QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var QueryParams___WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__utils_json__ = __webpack_require__(3);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n\n\n\n\n/**\r\n * This class is an immutable-from-the-public-api struct containing a set of query parameters defining a\r\n * range to be returned for a particular location. It is assumed that validation of parameters is done at the\r\n * user-facing API level, so it is not done here.\r\n * @constructor\r\n */\nvar QueryParams_QueryParams = function () {\n function QueryParams() {\n this.limitSet_ = false;\n this.startSet_ = false;\n this.startNameSet_ = false;\n this.endSet_ = false;\n this.endNameSet_ = false;\n this.limit_ = 0;\n this.viewFrom_ = '';\n this.indexStartValue_ = null;\n this.indexStartName_ = '';\n this.indexEndValue_ = null;\n this.indexEndName_ = '';\n this.index_ = PRIORITY_INDEX;\n }\n /**\r\n * @return {boolean}\r\n */\n QueryParams.prototype.hasStart = function () {\n return this.startSet_;\n };\n /**\r\n * @return {boolean} True if it would return from left.\r\n */\n QueryParams.prototype.isViewFromLeft = function () {\n if (this.viewFrom_ === '') {\n // limit(), rather than limitToFirst or limitToLast was called.\n // This means that only one of startSet_ and endSet_ is true. Use them\n // to calculate which side of the view to anchor to. If neither is set,\n // anchor to the end.\n return this.startSet_;\n } else {\n return this.viewFrom_ === QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;\n }\n };\n /**\r\n * Only valid to call if hasStart() returns true\r\n * @return {*}\r\n */\n QueryParams.prototype.getIndexStartValue = function () {\n QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](this.startSet_, 'Only valid if start has been set');\n return this.indexStartValue_;\n };\n /**\r\n * Only valid to call if hasStart() returns true.\r\n * Returns the starting key name for the range defined by these query parameters\r\n * @return {!string}\r\n */\n QueryParams.prototype.getIndexStartName = function () {\n QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](this.startSet_, 'Only valid if start has been set');\n if (this.startNameSet_) {\n return this.indexStartName_;\n } else {\n return QueryParams___WEBPACK_IMPORTED_MODULE_1__util_util__[\"c\" /* MIN_NAME */];\n }\n };\n /**\r\n * @return {boolean}\r\n */\n QueryParams.prototype.hasEnd = function () {\n return this.endSet_;\n };\n /**\r\n * Only valid to call if hasEnd() returns true.\r\n * @return {*}\r\n */\n QueryParams.prototype.getIndexEndValue = function () {\n QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](this.endSet_, 'Only valid if end has been set');\n return this.indexEndValue_;\n };\n /**\r\n * Only valid to call if hasEnd() returns true.\r\n * Returns the end key name for the range defined by these query parameters\r\n * @return {!string}\r\n */\n QueryParams.prototype.getIndexEndName = function () {\n QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](this.endSet_, 'Only valid if end has been set');\n if (this.endNameSet_) {\n return this.indexEndName_;\n } else {\n return QueryParams___WEBPACK_IMPORTED_MODULE_1__util_util__[\"b\" /* MAX_NAME */];\n }\n };\n /**\r\n * @return {boolean}\r\n */\n QueryParams.prototype.hasLimit = function () {\n return this.limitSet_;\n };\n /**\r\n * @return {boolean} True if a limit has been set and it has been explicitly anchored\r\n */\n QueryParams.prototype.hasAnchoredLimit = function () {\n return this.limitSet_ && this.viewFrom_ !== '';\n };\n /**\r\n * Only valid to call if hasLimit() returns true\r\n * @return {!number}\r\n */\n QueryParams.prototype.getLimit = function () {\n QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](this.limitSet_, 'Only valid if limit has been set');\n return this.limit_;\n };\n /**\r\n * @return {!Index}\r\n */\n QueryParams.prototype.getIndex = function () {\n return this.index_;\n };\n /**\r\n * @return {!QueryParams}\r\n * @private\r\n */\n QueryParams.prototype.copy_ = function () {\n var copy = new QueryParams();\n copy.limitSet_ = this.limitSet_;\n copy.limit_ = this.limit_;\n copy.startSet_ = this.startSet_;\n copy.indexStartValue_ = this.indexStartValue_;\n copy.startNameSet_ = this.startNameSet_;\n copy.indexStartName_ = this.indexStartName_;\n copy.endSet_ = this.endSet_;\n copy.indexEndValue_ = this.indexEndValue_;\n copy.endNameSet_ = this.endNameSet_;\n copy.indexEndName_ = this.indexEndName_;\n copy.index_ = this.index_;\n copy.viewFrom_ = this.viewFrom_;\n return copy;\n };\n /**\r\n * @param {!number} newLimit\r\n * @return {!QueryParams}\r\n */\n QueryParams.prototype.limit = function (newLimit) {\n var newParams = this.copy_();\n newParams.limitSet_ = true;\n newParams.limit_ = newLimit;\n newParams.viewFrom_ = '';\n return newParams;\n };\n /**\r\n * @param {!number} newLimit\r\n * @return {!QueryParams}\r\n */\n QueryParams.prototype.limitToFirst = function (newLimit) {\n var newParams = this.copy_();\n newParams.limitSet_ = true;\n newParams.limit_ = newLimit;\n newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;\n return newParams;\n };\n /**\r\n * @param {!number} newLimit\r\n * @return {!QueryParams}\r\n */\n QueryParams.prototype.limitToLast = function (newLimit) {\n var newParams = this.copy_();\n newParams.limitSet_ = true;\n newParams.limit_ = newLimit;\n newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_RIGHT;\n return newParams;\n };\n ;\n /**\r\n * @param {*} indexValue\r\n * @param {?string=} key\r\n * @return {!QueryParams}\r\n */\n QueryParams.prototype.startAt = function (indexValue, key) {\n var newParams = this.copy_();\n newParams.startSet_ = true;\n if (!(indexValue !== undefined)) {\n indexValue = null;\n }\n newParams.indexStartValue_ = indexValue;\n if (key != null) {\n newParams.startNameSet_ = true;\n newParams.indexStartName_ = key;\n } else {\n newParams.startNameSet_ = false;\n newParams.indexStartName_ = '';\n }\n return newParams;\n };\n /**\r\n * @param {*} indexValue\r\n * @param {?string=} key\r\n * @return {!QueryParams}\r\n */\n QueryParams.prototype.endAt = function (indexValue, key) {\n var newParams = this.copy_();\n newParams.endSet_ = true;\n if (!(indexValue !== undefined)) {\n indexValue = null;\n }\n newParams.indexEndValue_ = indexValue;\n if (key !== undefined) {\n newParams.endNameSet_ = true;\n newParams.indexEndName_ = key;\n } else {\n newParams.endNameSet_ = false;\n newParams.indexEndName_ = '';\n }\n return newParams;\n };\n ;\n /**\r\n * @param {!Index} index\r\n * @return {!QueryParams}\r\n */\n QueryParams.prototype.orderBy = function (index) {\n var newParams = this.copy_();\n newParams.index_ = index;\n return newParams;\n };\n /**\r\n * @return {!Object}\r\n */\n QueryParams.prototype.getQueryObject = function () {\n var WIRE_PROTOCOL_CONSTANTS = QueryParams.WIRE_PROTOCOL_CONSTANTS_;\n var obj = {};\n if (this.startSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE] = this.indexStartValue_;\n if (this.startNameSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME] = this.indexStartName_;\n }\n }\n if (this.endSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE] = this.indexEndValue_;\n if (this.endNameSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME] = this.indexEndName_;\n }\n }\n if (this.limitSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.LIMIT] = this.limit_;\n var viewFrom = this.viewFrom_;\n if (viewFrom === '') {\n if (this.isViewFromLeft()) {\n viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT;\n } else {\n viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT;\n }\n }\n obj[WIRE_PROTOCOL_CONSTANTS.VIEW_FROM] = viewFrom;\n }\n // For now, priority index is the default, so we only specify if it's some other index\n if (this.index_ !== PRIORITY_INDEX) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX] = this.index_.toString();\n }\n return obj;\n };\n /**\r\n * @return {boolean}\r\n */\n QueryParams.prototype.loadsAllData = function () {\n return !(this.startSet_ || this.endSet_ || this.limitSet_);\n };\n /**\r\n * @return {boolean}\r\n */\n QueryParams.prototype.isDefault = function () {\n return this.loadsAllData() && this.index_ == PRIORITY_INDEX;\n };\n /**\r\n * @return {!NodeFilter}\r\n */\n QueryParams.prototype.getNodeFilter = function () {\n if (this.loadsAllData()) {\n return new IndexedFilter_IndexedFilter(this.getIndex());\n } else if (this.hasLimit()) {\n return new LimitedFilter_LimitedFilter(this);\n } else {\n return new RangedFilter_RangedFilter(this);\n }\n };\n /**\r\n * Returns a set of REST query string parameters representing this query.\r\n *\r\n * @return {!Object.} query string parameters\r\n */\n QueryParams.prototype.toRestQueryStringParameters = function () {\n var REST_CONSTANTS = QueryParams.REST_QUERY_CONSTANTS_;\n var qs = {};\n if (this.isDefault()) {\n return qs;\n }\n var orderBy;\n if (this.index_ === PRIORITY_INDEX) {\n orderBy = REST_CONSTANTS.PRIORITY_INDEX;\n } else if (this.index_ === VALUE_INDEX) {\n orderBy = REST_CONSTANTS.VALUE_INDEX;\n } else if (this.index_ === KEY_INDEX) {\n orderBy = REST_CONSTANTS.KEY_INDEX;\n } else {\n QueryParams___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](this.index_ instanceof PathIndex_PathIndex, 'Unrecognized index type!');\n orderBy = this.index_.toString();\n }\n qs[REST_CONSTANTS.ORDER_BY] = __WEBPACK_IMPORTED_MODULE_9__utils_json__[\"b\" /* stringify */](orderBy);\n if (this.startSet_) {\n qs[REST_CONSTANTS.START_AT] = __WEBPACK_IMPORTED_MODULE_9__utils_json__[\"b\" /* stringify */](this.indexStartValue_);\n if (this.startNameSet_) {\n qs[REST_CONSTANTS.START_AT] += ',' + __WEBPACK_IMPORTED_MODULE_9__utils_json__[\"b\" /* stringify */](this.indexStartName_);\n }\n }\n if (this.endSet_) {\n qs[REST_CONSTANTS.END_AT] = __WEBPACK_IMPORTED_MODULE_9__utils_json__[\"b\" /* stringify */](this.indexEndValue_);\n if (this.endNameSet_) {\n qs[REST_CONSTANTS.END_AT] += ',' + __WEBPACK_IMPORTED_MODULE_9__utils_json__[\"b\" /* stringify */](this.indexEndName_);\n }\n }\n if (this.limitSet_) {\n if (this.isViewFromLeft()) {\n qs[REST_CONSTANTS.LIMIT_TO_FIRST] = this.limit_;\n } else {\n qs[REST_CONSTANTS.LIMIT_TO_LAST] = this.limit_;\n }\n }\n return qs;\n };\n return QueryParams;\n}();\n\n/**\r\n * Wire Protocol Constants\r\n * @const\r\n * @enum {string}\r\n * @private\r\n */\nQueryParams_QueryParams.WIRE_PROTOCOL_CONSTANTS_ = {\n INDEX_START_VALUE: 'sp',\n INDEX_START_NAME: 'sn',\n INDEX_END_VALUE: 'ep',\n INDEX_END_NAME: 'en',\n LIMIT: 'l',\n VIEW_FROM: 'vf',\n VIEW_FROM_LEFT: 'l',\n VIEW_FROM_RIGHT: 'r',\n INDEX: 'i'\n};\n/**\r\n * REST Query Constants\r\n * @const\r\n * @enum {string}\r\n * @private\r\n */\nQueryParams_QueryParams.REST_QUERY_CONSTANTS_ = {\n ORDER_BY: 'orderBy',\n PRIORITY_INDEX: '$priority',\n VALUE_INDEX: '$value',\n KEY_INDEX: '$key',\n START_AT: 'startAt',\n END_AT: 'endAt',\n LIMIT_TO_FIRST: 'limitToFirst',\n LIMIT_TO_LAST: 'limitToLast'\n};\n/**\r\n * Default, empty query parameters\r\n * @type {!QueryParams}\r\n * @const\r\n */\nQueryParams_QueryParams.DEFAULT = new QueryParams_QueryParams();\n// CONCATENATED MODULE: ./src/database/api/Reference.ts\n/* harmony import */ var Reference___WEBPACK_IMPORTED_MODULE_2__core_util_util__ = __webpack_require__(1);\n/* harmony import */ var Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__ = __webpack_require__(4);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\nvar Reference___extends = this && this.__extends || function () {\n var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (b.hasOwnProperty(p)) d[p] = b[p];\n }\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\nvar Reference_Reference = function (_super) {\n Reference___extends(Reference, _super);\n /**\r\n * Call options:\r\n * new Reference(Repo, Path) or\r\n * new Reference(url: string, string|RepoManager)\r\n *\r\n * Externally - this is the firebase.database.Reference type.\r\n *\r\n * @param {!Repo} repo\r\n * @param {(!Path)} path\r\n * @extends {Query}\r\n */\n function Reference(repo, path) {\n var _this = this;\n if (!(repo instanceof Repo_Repo)) {\n throw new Error('new Reference() no longer supported - use app.database().');\n }\n // call Query's constructor, passing in the repo and path.\n _this = _super.call(this, repo, path, QueryParams_QueryParams.DEFAULT, false) || this;\n return _this;\n }\n /** @return {?string} */\n Reference.prototype.getKey = function () {\n validateArgCount('Reference.key', 0, 0, arguments.length);\n if (this.path.isEmpty()) return null;else return this.path.getBack();\n };\n /**\r\n * @param {!(string|Path)} pathString\r\n * @return {!Reference}\r\n */\n Reference.prototype.child = function (pathString) {\n validateArgCount('Reference.child', 1, 1, arguments.length);\n if (typeof pathString === 'number') {\n pathString = String(pathString);\n } else if (!(pathString instanceof Path)) {\n if (this.path.getFront() === null) validateRootPathString('Reference.child', 1, pathString, false);else validation_validatePathString('Reference.child', 1, pathString, false);\n }\n return new Reference(this.repo, this.path.child(pathString));\n };\n /** @return {?Reference} */\n Reference.prototype.getParent = function () {\n validateArgCount('Reference.parent', 0, 0, arguments.length);\n var parentPath = this.path.parent();\n return parentPath === null ? null : new Reference(this.repo, parentPath);\n };\n /** @return {!Reference} */\n Reference.prototype.getRoot = function () {\n validateArgCount('Reference.root', 0, 0, arguments.length);\n var ref = this;\n while (ref.getParent() !== null) {\n ref = ref.getParent();\n }\n return ref;\n };\n /** @return {!Database} */\n Reference.prototype.databaseProp = function () {\n return this.repo.database;\n };\n /**\r\n * @param {*} newVal\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\n Reference.prototype.set = function (newVal, onComplete) {\n validateArgCount('Reference.set', 1, 2, arguments.length);\n validateWritablePath('Reference.set', this.path);\n validation_validateFirebaseDataArg('Reference.set', 1, newVal, this.path, false);\n validateCallback('Reference.set', 2, onComplete, true);\n var deferred = new Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"a\" /* Deferred */]();\n this.repo.setWithPriority(this.path, newVal, /*priority=*/null, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {!Object} objectToMerge\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\n Reference.prototype.update = function (objectToMerge, onComplete) {\n validateArgCount('Reference.update', 1, 2, arguments.length);\n validateWritablePath('Reference.update', this.path);\n if (Array.isArray(objectToMerge)) {\n var newObjectToMerge = {};\n for (var i = 0; i < objectToMerge.length; ++i) {\n newObjectToMerge['' + i] = objectToMerge[i];\n }\n objectToMerge = newObjectToMerge;\n Reference___WEBPACK_IMPORTED_MODULE_2__core_util_util__[\"B\" /* warn */]('Passing an Array to Firebase.update() is deprecated. ' + 'Use set() if you want to overwrite the existing data, or ' + 'an Object with integer keys if you really do want to ' + 'only update some of the children.');\n }\n validation_validateFirebaseMergeDataArg('Reference.update', 1, objectToMerge, this.path, false);\n validateCallback('Reference.update', 2, onComplete, true);\n var deferred = new Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"a\" /* Deferred */]();\n this.repo.update(this.path, objectToMerge, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {*} newVal\r\n * @param {string|number|null} newPriority\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\n Reference.prototype.setWithPriority = function (newVal, newPriority, onComplete) {\n validateArgCount('Reference.setWithPriority', 2, 3, arguments.length);\n validateWritablePath('Reference.setWithPriority', this.path);\n validation_validateFirebaseDataArg('Reference.setWithPriority', 1, newVal, this.path, false);\n validation_validatePriority('Reference.setWithPriority', 2, newPriority, false);\n validateCallback('Reference.setWithPriority', 3, onComplete, true);\n if (this.getKey() === '.length' || this.getKey() === '.keys') throw 'Reference.setWithPriority failed: ' + this.getKey() + ' is a read-only object.';\n var deferred = new Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"a\" /* Deferred */]();\n this.repo.setWithPriority(this.path, newVal, newPriority, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\n Reference.prototype.remove = function (onComplete) {\n validateArgCount('Reference.remove', 0, 1, arguments.length);\n validateWritablePath('Reference.remove', this.path);\n validateCallback('Reference.remove', 1, onComplete, true);\n return this.set(null, onComplete);\n };\n /**\r\n * @param {function(*):*} transactionUpdate\r\n * @param {(function(?Error, boolean, ?DataSnapshot))=} onComplete\r\n * @param {boolean=} applyLocally\r\n * @return {!Promise}\r\n */\n Reference.prototype.transaction = function (transactionUpdate, onComplete, applyLocally) {\n validateArgCount('Reference.transaction', 1, 3, arguments.length);\n validateWritablePath('Reference.transaction', this.path);\n validateCallback('Reference.transaction', 1, transactionUpdate, false);\n validateCallback('Reference.transaction', 2, onComplete, true);\n // NOTE: applyLocally is an internal-only option for now. We need to decide if we want to keep it and how\n // to expose it.\n validation_validateBoolean('Reference.transaction', 3, applyLocally, true);\n if (this.getKey() === '.length' || this.getKey() === '.keys') throw 'Reference.transaction failed: ' + this.getKey() + ' is a read-only object.';\n if (applyLocally === undefined) applyLocally = true;\n var deferred = new Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"a\" /* Deferred */]();\n if (typeof onComplete === 'function') {\n Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"c\" /* attachDummyErrorHandler */](deferred.promise);\n }\n var promiseComplete = function promiseComplete(error, committed, snapshot) {\n if (error) {\n deferred.reject(error);\n } else {\n deferred.resolve(new TransactionResult(committed, snapshot));\n }\n if (typeof onComplete === 'function') {\n onComplete(error, committed, snapshot);\n }\n };\n this.repo.startTransaction(this.path, transactionUpdate, promiseComplete, applyLocally);\n return deferred.promise;\n };\n /**\r\n * @param {string|number|null} priority\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\n Reference.prototype.setPriority = function (priority, onComplete) {\n validateArgCount('Reference.setPriority', 1, 2, arguments.length);\n validateWritablePath('Reference.setPriority', this.path);\n validation_validatePriority('Reference.setPriority', 1, priority, false);\n validateCallback('Reference.setPriority', 2, onComplete, true);\n var deferred = new Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"a\" /* Deferred */]();\n this.repo.setWithPriority(this.path.child('.priority'), priority, null, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {*=} value\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Reference}\r\n */\n Reference.prototype.push = function (value, onComplete) {\n validateArgCount('Reference.push', 0, 2, arguments.length);\n validateWritablePath('Reference.push', this.path);\n validation_validateFirebaseDataArg('Reference.push', 1, value, this.path, true);\n validateCallback('Reference.push', 2, onComplete, true);\n var now = this.repo.serverTime();\n var name = nextPushId(now);\n // push() returns a ThennableReference whose promise is fulfilled with a regular Reference.\n // We use child() to create handles to two different references. The first is turned into a\n // ThennableReference below by adding then() and catch() methods and is used as the\n // return value of push(). The second remains a regular Reference and is used as the fulfilled\n // value of the first ThennableReference.\n var thennablePushRef = this.child(name);\n var pushRef = this.child(name);\n var promise;\n if (value != null) {\n promise = thennablePushRef.set(value, onComplete).then(function () {\n return pushRef;\n });\n } else {\n promise = Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"b\" /* PromiseImpl */].resolve(pushRef);\n }\n thennablePushRef.then = promise.then.bind(promise);\n thennablePushRef.catch = promise.then.bind(promise, undefined);\n if (typeof onComplete === 'function') {\n Reference___WEBPACK_IMPORTED_MODULE_10__utils_promise__[\"c\" /* attachDummyErrorHandler */](promise);\n }\n return thennablePushRef;\n };\n /**\r\n * @return {!OnDisconnect}\r\n */\n Reference.prototype.onDisconnect = function () {\n validateWritablePath('Reference.onDisconnect', this.path);\n return new onDisconnect_OnDisconnect(this.repo, this.path);\n };\n Object.defineProperty(Reference.prototype, \"database\", {\n get: function get() {\n return this.databaseProp();\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"key\", {\n get: function get() {\n return this.getKey();\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"parent\", {\n get: function get() {\n return this.getParent();\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"root\", {\n get: function get() {\n return this.getRoot();\n },\n enumerable: true,\n configurable: true\n });\n return Reference;\n}(Query_Query);\n\n/**\r\n * Define reference constructor in various modules\r\n *\r\n * We are doing this here to avoid several circular\r\n * dependency issues\r\n */\nQuery_Query.__referenceConstructor = Reference_Reference;\nSyncPoint_SyncPoint.__referenceConstructor = Reference_Reference;\n// CONCATENATED MODULE: ./src/database/core/util/Tree.ts\n/* harmony import */ var Tree___WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var Tree___WEBPACK_IMPORTED_MODULE_2__utils_obj__ = __webpack_require__(2);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n/**\r\n * Node in a Tree.\r\n */\nvar TreeNode = function () {\n function TreeNode() {\n // TODO: Consider making accessors that create children and value lazily or\n // separate Internal / Leaf 'types'.\n this.children = {};\n this.childCount = 0;\n this.value = null;\n }\n return TreeNode;\n}();\n\n/**\r\n * A light-weight tree, traversable by path. Nodes can have both values and children.\r\n * Nodes are not enumerated (by forEachChild) unless they have a value or non-empty\r\n * children.\r\n */\nvar Tree_Tree = function () {\n /**\r\n * @template T\r\n * @param {string=} name_ Optional name of the node.\r\n * @param {Tree=} parent_ Optional parent node.\r\n * @param {TreeNode=} node_ Optional node to wrap.\r\n */\n function Tree(name_, parent_, node_) {\n if (name_ === void 0) {\n name_ = '';\n }\n if (parent_ === void 0) {\n parent_ = null;\n }\n if (node_ === void 0) {\n node_ = new TreeNode();\n }\n this.name_ = name_;\n this.parent_ = parent_;\n this.node_ = node_;\n }\n /**\r\n * Returns a sub-Tree for the given path.\r\n *\r\n * @param {!(string|Path)} pathObj Path to look up.\r\n * @return {!Tree.} Tree for path.\r\n */\n Tree.prototype.subTree = function (pathObj) {\n // TODO: Require pathObj to be Path?\n var path = pathObj instanceof Path ? pathObj : new Path(pathObj);\n var child = this,\n next;\n while ((next = path.getFront()) !== null) {\n var childNode = Tree___WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"l\" /* safeGet */](child.node_.children, next) || new TreeNode();\n child = new Tree(next, child, childNode);\n path = path.popFront();\n }\n return child;\n };\n /**\r\n * Returns the data associated with this tree node.\r\n *\r\n * @return {?T} The data or null if no data exists.\r\n */\n Tree.prototype.getValue = function () {\n return this.node_.value;\n };\n /**\r\n * Sets data to this tree node.\r\n *\r\n * @param {!T} value Value to set.\r\n */\n Tree.prototype.setValue = function (value) {\n Tree___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](typeof value !== 'undefined', 'Cannot set value to undefined');\n this.node_.value = value;\n this.updateParents_();\n };\n /**\r\n * Clears the contents of the tree node (its value and all children).\r\n */\n Tree.prototype.clear = function () {\n this.node_.value = null;\n this.node_.children = {};\n this.node_.childCount = 0;\n this.updateParents_();\n };\n /**\r\n * @return {boolean} Whether the tree has any children.\r\n */\n Tree.prototype.hasChildren = function () {\n return this.node_.childCount > 0;\n };\n /**\r\n * @return {boolean} Whether the tree is empty (no value or children).\r\n */\n Tree.prototype.isEmpty = function () {\n return this.getValue() === null && !this.hasChildren();\n };\n /**\r\n * Calls action for each child of this tree node.\r\n *\r\n * @param {function(!Tree.)} action Action to be called for each child.\r\n */\n Tree.prototype.forEachChild = function (action) {\n var _this = this;\n Tree___WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"f\" /* forEach */](this.node_.children, function (child, childTree) {\n action(new Tree(child, _this, childTree));\n });\n };\n /**\r\n * Does a depth-first traversal of this node's descendants, calling action for each one.\r\n *\r\n * @param {function(!Tree.)} action Action to be called for each child.\r\n * @param {boolean=} includeSelf Whether to call action on this node as well. Defaults to\r\n * false.\r\n * @param {boolean=} childrenFirst Whether to call action on children before calling it on\r\n * parent.\r\n */\n Tree.prototype.forEachDescendant = function (action, includeSelf, childrenFirst) {\n if (includeSelf && !childrenFirst) action(this);\n this.forEachChild(function (child) {\n child.forEachDescendant(action, /*includeSelf=*/true, childrenFirst);\n });\n if (includeSelf && childrenFirst) action(this);\n };\n /**\r\n * Calls action on each ancestor node.\r\n *\r\n * @param {function(!Tree.)} action Action to be called on each parent; return\r\n * true to abort.\r\n * @param {boolean=} includeSelf Whether to call action on this node as well.\r\n * @return {boolean} true if the action callback returned true.\r\n */\n Tree.prototype.forEachAncestor = function (action, includeSelf) {\n var node = includeSelf ? this : this.parent();\n while (node !== null) {\n if (action(node)) {\n return true;\n }\n node = node.parent();\n }\n return false;\n };\n /**\r\n * Does a depth-first traversal of this node's descendants. When a descendant with a value\r\n * is found, action is called on it and traversal does not continue inside the node.\r\n * Action is *not* called on this node.\r\n *\r\n * @param {function(!Tree.)} action Action to be called for each child.\r\n */\n Tree.prototype.forEachImmediateDescendantWithValue = function (action) {\n this.forEachChild(function (child) {\n if (child.getValue() !== null) action(child);else child.forEachImmediateDescendantWithValue(action);\n });\n };\n /**\r\n * @return {!Path} The path of this tree node, as a Path.\r\n */\n Tree.prototype.path = function () {\n return new Path(this.parent_ === null ? this.name_ : this.parent_.path() + '/' + this.name_);\n };\n /**\r\n * @return {string} The name of the tree node.\r\n */\n Tree.prototype.name = function () {\n return this.name_;\n };\n /**\r\n * @return {?Tree} The parent tree node, or null if this is the root of the tree.\r\n */\n Tree.prototype.parent = function () {\n return this.parent_;\n };\n /**\r\n * Adds or removes this child from its parent based on whether it's empty or not.\r\n *\r\n * @private\r\n */\n Tree.prototype.updateParents_ = function () {\n if (this.parent_ !== null) this.parent_.updateChild_(this.name_, this);\n };\n /**\r\n * Adds or removes the passed child to this tree node, depending on whether it's empty.\r\n *\r\n * @param {string} childName The name of the child to update.\r\n * @param {!Tree.} child The child to update.\r\n * @private\r\n */\n Tree.prototype.updateChild_ = function (childName, child) {\n var childEmpty = child.isEmpty();\n var childExists = Tree___WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"b\" /* contains */](this.node_.children, childName);\n if (childEmpty && childExists) {\n delete this.node_.children[childName];\n this.node_.childCount--;\n this.updateParents_();\n } else if (!childEmpty && !childExists) {\n this.node_.children[childName] = child.node_;\n this.node_.childCount++;\n this.updateParents_();\n }\n };\n return Tree;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/Repo_transaction.ts\n/* harmony import */ var Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__utils_obj__ = __webpack_require__(2);\nvar Repo_transaction__typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n\n// TODO: This is pretty messy. Ideally, a lot of this would move into FirebaseData, or a transaction-specific\n// component used by FirebaseData, but it has ties to user callbacks (transaction update and onComplete) as well\n// as the realtime connection (to send transactions to the server). So that all needs to be decoupled first.\n// For now it's part of Repo, but in its own file.\n/**\r\n * @enum {number}\r\n */\nvar TransactionStatus;\n(function (TransactionStatus) {\n // We've run the transaction and updated transactionResultData_ with the result, but it isn't currently sent to the\n // server. A transaction will go from RUN -> SENT -> RUN if it comes back from the server as rejected due to\n // mismatched hash.\n TransactionStatus[TransactionStatus[\"RUN\"] = 0] = \"RUN\";\n // We've run the transaction and sent it to the server and it's currently outstanding (hasn't come back as accepted\n // or rejected yet).\n TransactionStatus[TransactionStatus[\"SENT\"] = 1] = \"SENT\";\n // Temporary state used to mark completed transactions (whether successful or aborted). The transaction will be\n // removed when we get a chance to prune completed ones.\n TransactionStatus[TransactionStatus[\"COMPLETED\"] = 2] = \"COMPLETED\";\n // Used when an already-sent transaction needs to be aborted (e.g. due to a conflicting set() call that was made).\n // If it comes back as unsuccessful, we'll abort it.\n TransactionStatus[TransactionStatus[\"SENT_NEEDS_ABORT\"] = 3] = \"SENT_NEEDS_ABORT\";\n // Temporary state used to mark transactions that need to be aborted.\n TransactionStatus[TransactionStatus[\"NEEDS_ABORT\"] = 4] = \"NEEDS_ABORT\";\n})(TransactionStatus || (TransactionStatus = {}));\n/**\r\n * If a transaction does not succeed after 25 retries, we abort it. Among other things this ensure that if there's\r\n * ever a bug causing a mismatch between client / server hashes for some data, we won't retry indefinitely.\r\n * @type {number}\r\n * @const\r\n * @private\r\n */\nRepo_Repo.MAX_TRANSACTION_RETRIES_ = 25;\n/**\r\n * Setup the transaction data structures\r\n * @private\r\n */\nRepo_Repo.prototype.transactions_init_ = function () {\n /**\r\n * Stores queues of outstanding transactions for Firebase locations.\r\n *\r\n * @type {!Tree.>}\r\n * @private\r\n */\n this.transactionQueueTree_ = new Tree_Tree();\n};\n/**\r\n * Creates a new transaction, adds it to the transactions we're tracking, and sends it to the server if possible.\r\n *\r\n * @param {!Path} path Path at which to do transaction.\r\n * @param {function(*):*} transactionUpdate Update callback.\r\n * @param {?function(?Error, boolean, ?DataSnapshot)} onComplete Completion callback.\r\n * @param {boolean} applyLocally Whether or not to make intermediate results visible\r\n */\nRepo_Repo.prototype.startTransaction = function (path, transactionUpdate, onComplete, applyLocally) {\n this.log_('transaction on ' + path);\n // Add a watch to make sure we get server updates.\n var valueCallback = function valueCallback() {};\n var watchRef = new Reference_Reference(this, path);\n watchRef.on('value', valueCallback);\n var unwatcher = function unwatcher() {\n watchRef.off('value', valueCallback);\n };\n // Initialize transaction.\n var transaction = {\n path: path,\n update: transactionUpdate,\n onComplete: onComplete,\n // One of TransactionStatus enums.\n status: null,\n // Used when combining transactions at different locations to figure out which one goes first.\n order: __WEBPACK_IMPORTED_MODULE_6__util_util__[\"a\" /* LUIDGenerator */](),\n // Whether to raise local events for this transaction.\n applyLocally: applyLocally,\n // Count of how many times we've retried the transaction.\n retryCount: 0,\n // Function to call to clean up our .on() listener.\n unwatcher: unwatcher,\n // Stores why a transaction was aborted.\n abortReason: null,\n currentWriteId: null,\n currentInputSnapshot: null,\n currentOutputSnapshotRaw: null,\n currentOutputSnapshotResolved: null\n };\n // Run transaction initially.\n var currentState = this.getLatestState_(path);\n transaction.currentInputSnapshot = currentState;\n var newVal = transaction.update(currentState.val());\n if (newVal === undefined) {\n // Abort transaction.\n transaction.unwatcher();\n transaction.currentOutputSnapshotRaw = null;\n transaction.currentOutputSnapshotResolved = null;\n if (transaction.onComplete) {\n // We just set the input snapshot, so this cast should be safe\n var snapshot = new DataSnapshot_DataSnapshot(transaction.currentInputSnapshot, new Reference_Reference(this, transaction.path), PRIORITY_INDEX);\n transaction.onComplete(null, false, snapshot);\n }\n } else {\n validation_validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path);\n // Mark as run and add to our queue.\n transaction.status = TransactionStatus.RUN;\n var queueNode = this.transactionQueueTree_.subTree(path);\n var nodeQueue = queueNode.getValue() || [];\n nodeQueue.push(transaction);\n queueNode.setValue(nodeQueue);\n // Update visibleData and raise events\n // Note: We intentionally raise events after updating all of our transaction state, since the user could\n // start new transactions from the event callbacks.\n var priorityForNode = void 0;\n if ((typeof newVal === 'undefined' ? 'undefined' : Repo_transaction__typeof(newVal)) === 'object' && newVal !== null && __WEBPACK_IMPORTED_MODULE_9__utils_obj__[\"b\" /* contains */](newVal, '.priority')) {\n priorityForNode = __WEBPACK_IMPORTED_MODULE_9__utils_obj__[\"l\" /* safeGet */](newVal, '.priority');\n Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](isValidPriority(priorityForNode), 'Invalid priority returned by transaction. ' + 'Priority must be a valid string, finite number, server value, or null.');\n } else {\n var currentNode = this.serverSyncTree_.calcCompleteEventCache(path) || ChildrenNode_ChildrenNode.EMPTY_NODE;\n priorityForNode = currentNode.getPriority().val();\n }\n priorityForNode = priorityForNode;\n var serverValues = this.generateServerValues();\n var newNodeUnresolved = nodeFromJSON_nodeFromJSON(newVal, priorityForNode);\n var newNode = ServerValues_resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\n transaction.currentOutputSnapshotRaw = newNodeUnresolved;\n transaction.currentOutputSnapshotResolved = newNode;\n transaction.currentWriteId = this.getNextWriteId_();\n var events = this.serverSyncTree_.applyUserOverwrite(path, newNode, transaction.currentWriteId, transaction.applyLocally);\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n this.sendReadyTransactions_();\n }\n};\n/**\r\n * @param {!Path} path\r\n * @param {Array.=} excludeSets A specific set to exclude\r\n * @return {Node}\r\n * @private\r\n */\nRepo_Repo.prototype.getLatestState_ = function (path, excludeSets) {\n return this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) || ChildrenNode_ChildrenNode.EMPTY_NODE;\n};\n/**\r\n * Sends any already-run transactions that aren't waiting for outstanding transactions to\r\n * complete.\r\n *\r\n * Externally it's called with no arguments, but it calls itself recursively with a particular\r\n * transactionQueueTree node to recurse through the tree.\r\n *\r\n * @param {Tree.>=} node transactionQueueTree node to start at.\r\n * @private\r\n */\nRepo_Repo.prototype.sendReadyTransactions_ = function (node) {\n var _this = this;\n if (node === void 0) {\n node = this.transactionQueueTree_;\n }\n // Before recursing, make sure any completed transactions are removed.\n if (!node) {\n this.pruneCompletedTransactionsBelowNode_(node);\n }\n if (node.getValue() !== null) {\n var queue = this.buildTransactionQueue_(node);\n Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](queue.length > 0, 'Sending zero length transaction queue');\n var allRun = queue.every(function (transaction) {\n return transaction.status === TransactionStatus.RUN;\n });\n // If they're all run (and not sent), we can send them. Else, we must wait.\n if (allRun) {\n this.sendTransactionQueue_(node.path(), queue);\n }\n } else if (node.hasChildren()) {\n node.forEachChild(function (childNode) {\n _this.sendReadyTransactions_(childNode);\n });\n }\n};\n/**\r\n * Given a list of run transactions, send them to the server and then handle the result (success or failure).\r\n *\r\n * @param {!Path} path The location of the queue.\r\n * @param {!Array.} queue Queue of transactions under the specified location.\r\n * @private\r\n */\nRepo_Repo.prototype.sendTransactionQueue_ = function (path, queue) {\n var _this = this;\n // Mark transactions as sent and increment retry count!\n var setsToIgnore = queue.map(function (txn) {\n return txn.currentWriteId;\n });\n var latestState = this.getLatestState_(path, setsToIgnore);\n var snapToSend = latestState;\n var latestHash = latestState.hash();\n for (var i = 0; i < queue.length; i++) {\n var txn = queue[i];\n Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](txn.status === TransactionStatus.RUN, 'tryToSendTransactionQueue_: items in queue should all be run.');\n txn.status = TransactionStatus.SENT;\n txn.retryCount++;\n var relativePath = Path.relativePath(path, txn.path);\n // If we've gotten to this point, the output snapshot must be defined.\n snapToSend = snapToSend.updateChild(relativePath, /**@type {!Node} */txn.currentOutputSnapshotRaw);\n }\n var dataToSend = snapToSend.val(true);\n var pathToSend = path;\n // Send the put.\n this.server_.put(pathToSend.toString(), dataToSend, function (status) {\n _this.log_('transaction put response', { path: pathToSend.toString(), status: status });\n var events = [];\n if (status === 'ok') {\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n // the callback could trigger more transactions or sets.\n var callbacks = [];\n for (var i = 0; i < queue.length; i++) {\n queue[i].status = TransactionStatus.COMPLETED;\n events = events.concat(_this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId));\n if (queue[i].onComplete) {\n // We never unset the output snapshot, and given that this transaction is complete, it should be set\n var node = queue[i].currentOutputSnapshotResolved;\n var ref = new Reference_Reference(_this, queue[i].path);\n var snapshot = new DataSnapshot_DataSnapshot(node, ref, PRIORITY_INDEX);\n callbacks.push(queue[i].onComplete.bind(null, null, true, snapshot));\n }\n queue[i].unwatcher();\n }\n // Now remove the completed transactions.\n _this.pruneCompletedTransactionsBelowNode_(_this.transactionQueueTree_.subTree(path));\n // There may be pending transactions that we can now send.\n _this.sendReadyTransactions_();\n _this.eventQueue_.raiseEventsForChangedPath(path, events);\n // Finally, trigger onComplete callbacks.\n for (var i = 0; i < callbacks.length; i++) {\n __WEBPACK_IMPORTED_MODULE_6__util_util__[\"m\" /* exceptionGuard */](callbacks[i]);\n }\n } else {\n // transactions are no longer sent. Update their status appropriately.\n if (status === 'datastale') {\n for (var i = 0; i < queue.length; i++) {\n if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT) queue[i].status = TransactionStatus.NEEDS_ABORT;else queue[i].status = TransactionStatus.RUN;\n }\n } else {\n __WEBPACK_IMPORTED_MODULE_6__util_util__[\"B\" /* warn */]('transaction at ' + pathToSend.toString() + ' failed: ' + status);\n for (var i = 0; i < queue.length; i++) {\n queue[i].status = TransactionStatus.NEEDS_ABORT;\n queue[i].abortReason = status;\n }\n }\n _this.rerunTransactions_(path);\n }\n }, latestHash);\n};\n/**\r\n * Finds all transactions dependent on the data at changedPath and reruns them.\r\n *\r\n * Should be called any time cached data changes.\r\n *\r\n * Return the highest path that was affected by rerunning transactions. This is the path at which events need to\r\n * be raised for.\r\n *\r\n * @param {!Path} changedPath The path in mergedData that changed.\r\n * @return {!Path} The rootmost path that was affected by rerunning transactions.\r\n * @private\r\n */\nRepo_Repo.prototype.rerunTransactions_ = function (changedPath) {\n var rootMostTransactionNode = this.getAncestorTransactionNode_(changedPath);\n var path = rootMostTransactionNode.path();\n var queue = this.buildTransactionQueue_(rootMostTransactionNode);\n this.rerunTransactionQueue_(queue, path);\n return path;\n};\n/**\r\n * Does all the work of rerunning transactions (as well as cleans up aborted transactions and whatnot).\r\n *\r\n * @param {Array.} queue The queue of transactions to run.\r\n * @param {!Path} path The path the queue is for.\r\n * @private\r\n */\nRepo_Repo.prototype.rerunTransactionQueue_ = function (queue, path) {\n if (queue.length === 0) {\n return; // Nothing to do!\n }\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n // the callback could trigger more transactions or sets.\n var callbacks = [];\n var events = [];\n // Ignore all of the sets we're going to re-run.\n var txnsToRerun = queue.filter(function (q) {\n return q.status === TransactionStatus.RUN;\n });\n var setsToIgnore = txnsToRerun.map(function (q) {\n return q.currentWriteId;\n });\n for (var i = 0; i < queue.length; i++) {\n var transaction = queue[i];\n var relativePath = Path.relativePath(path, transaction.path);\n var abortTransaction = false,\n abortReason = void 0;\n Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](relativePath !== null, 'rerunTransactionsUnderNode_: relativePath should not be null.');\n if (transaction.status === TransactionStatus.NEEDS_ABORT) {\n abortTransaction = true;\n abortReason = transaction.abortReason;\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\n } else if (transaction.status === TransactionStatus.RUN) {\n if (transaction.retryCount >= Repo_Repo.MAX_TRANSACTION_RETRIES_) {\n abortTransaction = true;\n abortReason = 'maxretry';\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\n } else {\n // This code reruns a transaction\n var currentNode = this.getLatestState_(transaction.path, setsToIgnore);\n transaction.currentInputSnapshot = currentNode;\n var newData = queue[i].update(currentNode.val());\n if (newData !== undefined) {\n validation_validateFirebaseData('transaction failed: Data returned ', newData, transaction.path);\n var newDataNode = nodeFromJSON_nodeFromJSON(newData);\n var hasExplicitPriority = (typeof newData === 'undefined' ? 'undefined' : Repo_transaction__typeof(newData)) === 'object' && newData != null && __WEBPACK_IMPORTED_MODULE_9__utils_obj__[\"b\" /* contains */](newData, '.priority');\n if (!hasExplicitPriority) {\n // Keep the old priority if there wasn't a priority explicitly specified.\n newDataNode = newDataNode.updatePriority(currentNode.getPriority());\n }\n var oldWriteId = transaction.currentWriteId;\n var serverValues = this.generateServerValues();\n var newNodeResolved = ServerValues_resolveDeferredValueSnapshot(newDataNode, serverValues);\n transaction.currentOutputSnapshotRaw = newDataNode;\n transaction.currentOutputSnapshotResolved = newNodeResolved;\n transaction.currentWriteId = this.getNextWriteId_();\n // Mutates setsToIgnore in place\n setsToIgnore.splice(setsToIgnore.indexOf(oldWriteId), 1);\n events = events.concat(this.serverSyncTree_.applyUserOverwrite(transaction.path, newNodeResolved, transaction.currentWriteId, transaction.applyLocally));\n events = events.concat(this.serverSyncTree_.ackUserWrite(oldWriteId, true));\n } else {\n abortTransaction = true;\n abortReason = 'nodata';\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\n }\n }\n }\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n events = [];\n if (abortTransaction) {\n // Abort.\n queue[i].status = TransactionStatus.COMPLETED;\n // Removing a listener can trigger pruning which can muck with mergedData/visibleData (as it prunes data).\n // So defer the unwatcher until we're done.\n (function (unwatcher) {\n setTimeout(unwatcher, Math.floor(0));\n })(queue[i].unwatcher);\n if (queue[i].onComplete) {\n if (abortReason === 'nodata') {\n var ref = new Reference_Reference(this, queue[i].path);\n // We set this field immediately, so it's safe to cast to an actual snapshot\n var lastInput = queue[i].currentInputSnapshot;\n var snapshot = new DataSnapshot_DataSnapshot(lastInput, ref, PRIORITY_INDEX);\n callbacks.push(queue[i].onComplete.bind(null, null, false, snapshot));\n } else {\n callbacks.push(queue[i].onComplete.bind(null, new Error(abortReason), false, null));\n }\n }\n }\n }\n // Clean up completed transactions.\n this.pruneCompletedTransactionsBelowNode_(this.transactionQueueTree_);\n // Now fire callbacks, now that we're in a good, known state.\n for (var i = 0; i < callbacks.length; i++) {\n __WEBPACK_IMPORTED_MODULE_6__util_util__[\"m\" /* exceptionGuard */](callbacks[i]);\n }\n // Try to send the transaction result to the server.\n this.sendReadyTransactions_();\n};\n/**\r\n * Returns the rootmost ancestor node of the specified path that has a pending transaction on it, or just returns\r\n * the node for the given path if there are no pending transactions on any ancestor.\r\n *\r\n * @param {!Path} path The location to start at.\r\n * @return {!Tree.>} The rootmost node with a transaction.\r\n * @private\r\n */\nRepo_Repo.prototype.getAncestorTransactionNode_ = function (path) {\n var front;\n // Start at the root and walk deeper into the tree towards path until we find a node with pending transactions.\n var transactionNode = this.transactionQueueTree_;\n while ((front = path.getFront()) !== null && transactionNode.getValue() === null) {\n transactionNode = transactionNode.subTree(front);\n path = path.popFront();\n }\n return transactionNode;\n};\n/**\r\n * Builds the queue of all transactions at or below the specified transactionNode.\r\n *\r\n * @param {!Tree.>} transactionNode\r\n * @return {Array.} The generated queue.\r\n * @private\r\n */\nRepo_Repo.prototype.buildTransactionQueue_ = function (transactionNode) {\n // Walk any child transaction queues and aggregate them into a single queue.\n var transactionQueue = [];\n this.aggregateTransactionQueuesForNode_(transactionNode, transactionQueue);\n // Sort them by the order the transactions were created.\n transactionQueue.sort(function (a, b) {\n return a.order - b.order;\n });\n return transactionQueue;\n};\n/**\r\n * @param {!Tree.>} node\r\n * @param {Array.} queue\r\n * @private\r\n */\nRepo_Repo.prototype.aggregateTransactionQueuesForNode_ = function (node, queue) {\n var _this = this;\n var nodeQueue = node.getValue();\n if (nodeQueue !== null) {\n for (var i = 0; i < nodeQueue.length; i++) {\n queue.push(nodeQueue[i]);\n }\n }\n node.forEachChild(function (child) {\n _this.aggregateTransactionQueuesForNode_(child, queue);\n });\n};\n/**\r\n * Remove COMPLETED transactions at or below this node in the transactionQueueTree_.\r\n *\r\n * @param {!Tree.>} node\r\n * @private\r\n */\nRepo_Repo.prototype.pruneCompletedTransactionsBelowNode_ = function (node) {\n var _this = this;\n var queue = node.getValue();\n if (queue) {\n var to = 0;\n for (var from = 0; from < queue.length; from++) {\n if (queue[from].status !== TransactionStatus.COMPLETED) {\n queue[to] = queue[from];\n to++;\n }\n }\n queue.length = to;\n node.setValue(queue.length > 0 ? queue : null);\n }\n node.forEachChild(function (childNode) {\n _this.pruneCompletedTransactionsBelowNode_(childNode);\n });\n};\n/**\r\n * Aborts all transactions on ancestors or descendants of the specified path. Called when doing a set() or update()\r\n * since we consider them incompatible with transactions.\r\n *\r\n * @param {!Path} path Path for which we want to abort related transactions.\r\n * @return {!Path}\r\n * @private\r\n */\nRepo_Repo.prototype.abortTransactions_ = function (path) {\n var _this = this;\n var affectedPath = this.getAncestorTransactionNode_(path).path();\n var transactionNode = this.transactionQueueTree_.subTree(path);\n transactionNode.forEachAncestor(function (node) {\n _this.abortTransactionsOnNode_(node);\n });\n this.abortTransactionsOnNode_(transactionNode);\n transactionNode.forEachDescendant(function (node) {\n _this.abortTransactionsOnNode_(node);\n });\n return affectedPath;\n};\n/**\r\n * Abort transactions stored in this transaction queue node.\r\n *\r\n * @param {!Tree.>} node Node to abort transactions for.\r\n * @private\r\n */\nRepo_Repo.prototype.abortTransactionsOnNode_ = function (node) {\n var queue = node.getValue();\n if (queue !== null) {\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n // the callback could trigger more transactions or sets.\n var callbacks = [];\n // Go through queue. Any already-sent transactions must be marked for abort, while the unsent ones\n // can be immediately aborted and removed.\n var events = [];\n var lastSent = -1;\n for (var i = 0; i < queue.length; i++) {\n if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT) {\n // Already marked. No action needed.\n } else if (queue[i].status === TransactionStatus.SENT) {\n Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](lastSent === i - 1, 'All SENT items should be at beginning of queue.');\n lastSent = i;\n // Mark transaction for abort when it comes back.\n queue[i].status = TransactionStatus.SENT_NEEDS_ABORT;\n queue[i].abortReason = 'set';\n } else {\n Repo_transaction___WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */](queue[i].status === TransactionStatus.RUN, 'Unexpected transaction status in abort');\n // We can abort it immediately.\n queue[i].unwatcher();\n events = events.concat(this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId, true));\n if (queue[i].onComplete) {\n var snapshot = null;\n callbacks.push(queue[i].onComplete.bind(null, new Error('set'), false, snapshot));\n }\n }\n }\n if (lastSent === -1) {\n // We're not waiting for any sent transactions. We can clear the queue.\n node.setValue(null);\n } else {\n // Remove the transactions we aborted.\n queue.length = lastSent + 1;\n }\n // Now fire the callbacks.\n this.eventQueue_.raiseEventsForChangedPath(node.path(), events);\n for (var i = 0; i < callbacks.length; i++) {\n __WEBPACK_IMPORTED_MODULE_6__util_util__[\"m\" /* exceptionGuard */](callbacks[i]);\n }\n }\n};\n// CONCATENATED MODULE: ./src/database/core/RepoManager.ts\n/* harmony import */ var RepoManager___WEBPACK_IMPORTED_MODULE_0__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var RepoManager___WEBPACK_IMPORTED_MODULE_2__util_util__ = __webpack_require__(1);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n/** @const {string} */\nvar DATABASE_URL_OPTION = 'databaseURL';\nvar _staticInstance;\n/**\r\n * Creates and caches Repo instances.\r\n */\nvar RepoManager_RepoManager = function () {\n function RepoManager() {\n /**\r\n * @private {!Object.}\r\n */\n this.repos_ = {};\n /**\r\n * If true, new Repos will be created to use ReadonlyRestClient (for testing purposes).\r\n * @private {boolean}\r\n */\n this.useRestClient_ = false;\n }\n RepoManager.getInstance = function () {\n if (!_staticInstance) {\n _staticInstance = new RepoManager();\n }\n return _staticInstance;\n };\n // TODO(koss): Remove these functions unless used in tests?\n RepoManager.prototype.interrupt = function () {\n for (var repo in this.repos_) {\n this.repos_[repo].interrupt();\n }\n };\n RepoManager.prototype.resume = function () {\n for (var repo in this.repos_) {\n this.repos_[repo].resume();\n }\n };\n /**\r\n * This function should only ever be called to CREATE a new database instance.\r\n *\r\n * @param {!FirebaseApp} app\r\n * @return {!Database}\r\n */\n RepoManager.prototype.databaseFromApp = function (app) {\n var dbUrl = app.options[DATABASE_URL_OPTION];\n if (dbUrl === undefined) {\n RepoManager___WEBPACK_IMPORTED_MODULE_2__util_util__[\"o\" /* fatal */](\"Can't determine Firebase Database URL. Be sure to include \" + DATABASE_URL_OPTION + \" option when calling firebase.intializeApp().\");\n }\n var parsedUrl = parser_parseRepoInfo(dbUrl);\n var repoInfo = parsedUrl.repoInfo;\n validation_validateUrl('Invalid Firebase Database URL', 1, parsedUrl);\n if (!parsedUrl.path.isEmpty()) {\n RepoManager___WEBPACK_IMPORTED_MODULE_2__util_util__[\"o\" /* fatal */](\"Database URL must point to the root of a Firebase Database \" + \"(not including a child path).\");\n }\n var repo = this.createRepo(repoInfo, app);\n return repo.database;\n };\n /**\r\n * Remove the repo and make sure it is disconnected.\r\n *\r\n * @param {!Repo} repo\r\n */\n RepoManager.prototype.deleteRepo = function (repo) {\n // This should never happen...\n if (RepoManager___WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"l\" /* safeGet */](this.repos_, repo.app.name) !== repo) {\n RepoManager___WEBPACK_IMPORTED_MODULE_2__util_util__[\"o\" /* fatal */](\"Database \" + repo.app.name + \" has already been deleted.\");\n }\n repo.interrupt();\n delete this.repos_[repo.app.name];\n };\n /**\r\n * Ensures a repo doesn't already exist and then creates one using the\r\n * provided app.\r\n *\r\n * @param {!RepoInfo} repoInfo The metadata about the Repo\r\n * @param {!FirebaseApp} app\r\n * @return {!Repo} The Repo object for the specified server / repoName.\r\n */\n RepoManager.prototype.createRepo = function (repoInfo, app) {\n var repo = RepoManager___WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"l\" /* safeGet */](this.repos_, app.name);\n if (repo) {\n RepoManager___WEBPACK_IMPORTED_MODULE_2__util_util__[\"o\" /* fatal */]('FIREBASE INTERNAL ERROR: Database initialized multiple times.');\n }\n repo = new Repo_Repo(repoInfo, this.useRestClient_, app);\n this.repos_[app.name] = repo;\n return repo;\n };\n /**\r\n * Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.\r\n * @param {boolean} forceRestClient\r\n */\n RepoManager.prototype.forceRestClient = function (forceRestClient) {\n this.useRestClient_ = forceRestClient;\n };\n return RepoManager;\n}();\n\n// CONCATENATED MODULE: ./src/database/api/Database.ts\n/* harmony import */ var Database___WEBPACK_IMPORTED_MODULE_0__core_util_util__ = __webpack_require__(1);\n/* harmony import */ var Database___WEBPACK_IMPORTED_MODULE_3__utils_promise__ = __webpack_require__(4);\n/**\r\n * Copyright 2017 Google Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\n\n\n\n\n\n\n\n\n\n/**\r\n * Class representing a firebase database.\r\n * @implements {FirebaseService}\r\n */\nvar Database_Database = function () {\n /**\r\n * The constructor should not be called by users of our public API.\r\n * @param {!Repo} repo_\r\n */\n function Database(repo_) {\n this.repo_ = repo_;\n if (!(repo_ instanceof Repo_Repo)) {\n Database___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"o\" /* fatal */]('Don\\'t call new Database() directly - please use firebase.database().');\n }\n /** @type {Reference} */\n this.root_ = new Reference_Reference(repo_, Path.Empty);\n this.INTERNAL = new Database_DatabaseInternals(this);\n }\n Object.defineProperty(Database.prototype, \"app\", {\n get: function get() {\n return this.repo_.app;\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * Returns a reference to the root or the path specified in opt_pathString.\r\n * @param {string=} pathString\r\n * @return {!Reference} Firebase reference.\r\n */\n Database.prototype.ref = function (pathString) {\n this.checkDeleted_('ref');\n validateArgCount('database.ref', 0, 1, arguments.length);\n return pathString !== undefined ? this.root_.child(pathString) : this.root_;\n };\n /**\r\n * Returns a reference to the root or the path specified in url.\r\n * We throw a exception if the url is not in the same domain as the\r\n * current repo.\r\n * @param {string} url\r\n * @return {!Reference} Firebase reference.\r\n */\n Database.prototype.refFromURL = function (url) {\n /** @const {string} */\n var apiName = 'database.refFromURL';\n this.checkDeleted_(apiName);\n validateArgCount(apiName, 1, 1, arguments.length);\n var parsedURL = parser_parseRepoInfo(url);\n validation_validateUrl(apiName, 1, parsedURL);\n var repoInfo = parsedURL.repoInfo;\n if (repoInfo.host !== this.repo_.repoInfo_.host) {\n Database___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"o\" /* fatal */](apiName + ': Host name does not match the current database: ' + '(found ' + repoInfo.host + ' but expected ' + this.repo_.repoInfo_.host + ')');\n }\n return this.ref(parsedURL.path.toString());\n };\n /**\r\n * @param {string} apiName\r\n */\n Database.prototype.checkDeleted_ = function (apiName) {\n if (this.repo_ === null) {\n Database___WEBPACK_IMPORTED_MODULE_0__core_util_util__[\"o\" /* fatal */]('Cannot call ' + apiName + ' on a deleted database.');\n }\n };\n // Make individual repo go offline.\n Database.prototype.goOffline = function () {\n validateArgCount('database.goOffline', 0, 0, arguments.length);\n this.checkDeleted_('goOffline');\n this.repo_.interrupt();\n };\n Database.prototype.goOnline = function () {\n validateArgCount('database.goOnline', 0, 0, arguments.length);\n this.checkDeleted_('goOnline');\n this.repo_.resume();\n };\n return Database;\n}();\n\nDatabase_Database.ServerValue = {\n 'TIMESTAMP': {\n '.sv': 'timestamp'\n }\n};\nvar Database_DatabaseInternals = function () {\n /** @param {!Database} database */\n function DatabaseInternals(database) {\n this.database = database;\n }\n /** @return {Promise} */\n DatabaseInternals.prototype.delete = function () {\n this.database.checkDeleted_('delete');\n RepoManager_RepoManager.getInstance().deleteRepo(this.database.repo_);\n this.database.repo_ = null;\n this.database.root_ = null;\n this.database.INTERNAL = null;\n this.database = null;\n return Database___WEBPACK_IMPORTED_MODULE_3__utils_promise__[\"b\" /* PromiseImpl */].resolve();\n };\n return DatabaseInternals;\n}();\n\n// CONCATENATED MODULE: ./src/database/api/internal.ts\nvar internal_namespaceObject = {};\n__webpack_require__.d(internal_namespaceObject, \"forceLongPolling\", function() { return internal_forceLongPolling; });\n__webpack_require__.d(internal_namespaceObject, \"forceWebSockets\", function() { return internal_forceWebSockets; });\n__webpack_require__.d(internal_namespaceObject, \"isWebSocketsAvailable\", function() { return isWebSocketsAvailable; });\n__webpack_require__.d(internal_namespaceObject, \"setSecurityDebugCallback\", function() { return setSecurityDebugCallback; });\n__webpack_require__.d(internal_namespaceObject, \"stats\", function() { return internal_stats; });\n__webpack_require__.d(internal_namespaceObject, \"statsIncrementCounter\", function() { return statsIncrementCounter; });\n__webpack_require__.d(internal_namespaceObject, \"dataUpdateCount\", function() { return dataUpdateCount; });\n__webpack_require__.d(internal_namespaceObject, \"interceptServerData\", function() { return interceptServerData; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__ = __webpack_require__(18);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n/**\r\n * INTERNAL methods for internal-use only (tests, etc.).\r\n *\r\n * Customers shouldn't use these or else should be aware that they could break at any time.\r\n *\r\n * @const\r\n */\nvar internal_forceLongPolling = function forceLongPolling() {\n __WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__[\"a\" /* WebSocketConnection */].forceDisallow();\n BrowserPollConnection_BrowserPollConnection.forceAllow();\n};\nvar internal_forceWebSockets = function forceWebSockets() {\n BrowserPollConnection_BrowserPollConnection.forceDisallow();\n};\n/* Used by App Manager */\nvar isWebSocketsAvailable = function isWebSocketsAvailable() {\n return __WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__[\"a\" /* WebSocketConnection */]['isAvailable']();\n};\nvar setSecurityDebugCallback = function setSecurityDebugCallback(ref, callback) {\n ref.repo.persistentConnection_.securityDebugCallback_ = callback;\n};\nvar internal_stats = function stats(ref, showDelta) {\n ref.repo.stats(showDelta);\n};\nvar statsIncrementCounter = function statsIncrementCounter(ref, metric) {\n ref.repo.statsIncrementCounter(metric);\n};\nvar dataUpdateCount = function dataUpdateCount(ref) {\n return ref.repo.dataUpdateCount;\n};\nvar interceptServerData = function interceptServerData(ref, callback) {\n return ref.repo.interceptServerData_(callback);\n};\n// CONCATENATED MODULE: ./src/database/api/test_access.ts\nvar test_access_namespaceObject = {};\n__webpack_require__.d(test_access_namespaceObject, \"DataConnection\", function() { return DataConnection; });\n__webpack_require__.d(test_access_namespaceObject, \"RealTimeConnection\", function() { return RealTimeConnection; });\n__webpack_require__.d(test_access_namespaceObject, \"hijackHash\", function() { return test_access_hijackHash; });\n__webpack_require__.d(test_access_namespaceObject, \"ConnectionTarget\", function() { return ConnectionTarget; });\n__webpack_require__.d(test_access_namespaceObject, \"queryIdentifier\", function() { return queryIdentifier; });\n__webpack_require__.d(test_access_namespaceObject, \"listens\", function() { return listens; });\n__webpack_require__.d(test_access_namespaceObject, \"forceRestClient\", function() { return test_access_forceRestClient; });\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\nvar DataConnection = PersistentConnection_PersistentConnection;\n/**\r\n * @param {!string} pathString\r\n * @param {function(*)} onComplete\r\n */\nPersistentConnection_PersistentConnection.prototype.simpleListen = function (pathString, onComplete) {\n this.sendRequest('q', { 'p': pathString }, onComplete);\n};\n/**\r\n * @param {*} data\r\n * @param {function(*)} onEcho\r\n */\nPersistentConnection_PersistentConnection.prototype.echo = function (data, onEcho) {\n this.sendRequest('echo', { 'd': data }, onEcho);\n};\n// RealTimeConnection properties that we use in tests.\nvar RealTimeConnection = Connection_Connection;\n/**\r\n * @param {function(): string} newHash\r\n * @return {function()}\r\n */\nvar test_access_hijackHash = function hijackHash(newHash) {\n var oldPut = PersistentConnection_PersistentConnection.prototype.put;\n PersistentConnection_PersistentConnection.prototype.put = function (pathString, data, opt_onComplete, opt_hash) {\n if (opt_hash !== undefined) {\n opt_hash = newHash();\n }\n oldPut.call(this, pathString, data, opt_onComplete, opt_hash);\n };\n return function () {\n PersistentConnection_PersistentConnection.prototype.put = oldPut;\n };\n};\n/**\r\n * @type {function(new:RepoInfo, !string, boolean, !string, boolean): undefined}\r\n */\nvar ConnectionTarget = RepoInfo;\n/**\r\n * @param {!Query} query\r\n * @return {!string}\r\n */\nvar queryIdentifier = function queryIdentifier(query) {\n return query.queryIdentifier();\n};\n/**\r\n * @param {!Query} firebaseRef\r\n * @return {!Object}\r\n */\nvar listens = function listens(firebaseRef) {\n return firebaseRef.repo.persistentConnection_.listens_;\n};\n/**\r\n * Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.\r\n *\r\n * @param {boolean} forceRestClient\r\n */\nvar test_access_forceRestClient = function forceRestClient(_forceRestClient) {\n RepoManager_RepoManager.getInstance().forceRestClient(_forceRestClient);\n};\n// CONCATENATED MODULE: ./src/database.ts\n/* WEBPACK VAR INJECTION */(function(module) {/* harmony export (immutable) */ __webpack_exports__[\"registerDatabase\"] = registerDatabase;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__app__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__database_core_util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_environment__ = __webpack_require__(6);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n\n\n\nfunction registerDatabase(instance) {\n // Register the Database Service with the 'firebase' namespace.\n var namespace = instance.INTERNAL.registerService('database', function (app) {\n return RepoManager_RepoManager.getInstance().databaseFromApp(app);\n },\n // firebase.database namespace properties\n {\n Reference: Reference_Reference,\n Query: Query_Query,\n Database: Database_Database,\n enableLogging: __WEBPACK_IMPORTED_MODULE_4__database_core_util_util__[\"j\" /* enableLogging */],\n INTERNAL: internal_namespaceObject,\n ServerValue: Database_Database.ServerValue,\n TEST_ACCESS: test_access_namespaceObject\n });\n if (__WEBPACK_IMPORTED_MODULE_8__utils_environment__[\"b\" /* isNodeSdk */]()) {\n module.exports = namespace;\n }\n}\nregisterDatabase(__WEBPACK_IMPORTED_MODULE_0__app__[\"default\"]);\n/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(25)(module)))\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports) {\n\nmodule.exports = function(originalModule) {\r\n\tif(!originalModule.webpackPolyfill) {\r\n\t\tvar module = Object.create(originalModule);\r\n\t\t// module.parent = undefined by default\r\n\t\tif(!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.l;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.i;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"exports\", {\r\n\t\t\tenumerable: true,\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n};\r\n\n\n/***/ })\n],[24]);\n } catch(error) {\n throw new Error(\n 'Cannot instantiate firebase-database.js - ' +\n 'be sure to load firebase-app.js first.'\n )\n }\n\n\n// WEBPACK FOOTER //\n// firebase-database.js","/**\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\nimport { CONSTANTS } from \"./constants\";\n\n/**\n * Throws an error if the provided assertion is falsy\n * @param {*} assertion The assertion to be tested for falsiness\n * @param {!string} message The message to display if the check fails\n */\nexport const assert = function(assertion, message) {\n if (!assertion) {\n throw assertionError(message);\n }\n};\n\n/**\n * Returns an Error object suitable for throwing.\n * @param {string} message\n * @return {!Error}\n */\nexport const assertionError = function(message) {\n return new Error('Firebase Database (' + CONSTANTS.SDK_VERSION + ') INTERNAL ASSERT FAILED: ' + message);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/assert.ts","/**\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\nimport { globalScope } from './globalScope';\n\nconst stringToByteArray = function(str) {\n var output = [], p = 0;\n for (var i = 0;i < str.length;i++) {\n var c = str.charCodeAt(i);\n while (c > 255) {\n output[p++] = c & 255;\n c >>= 8;\n }\n output[p++] = c;\n }\n return output;\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 {Array} bytes Array of numbers representing characters.\n * @return {string} Stringification of the array.\n */\nconst 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 = bytes.slice(i, i + CHUNK_SIZE);\n str += String.fromCharCode.apply(null, chunk);\n }\n return str;\n};\n\n// Static lookup maps, lazily populated by init_()\nexport const base64 = {\n /**\n * Maps bytes to characters.\n * @type {Object}\n * @private\n */\n byteToCharMap_: null,\n \n /**\n * Maps characters to bytes.\n * @type {Object}\n * @private\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @type {Object}\n * @private\n */\n byteToCharMapWebSafe_: null,\n \n \n /**\n * Maps websafe characters to bytes.\n * @type {Object}\n * @private\n */\n charToByteMapWebSafe_: null,\n \n \n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n * @type {string}\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n 'abcdefghijklmnopqrstuvwxyz' +\n '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n * @type {string}\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n \n /**\n * Our websafe alphabet.\n * @type {string}\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.'\n },\n \n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n * @type {boolean}\n */\n HAS_NATIVE_SUPPORT: typeof globalScope.atob === 'function',\n \n /**\n * Base64-encode an array of bytes.\n *\n * @param {Array|Uint8Array} input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param {boolean=} opt_webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return {string} The base64 encoded string.\n */\n encodeByteArray(input, opt_webSafe?) {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n \n this.init_();\n \n var byteToCharMap = opt_webSafe ?\n this.byteToCharMapWebSafe_ :\n this.byteToCharMap_;\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(byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n 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 {boolean=} opt_webSafe If true, we should use the\n * alternative alphabet.\n * @return {string} The base64 encoded string.\n */\n encodeString(input, opt_webSafe) {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !opt_webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(\n stringToByteArray(input), opt_webSafe);\n },\n \n \n /**\n * Base64-decode a string.\n *\n * @param {string} input to decode.\n * @param {boolean=} opt_webSafe True if we should use the\n * alternative alphabet.\n * @return {string} string representing the decoded value.\n */\n decodeString(input, opt_webSafe) {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !opt_webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, opt_webSafe));\n },\n \n \n /**\n * Base64-decode a string.\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.\n * @param {boolean=} opt_webSafe True if we should use the web-safe alphabet.\n * @return {!Array} bytes representing the decoded value.\n */\n decodeStringToByteArray(input, opt_webSafe) {\n this.init_();\n \n var charToByteMap = opt_webSafe ?\n this.charToByteMapWebSafe_ :\n this.charToByteMap_;\n \n var output = [];\n \n for (var i = 0; i < input.length; ) {\n var byte1 = charToByteMap[input.charAt(i++)];\n \n var haveByte2 = i < input.length;\n var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n \n var haveByte3 = i < input.length;\n var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n \n var haveByte4 = i < input.length;\n var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n \n if (byte1 == null || byte2 == null ||\n byte3 == null || byte4 == null) {\n throw Error();\n }\n \n var outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n \n if (byte3 != 64) {\n var outByte2 = ((byte2 << 4) & 0xF0) | (byte3 >> 2);\n output.push(outByte2);\n \n if (byte4 != 64) {\n var outByte3 = ((byte3 << 6) & 0xC0) | byte4;\n output.push(outByte3);\n }\n }\n }\n \n return output;\n },\n \n \n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n \n // We want quick mappings back and forth, so we precompute two maps.\n for (var i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] =\n this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] =\n this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[\n this.byteToCharMapWebSafe_[i]] = i;\n \n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[\n this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[\n this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n \n \n \n \n\n\n// WEBPACK FOOTER //\n// ./src/utils/crypt.ts","/**\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// 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 Abstract cryptographic hash interface.\n *\n * See Sha1 and Md5 for sample implementations.\n *\n */\n \n/**\n * Create a cryptographic hash instance.\n *\n * @constructor\n * @struct\n */\nexport class Hash {\n /**\n * The block size for the hasher.\n * @type {number}\n */\n blockSize: number = -1;\n \n constructor() {}\n}\n\n\n// WEBPACK FOOTER //\n// ./src/utils/hash.ts","/**\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\nimport { Hash } from './hash';\n\n/**\n * @fileoverview SHA-1 cryptographic hash.\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 * Usage:\n * var sha1 = new sha1();\n * sha1.update(bytes);\n * var hash = sha1.digest();\n *\n * Performance:\n * Chrome 23: ~400 Mbit/s\n * Firefox 16: ~250 Mbit/s\n *\n */\n \n/**\n * SHA-1 cryptographic hash constructor.\n *\n * The properties declared here are discussed in the above algorithm document.\n * @constructor\n * @extends {Hash}\n * @final\n * @struct\n */\nexport class Sha1 extends Hash {\n /**\n * Holds the previous values of accumulated variables a-e in the compress_\n * function.\n * @type {!Array}\n * @private\n */\n private chain_: Array = [];\n \n /**\n * A buffer holding the partially computed hash result.\n * @type {!Array}\n * @private\n */\n private buf_: Array = [];\n\n /**\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\n * as the message schedule in the docs.\n * @type {!Array}\n * @private\n */\n private W_: Array = [];\n\n /**\n * Contains data needed to pad messages less than 64 bytes.\n * @type {!Array}\n * @private\n */\n private pad_: Array = [];\n\n /**\n * @private {number}\n */\n private inbuf_: number = 0;\n\n /**\n * @private {number}\n */\n private total_: number = 0;\n\n constructor() {\n super();\n \n this.blockSize = 512 / 8;\n \n this.pad_[0] = 128;\n for (var i = 1; i < this.blockSize; ++i) {\n this.pad_[i] = 0;\n }\n \n this.reset();\n }\n \n reset() {\n this.chain_[0] = 0x67452301;\n this.chain_[1] = 0xefcdab89;\n this.chain_[2] = 0x98badcfe;\n this.chain_[3] = 0x10325476;\n this.chain_[4] = 0xc3d2e1f0;\n \n this.inbuf_ = 0;\n this.total_ = 0;\n }\n \n \n /**\n * Internal compress helper function.\n * @param {!Array|!Uint8Array|string} buf Block to compress.\n * @param {number=} opt_offset Offset of the block in the buffer.\n * @private\n */\n compress_(buf, opt_offset?) {\n if (!opt_offset) {\n opt_offset = 0;\n }\n \n var W = this.W_;\n \n // get 16 big endian words\n if (typeof buf === 'string') {\n for (var i = 0; i < 16; i++) {\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\n // have a bug that turns the post-increment ++ operator into pre-increment\n // during JIT compilation. We have code that depends heavily on SHA-1 for\n // correctness and which is affected by this bug, so I've removed all uses\n // of post-increment ++ in which the result value is used. We can revert\n // this change once the Safari bug\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\n // most clients have been updated.\n W[i] = (buf.charCodeAt(opt_offset) << 24) |\n (buf.charCodeAt(opt_offset + 1) << 16) |\n (buf.charCodeAt(opt_offset + 2) << 8) |\n (buf.charCodeAt(opt_offset + 3));\n opt_offset += 4;\n }\n } else {\n for (var i = 0; i < 16; i++) {\n W[i] = (buf[opt_offset] << 24) |\n (buf[opt_offset + 1] << 16) |\n (buf[opt_offset + 2] << 8) |\n (buf[opt_offset + 3]);\n opt_offset += 4;\n }\n }\n \n // expand to 80 words\n for (var i = 16; i < 80; i++) {\n var t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\n }\n \n var a = this.chain_[0];\n var b = this.chain_[1];\n var c = this.chain_[2];\n var d = this.chain_[3];\n var e = this.chain_[4];\n var f, k;\n \n // TODO(user): Try to unroll this loop to speed up the computation.\n for (var i = 0; i < 80; i++) {\n if (i < 40) {\n if (i < 20) {\n f = d ^ (b & (c ^ d));\n k = 0x5a827999;\n } else {\n f = b ^ c ^ d;\n k = 0x6ed9eba1;\n }\n } else {\n if (i < 60) {\n f = (b & c) | (d & (b | c));\n k = 0x8f1bbcdc;\n } else {\n f = b ^ c ^ d;\n k = 0xca62c1d6;\n }\n }\n \n var t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\n e = d;\n d = c;\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\n b = a;\n a = t;\n }\n \n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\n }\n \n update(bytes, opt_length?) {\n // TODO(johnlenz): tighten the function signature and remove this check\n if (bytes == null) {\n return;\n }\n \n if (opt_length === undefined) {\n opt_length = bytes.length;\n }\n \n var lengthMinusBlock = opt_length - this.blockSize;\n var n = 0;\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\n var buf = this.buf_;\n var inbuf = this.inbuf_;\n \n // The outer while loop should execute at most twice.\n while (n < opt_length) {\n // When we have no data in the block to top up, we can directly process the\n // input buffer (assuming it contains sufficient data). This gives ~25%\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\n // the data is provided in large chunks (or in multiples of 64 bytes).\n if (inbuf == 0) {\n while (n <= lengthMinusBlock) {\n this.compress_(bytes, n);\n n += this.blockSize;\n }\n }\n \n if (typeof bytes === 'string') {\n while (n < opt_length) {\n buf[inbuf] = bytes.charCodeAt(n);\n ++inbuf;\n ++n;\n if (inbuf == this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n } else {\n while (n < opt_length) {\n buf[inbuf] = bytes[n];\n ++inbuf;\n ++n;\n if (inbuf == this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n }\n }\n \n this.inbuf_ = inbuf;\n this.total_ += opt_length;\n }\n \n \n /** @override */\n digest() {\n var digest = [];\n var totalBits = this.total_ * 8;\n \n // Add pad 0x80 0x00*.\n if (this.inbuf_ < 56) {\n this.update(this.pad_, 56 - this.inbuf_);\n } else {\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\n }\n \n // Add # bits.\n for (var i = this.blockSize - 1; i >= 56; i--) {\n this.buf_[i] = totalBits & 255;\n totalBits /= 256; // Don't use bit-shifting here!\n }\n \n this.compress_(this.buf_);\n \n var n = 0;\n for (var i = 0; i < 5; i++) {\n for (var j = 24; j >= 0; j -= 8) {\n digest[n] = (this.chain_[i] >> j) & 255;\n ++n;\n }\n }\n return digest;\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/utils/Sha1.ts","/**\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\nimport { Query } from '../../api/Query';\n\ndeclare const window: any;\ndeclare const Windows: any;\n\nimport { assert } from '../../../utils/assert';\nimport { forEach } from '../../../utils/obj';\nimport { base64 } from '../../../utils/crypt';\nimport { Sha1 } from '../../../utils/Sha1';\nimport { stringToByteArray } from '../../../utils/utf8';\nimport { stringify } from '../../../utils/json';\nimport { SessionStorage } from '../storage/storage';\nimport { isNodeSdk } from '../../../utils/environment';\n\n/**\n * Returns a locally-unique ID (generated by just incrementing up from 0 each time its called).\n * @type {function(): number} Generated ID.\n */\nexport const LUIDGenerator: (() => number) = (function () {\n let id = 1;\n return function () {\n return id++;\n };\n})();\n\n\n/**\n * URL-safe base64 encoding\n * @param {!string} str\n * @return {!string}\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, /*useWebSafe=*/true);\n};\n\n\nlet BufferImpl;\nexport function setBufferImpl(impl) {\n BufferImpl = impl;\n}\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param {string} str To be decoded\n * @return {?string} Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n if (BufferImpl()) {\n return new BufferImpl(str, 'base64').toString('utf8');\n } else {\n return base64.decodeString(str, /*useWebSafe=*/true);\n }\n } catch (e) {\n log('base64Decode failed: ', e);\n }\n return null;\n};\n\n\n/**\n * Sha1 hash of the input string\n * @param {!string} str The string to hash\n * @return {!string} The resulting hash\n */\nexport const sha1 = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n const sha1 = new Sha1();\n sha1.update(utf8Bytes);\n const sha1Bytes = sha1.digest();\n return base64.encodeByteArray(sha1Bytes);\n};\n\n\n/**\n * @param {...*} var_args\n * @return {string}\n * @private\n */\nconst buildLogMessage_ = function (...var_args: any[]): string {\n let message = '';\n for (let i = 0; i < var_args.length; i++) {\n if (Array.isArray(var_args[i]) ||\n (var_args[i] && typeof var_args[i] === 'object' && typeof var_args[i].length === 'number')) {\n message += buildLogMessage_.apply(null, var_args[i]);\n }\n else if (typeof var_args[i] === 'object') {\n message += stringify(var_args[i]);\n }\n else {\n message += var_args[i];\n }\n message += ' ';\n }\n\n return message;\n};\n\n\n/**\n * Use this for all debug messages in Firebase.\n * @type {?function(string)}\n */\nexport let logger: ((a: string) => void) | null = null;\n\n\n/**\n * Flag to check for log availability on first log message\n * @type {boolean}\n * @private\n */\nlet firstLog_ = true;\n\n\n/**\n * The implementation of Firebase.enableLogging (defined here to break dependencies)\n * @param {boolean|?function(string)} logger_ A flag to turn on logging, or a custom logger\n * @param {boolean=} persistent Whether or not to persist logging settings across refreshes\n */\nexport const enableLogging = function (logger_?: boolean | ((a: string) => void) | null, persistent?: boolean) {\n assert(!persistent || (logger_ === true || logger_ === false), 'Can\\'t turn on custom loggers persistently.');\n if (logger_ === true) {\n if (typeof console !== 'undefined') {\n if (typeof console.log === 'function') {\n logger = console.log.bind(console);\n } else if (typeof console.log === 'object') {\n // IE does this.\n logger = function (message) { console.log(message); };\n }\n }\n if (persistent)\n SessionStorage.set('logging_enabled', true);\n }\n else if (typeof logger_ === 'function') {\n logger = logger_;\n } else {\n logger = null;\n SessionStorage.remove('logging_enabled');\n }\n};\n\n\n/**\n *\n * @param {...(string|Arguments)} var_args\n */\nexport const log = function (...var_args: string[]) {\n if (firstLog_ === true) {\n firstLog_ = false;\n if (logger === null && SessionStorage.get('logging_enabled') === true)\n enableLogging(true);\n }\n\n if (logger) {\n const message = buildLogMessage_.apply(null, var_args);\n logger(message);\n }\n};\n\n\n/**\n * @param {!string} prefix\n * @return {function(...[*])}\n */\nexport const logWrapper = function (prefix: string): (...var_args: any[]) => void {\n return function (...var_args: any[]) {\n log(prefix, ...var_args);\n };\n};\n\n\n/**\n * @param {...string} var_args\n */\nexport const error = function (...var_args: string[]) {\n if (typeof console !== 'undefined') {\n const message = 'FIREBASE INTERNAL ERROR: ' +\n buildLogMessage_(...var_args);\n if (typeof console.error !== 'undefined') {\n console.error(message);\n } else {\n console.log(message);\n }\n }\n};\n\n\n/**\n * @param {...string} var_args\n */\nexport const fatal = function (...var_args: string[]) {\n const message = buildLogMessage_(...var_args);\n throw new Error('FIREBASE FATAL ERROR: ' + message);\n};\n\n\n/**\n * @param {...*} var_args\n */\nexport const warn = function (...var_args: any[]) {\n if (typeof console !== 'undefined') {\n const message = 'FIREBASE WARNING: ' + buildLogMessage_(...var_args);\n if (typeof console.warn !== 'undefined') {\n console.warn(message);\n } else {\n console.log(message);\n }\n }\n};\n\n\n/**\n * Logs a warning if the containing page uses https. Called when a call to new Firebase\n * does not use https.\n */\nexport const warnIfPageIsSecure = function () {\n // Be very careful accessing browser globals. Who knows what may or may not exist.\n if (typeof window !== 'undefined' && window.location && window.location.protocol &&\n window.location.protocol.indexOf('https:') !== -1) {\n warn('Insecure Firebase access from a secure page. ' +\n 'Please use https in calls to new Firebase().');\n }\n};\n\n\n/**\n * @param {!String} methodName\n */\nexport const warnAboutUnsupportedMethod = function (methodName: string) {\n warn(methodName +\n ' is unsupported and will likely change soon. ' +\n 'Please do not use.');\n};\n\n\n/**\n * Returns true if data is NaN, or +/- Infinity.\n * @param {*} data\n * @return {boolean}\n */\nexport const isInvalidJSONNumber = function (data: any): boolean {\n return typeof data === 'number' &&\n (data != data || // NaN\n data == Number.POSITIVE_INFINITY ||\n data == Number.NEGATIVE_INFINITY);\n};\n\n\n/**\n * @param {function()} fn\n */\nexport const executeWhenDOMReady = function (fn: () => void) {\n if (isNodeSdk() || document.readyState === 'complete') {\n fn();\n } else {\n // Modeled after jQuery. Try DOMContentLoaded and onreadystatechange (which\n // fire before onload), but fall back to onload.\n\n let called = false;\n let wrappedFn = function () {\n if (!document.body) {\n setTimeout(wrappedFn, Math.floor(10));\n return;\n }\n\n if (!called) {\n called = true;\n fn();\n }\n };\n\n if (document.addEventListener) {\n document.addEventListener('DOMContentLoaded', wrappedFn, false);\n // fallback to onload.\n window.addEventListener('load', wrappedFn, false);\n } else if ((document as any).attachEvent) {\n // IE.\n (document as any).attachEvent('onreadystatechange',\n function () {\n if (document.readyState === 'complete')\n wrappedFn();\n }\n );\n // fallback to onload.\n (window as any).attachEvent('onload', wrappedFn);\n\n // jQuery has an extra hack for IE that we could employ (based on\n // http://javascript.nwbox.com/IEContentLoaded/) But it looks really old.\n // I'm hoping we don't need it.\n }\n }\n};\n\n\n/**\n * Minimum key name. Invalid for actual data, used as a marker to sort before any valid names\n * @type {!string}\n */\nexport const MIN_NAME = '[MIN_NAME]';\n\n\n/**\n * Maximum key name. Invalid for actual data, used as a marker to sort above any valid names\n * @type {!string}\n */\nexport const MAX_NAME = '[MAX_NAME]';\n\n\n/**\n * Compares valid Firebase key names, plus min and max name\n * @param {!string} a\n * @param {!string} b\n * @return {!number}\n */\nexport const nameCompare = function (a: string, b: string): number {\n if (a === b) {\n return 0;\n } else if (a === MIN_NAME || b === MAX_NAME) {\n return -1;\n } else if (b === MIN_NAME || a === MAX_NAME) {\n return 1;\n } else {\n const aAsInt = tryParseInt(a),\n bAsInt = tryParseInt(b);\n\n if (aAsInt !== null) {\n if (bAsInt !== null) {\n return (aAsInt - bAsInt) == 0 ? (a.length - b.length) : (aAsInt - bAsInt);\n } else {\n return -1;\n }\n } else if (bAsInt !== null) {\n return 1;\n } else {\n return (a < b) ? -1 : 1;\n }\n }\n};\n\n\n/**\n * @param {!string} a\n * @param {!string} b\n * @return {!number} comparison result.\n */\nexport const stringCompare = function (a: string, b: string): number {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else {\n return 1;\n }\n};\n\n\n/**\n * @param {string} key\n * @param {Object} obj\n * @return {*}\n */\nexport const requireKey = function (key: string, obj: { [k: string]: any }): any {\n if (obj && (key in obj)) {\n return obj[key];\n } else {\n throw new Error('Missing required key (' + key + ') in object: ' + stringify(obj));\n }\n};\n\n\n/**\n * @param {*} obj\n * @return {string}\n */\nexport const ObjectToUniqueKey = function (obj: any): string {\n if (typeof obj !== 'object' || obj === null)\n return stringify(obj);\n\n const keys = [];\n for (let k in obj) {\n keys.push(k);\n }\n\n // Export as json, but with the keys sorted.\n keys.sort();\n let key = '{';\n for (let i = 0; i < keys.length; i++) {\n if (i !== 0)\n key += ',';\n key += stringify(keys[i]);\n key += ':';\n key += ObjectToUniqueKey(obj[keys[i]]);\n }\n\n key += '}';\n return key;\n};\n\n\n/**\n * Splits a string into a number of smaller segments of maximum size\n * @param {!string} str The string\n * @param {!number} segsize The maximum number of chars in the string.\n * @return {Array.} The string, split into appropriately-sized chunks\n */\nexport const splitStringBySize = function (str: string, segsize: number): string[] {\n const len = str.length;\n\n if (len <= segsize) {\n return [str];\n }\n\n const dataSegs = [];\n for (let c = 0; c < len; c += segsize) {\n if (c + segsize > len) {\n dataSegs.push(str.substring(c, len));\n }\n else {\n dataSegs.push(str.substring(c, c + segsize));\n }\n }\n return dataSegs;\n};\n\n\n/**\n * Apply a function to each (key, value) pair in an object or\n * apply a function to each (index, value) pair in an array\n * @param {!(Object|Array)} obj The object or array to iterate over\n * @param {function(?, ?)} fn The function to apply\n */\nexport const each = function (obj: Object | Array, fn: (v?: any, k?: any) => void) {\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; ++i) {\n fn(i, obj[i]);\n }\n } else {\n /**\n * in the conversion of code we removed the goog.object.forEach\n * function which did a value,key callback. We standardized on\n * a single impl that does a key, value callback. So we invert\n * to not have to touch the `each` code points\n */\n forEach(obj, (key: any, val: any) => fn(val, key));\n }\n};\n\n\n/**\n * Like goog.bind, but doesn't bother to create a closure if opt_context is null/undefined.\n * @param {function(*)} callback Callback function.\n * @param {?Object=} context Optional context to bind to.\n * @return {function(*)}\n */\nexport const bindCallback = function (callback: (a: any) => void, context?: object | null): Function {\n return context ? callback.bind(context) : callback;\n};\n\n\n/**\n * Borrowed from http://hg.secondlife.com/llsd/src/tip/js/typedarray.js (MIT License)\n * I made one modification at the end and removed the NaN / Infinity\n * handling (since it seemed broken [caused an overflow] and we don't need it). See MJL comments.\n * @param {!number} v A double\n * @return {string}\n */\nexport const doubleToIEEE754String = function (v: number): string {\n assert(!isInvalidJSONNumber(v), 'Invalid JSON number'); // MJL\n\n const ebits = 11, fbits = 52;\n let bias = (1 << (ebits - 1)) - 1,\n s, e, f, ln,\n i, bits, str;\n\n // Compute sign, exponent, fraction\n // Skip NaN / Infinity handling --MJL.\n if (v === 0) {\n e = 0;\n f = 0;\n s = (1 / v === -Infinity) ? 1 : 0;\n }\n else {\n s = v < 0;\n v = Math.abs(v);\n\n if (v >= Math.pow(2, 1 - bias)) {\n // Normalized\n ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);\n e = ln + bias;\n f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits));\n }\n else {\n // Denormalized\n e = 0;\n f = Math.round(v / Math.pow(2, 1 - bias - fbits));\n }\n }\n\n // Pack sign, exponent, fraction\n bits = [];\n for (i = fbits; i; i -= 1) {\n bits.push(f % 2 ? 1 : 0);\n f = Math.floor(f / 2);\n }\n for (i = ebits; i; i -= 1) {\n bits.push(e % 2 ? 1 : 0);\n e = Math.floor(e / 2);\n }\n bits.push(s ? 1 : 0);\n bits.reverse();\n str = bits.join('');\n\n // Return the data as a hex string. --MJL\n let hexByteString = '';\n for (i = 0; i < 64; i += 8) {\n let hexByte = parseInt(str.substr(i, 8), 2).toString(16);\n if (hexByte.length === 1)\n hexByte = '0' + hexByte;\n hexByteString = hexByteString + hexByte;\n }\n return hexByteString.toLowerCase();\n};\n\n\n/**\n * Used to detect if we're in a Chrome content script (which executes in an\n * isolated environment where long-polling doesn't work).\n * @return {boolean}\n */\nexport const isChromeExtensionContentScript = function (): boolean {\n return !!(typeof window === 'object' &&\n window['chrome'] &&\n window['chrome']['extension'] &&\n !/^chrome/.test(window.location.href)\n );\n};\n\n\n/**\n * Used to detect if we're in a Windows 8 Store app.\n * @return {boolean}\n */\nexport const isWindowsStoreApp = function (): boolean {\n // Check for the presence of a couple WinRT globals\n return typeof Windows === 'object' && typeof Windows.UI === 'object';\n};\n\n\n/**\n * Converts a server error code to a Javascript Error\n * @param {!string} code\n * @param {!Query} query\n * @return {Error}\n */\nexport const errorForServerCode = function (code: string, query: Query): Error {\n let reason = 'Unknown Error';\n if (code === 'too_big') {\n reason = 'The data requested exceeds the maximum size ' +\n 'that can be accessed with a single request.';\n } else if (code == 'permission_denied') {\n reason = 'Client doesn\\'t have permission to access the desired data.';\n } else if (code == 'unavailable') {\n reason = 'The service is unavailable';\n }\n\n const error = new Error(code + ' at ' + query.path.toString() + ': ' + reason);\n (error as any).code = code.toUpperCase();\n return error;\n};\n\n\n/**\n * Used to test for integer-looking strings\n * @type {RegExp}\n * @private\n */\nexport const INTEGER_REGEXP_ = new RegExp('^-?\\\\d{1,10}$');\n\n\n/**\n * If the string contains a 32-bit integer, return it. Else return null.\n * @param {!string} str\n * @return {?number}\n */\nexport const tryParseInt = function (str: string): number | null {\n if (INTEGER_REGEXP_.test(str)) {\n const intVal = Number(str);\n if (intVal >= -2147483648 && intVal <= 2147483647) {\n return intVal;\n }\n }\n return null;\n};\n\n\n/**\n * Helper to run some code but catch any exceptions and re-throw them later.\n * Useful for preventing user callbacks from breaking internal code.\n *\n * Re-throwing the exception from a setTimeout is a little evil, but it's very\n * convenient (we don't have to try to figure out when is a safe point to\n * re-throw it), and the behavior seems reasonable:\n *\n * * If you aren't pausing on exceptions, you get an error in the console with\n * the correct stack trace.\n * * If you're pausing on all exceptions, the debugger will pause on your\n * exception and then again when we rethrow it.\n * * If you're only pausing on uncaught exceptions, the debugger will only pause\n * on us re-throwing it.\n *\n * @param {!function()} fn The code to guard.\n */\nexport const exceptionGuard = function (fn: () => void) {\n try {\n fn();\n } catch (e) {\n // Re-throw exception when it's safe.\n setTimeout(function () {\n // It used to be that \"throw e\" would result in a good console error with\n // relevant context, but as of Chrome 39, you just get the firebase.js\n // file/line number where we re-throw it, which is useless. So we log\n // e.stack explicitly.\n const stack = e.stack || '';\n warn('Exception was thrown by user callback.', stack);\n throw e;\n }, Math.floor(0));\n }\n};\n\n\n/**\n * Helper function to safely call opt_callback with the specified arguments. It:\n * 1. Turns into a no-op if opt_callback is null or undefined.\n * 2. Wraps the call inside exceptionGuard to prevent exceptions from breaking our state.\n *\n * @param {?Function=} callback Optional onComplete callback.\n * @param {...*} var_args Arbitrary args to be passed to opt_onComplete\n */\nexport const callUserCallback = function (callback?: Function | null, ...var_args: any[]) {\n if (typeof callback === 'function') {\n exceptionGuard(function () {\n callback(...var_args);\n });\n }\n};\n\n\n/**\n * @return {boolean} true if we think we're currently being crawled.\n */\nexport const beingCrawled = function (): boolean {\n const userAgent = (typeof window === 'object' && window['navigator'] && window['navigator']['userAgent']) || '';\n\n // For now we whitelist the most popular crawlers. We should refine this to be the set of crawlers we\n // believe to support JavaScript/AJAX rendering.\n // NOTE: Google Webmaster Tools doesn't really belong, but their \"This is how a visitor to your website\n // would have seen the page\" is flaky if we don't treat it as a crawler.\n return userAgent.search(/googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i) >=\n 0;\n};\n\n/**\n * Export a property of an object using a getter function.\n *\n * @param {!Object} object\n * @param {string} name\n * @param {!function(): *} fnGet\n */\nexport const exportPropGetter = function (object: Object, name: string, fnGet: () => any) {\n Object.defineProperty(object, name, {get: fnGet});\n};\n\n/**\n * Same as setTimeout() except on Node.JS it will /not/ prevent the process from exiting.\n *\n * It is removed with clearTimeout() as normal.\n *\n * @param {Function} fn Function to run.\n * @param {number} time Milliseconds to wait before running.\n * @return {number|Object} The setTimeout() return value.\n */\nexport const setTimeoutNonBlocking = function (fn: Function, time: number): number | Object {\n const timeout: number | Object = setTimeout(fn, time);\n if (typeof timeout === 'object' && (timeout as any)['unref']) {\n (timeout as any)['unref']();\n }\n return timeout;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/util.ts","/**\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// See http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/\n\nexport const contains = function(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n};\n\nexport const safeGet = function(obj, key) {\n if (Object.prototype.hasOwnProperty.call(obj, key))\n return obj[key];\n // else return undefined.\n};\n\n/**\n * Enumerates the keys/values in an object, excluding keys defined on the prototype.\n *\n * @param {?Object.} obj Object to enumerate.\n * @param {!function(K, V)} fn Function to call for each key and value.\n * @template K,V\n */\nexport const forEach = function(obj, fn) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n fn(key, obj[key]);\n }\n }\n};\n\n/**\n * Copies all the (own) properties from one object to another.\n * @param {!Object} objTo\n * @param {!Object} objFrom\n * @return {!Object} objTo\n */\nexport const extend = function(objTo, objFrom) {\n forEach(objFrom, function(key, value) {\n objTo[key] = value;\n });\n return objTo;\n}\n\n\n/**\n * Returns a clone of the specified object.\n * @param {!Object} obj\n * @return {!Object} cloned obj.\n */\nexport const clone = function(obj) {\n return extend({}, obj);\n};\n\n\n/**\n * Returns true if obj has typeof \"object\" and is not null. Unlike goog.isObject(), does not return true\n * for functions.\n *\n * @param obj {*} A potential object.\n * @returns {boolean} True if it's an object.\n */\nexport const isNonNullObject = function(obj) {\n return typeof obj === 'object' && obj !== null;\n};\n\nexport const isEmpty = function(obj) {\n for (var key in obj) {\n return false;\n }\n return true;\n}\n\nexport const getCount = function(obj) {\n var rv = 0;\n for (var key in obj) {\n rv++;\n }\n return rv;\n}\n\nexport const map = function(obj, f, opt_obj?) {\n var res = {};\n for (var key in obj) {\n res[key] = f.call(opt_obj, obj[key], key, obj);\n }\n return res;\n};\n\nexport const findKey = function(obj, fn, opt_this?) {\n for (var key in obj) {\n if (fn.call(opt_this, obj[key], key, obj)) {\n return key;\n }\n }\n return undefined;\n};\n\nexport const findValue = function(obj, fn, opt_this?) {\n var key = findKey(obj, fn, opt_this);\n return key && obj[key];\n};\n\nexport const getAnyKey = function(obj) {\n for (var key in obj) {\n return key;\n }\n};\n\nexport const getValues = function(obj) {\n var res = [];\n var i = 0;\n for (var key in obj) {\n res[i++] = obj[key];\n }\n return res;\n};\n\n/**\n * Tests whether every key/value pair in an object pass the test implemented\n * by the provided function\n *\n * @param {?Object.} obj Object to test.\n * @param {!function(K, V)} fn Function to call for each key and value.\n * @template K,V\n */\nexport const every = function(obj: Object, fn: (k: string, v?: V) => boolean): boolean {\n for (let key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n if (!fn(key, obj[key])) {\n return false;\n }\n }\n }\n return true;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/obj.ts","/**\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 * Evaluates a JSON string into a javascript object.\n *\n * @param {string} str A string containing JSON.\n * @return {*} The javascript object representing the specified JSON.\n */\nexport const jsonEval = function(str) {\n return JSON.parse(str);\n};\n\n\n/**\n * Returns JSON representing a javascript object.\n * @param {*} data Javascript object to be stringified.\n * @return {string} The JSON contents of the object.\n */\nexport const stringify = function(data) {\n return JSON.stringify(data);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/json.ts","/**\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\nimport { CONSTANTS } from \"./constants\";\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return {string} user agent string\n */\nexport const getUA = function() {\n if (typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string') {\n return navigator['userAgent'];\n } else {\n return '';\n }\n};\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap in the Ripple emulator) nor\n * Cordova `onDeviceReady`, which would normally wait for a callback.\n *\n * @return {boolean} isMobileCordova\n */\nexport const isMobileCordova = function() {\n return typeof window !== 'undefined' &&\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA());\n};\n\n\n/**\n * Detect React Native.\n *\n * @return {boolean} True if ReactNative environment is detected.\n */\nexport const isReactNative = function() {\n return typeof navigator === 'object' && navigator['product'] === 'ReactNative';\n};\n\n\n/**\n * Detect Node.js.\n *\n * @return {boolean} True if Node.js environment is detected.\n */\nexport const isNodeSdk = function() {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/environment.ts","/**\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 Firebase constants. Some of these (@defines) can be overridden at compile-time.\n */\n\nexport const CONSTANTS = {\n /**\n * @define {boolean} Whether this is the client Node.js SDK.\n */\n NODE_CLIENT: false,\n /**\n * @define {boolean} Whether this is the Admin Node.js SDK.\n */\n NODE_ADMIN: false,\n\n /**\n * Firebase SDK Version\n */\n SDK_VERSION: '4.1.4'\n}\n\n\n// WEBPACK FOOTER //\n// ./src/utils/constants.ts","/**\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\nimport { jsonEval, stringify } from '../../../utils/json';\n\n/**\n * Wraps a DOM Storage object and:\n * - automatically encode objects as JSON strings before storing them to allow us to store arbitrary types.\n * - prefixes names with \"firebase:\" to avoid collisions with app data.\n *\n * We automatically (see storage.js) create two such wrappers, one for sessionStorage,\n * and one for localStorage.\n *\n * @constructor\n */\nexport class DOMStorageWrapper {\n // Use a prefix to avoid collisions with other stuff saved by the app.\n private prefix_ = 'firebase:';\n\n /**\n * @param {Storage} domStorage_ The underlying storage object (e.g. localStorage or sessionStorage)\n */\n constructor(private domStorage_: Storage) {\n }\n\n /**\n * @param {string} key The key to save the value under\n * @param {?Object} value The value being stored, or null to remove the key.\n */\n set(key: string, value: any | null) {\n if (value == null) {\n this.domStorage_.removeItem(this.prefixedName_(key));\n } else {\n this.domStorage_.setItem(this.prefixedName_(key), stringify(value));\n }\n }\n\n /**\n * @param {string} key\n * @return {*} The value that was stored under this key, or null\n */\n get(key: string): any {\n const storedVal = this.domStorage_.getItem(this.prefixedName_(key));\n if (storedVal == null) {\n return null;\n } else {\n return jsonEval(storedVal);\n }\n }\n\n /**\n * @param {string} key\n */\n remove(key: string) {\n this.domStorage_.removeItem(this.prefixedName_(key));\n }\n\n isInMemoryStorage: boolean;\n\n /**\n * @param {string} name\n * @return {string}\n */\n prefixedName_(name: string): string {\n return this.prefix_ + name;\n }\n\n toString(): string {\n return this.domStorage_.toString();\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/storage/DOMStorageWrapper.ts","/**\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\nimport { contains } from '../../../utils/obj';\n\n/**\n * An in-memory storage implementation that matches the API of DOMStorageWrapper\n * (TODO: create interface for both to implement).\n *\n * @constructor\n */\nexport class MemoryStorage {\n private cache_: { [k: string]: any } = {};\n\n set(key: string, value: any | null) {\n if (value == null) {\n delete this.cache_[key];\n } else {\n this.cache_[key] = value;\n }\n }\n\n get(key: string): any {\n if (contains(this.cache_, key)) {\n return this.cache_[key];\n }\n return null;\n }\n\n remove(key: string) {\n delete this.cache_[key];\n }\n\n isInMemoryStorage = true;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/storage/MemoryStorage.ts","/**\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\nimport { DOMStorageWrapper } from './DOMStorageWrapper';\nimport { MemoryStorage } from './MemoryStorage';\n\ndeclare const window: any;\n\n/**\n* Helper to create a DOMStorageWrapper or else fall back to MemoryStorage.\n* TODO: Once MemoryStorage and DOMStorageWrapper have a shared interface this method annotation should change\n* to reflect this type\n*\n* @param {string} domStorageName Name of the underlying storage object\n* (e.g. 'localStorage' or 'sessionStorage').\n* @return {?} Turning off type information until a common interface is defined.\n*/\nconst createStoragefor = function(domStorageName: string): DOMStorageWrapper | MemoryStorage {\n try {\n // NOTE: just accessing \"localStorage\" or \"window['localStorage']\" may throw a security exception,\n // so it must be inside the try/catch.\n if (typeof window !== 'undefined' && typeof window[domStorageName] !== 'undefined') {\n // Need to test cache. Just because it's here doesn't mean it works\n const domStorage = window[domStorageName];\n domStorage.setItem('firebase:sentinel', 'cache');\n domStorage.removeItem('firebase:sentinel');\n return new DOMStorageWrapper(domStorage);\n }\n } catch (e) {\n }\n \n // Failed to create wrapper. Just return in-memory storage.\n // TODO: log?\n return new MemoryStorage();\n};\n\n\n/** A storage object that lasts across sessions */\nexport const PersistentStorage = createStoragefor('localStorage');\n\n\n/** A storage object that only lasts one session */\nexport const SessionStorage = createStoragefor('sessionStorage');\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/storage/storage.ts","/**\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\nexport const PROTOCOL_VERSION = '5';\n\nexport const VERSION_PARAM = 'v';\n\nexport const TRANSPORT_SESSION_PARAM = 's';\n\nexport const REFERER_PARAM = 'r';\n\nexport const FORGE_REF = 'f';\n\nexport const FORGE_DOMAIN = 'firebaseio.com';\n\nexport const LAST_SESSION_PARAM = 'ls';\n\nexport const WEBSOCKET = 'websocket';\n\nexport const LONG_POLLING = 'long_polling';\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/realtime/Constants.ts","/**\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\nimport { assert } from \"./assert\";\n\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\n// so it's been modified.\n\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\n// pair).\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\n\n\n/**\n * @param {string} str\n * @return {Array}\n */\nexport const stringToByteArray = function(str) {\n var out = [], p = 0;\n for (var i = 0; i < str.length; i++) {\n var c = str.charCodeAt(i);\n\n // Is this the lead surrogate in a surrogate pair?\n if (c >= 0xd800 && c <= 0xdbff) {\n var high = c - 0xd800; // the high 10 bits.\n i++;\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\n var low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\n c = 0x10000 + (high << 10) + low;\n }\n\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 (c < 65536) {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\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 }\n }\n return out;\n};\n\n\n/**\n * Calculate length without actually converting; useful for doing cheaper validation.\n * @param {string} str\n * @return {number}\n */\nexport const stringLength = function(str) {\n var p = 0;\n for (var i = 0; i < str.length; i++) {\n var c = str.charCodeAt(i);\n if (c < 128) {\n p++;\n } else if (c < 2048) {\n p += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\n p += 4;\n i++; // skip trail surrogate.\n } else {\n p += 3;\n }\n }\n return p;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/utf8.ts","/**\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\nimport { deepCopy } from '../../../utils/deep_copy';\nimport { contains } from '../../../utils/obj';\n\n/**\n * Tracks a collection of stats.\n *\n * @constructor\n */\nexport class StatsCollection {\n private counters_: { [k: string]: number } = {};\n\n incrementCounter(name: string, amount: number = 1) {\n if (!contains(this.counters_, name))\n this.counters_[name] = 0;\n\n this.counters_[name] += amount;\n }\n\n get() {\n return deepCopy(this.counters_);\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/stats/StatsCollection.ts","/**\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\nimport { StatsCollection } from './StatsCollection';\nimport { RepoInfo } from '../RepoInfo';\n\nexport class StatsManager {\n private static collections_: { [k: string]: StatsCollection } = {};\n private static reporters_: { [k: string]: any } = {};\n\n static getCollection(repoInfo: RepoInfo): StatsCollection {\n const hashString = repoInfo.toString();\n\n if (!this.collections_[hashString]) {\n this.collections_[hashString] = new StatsCollection();\n }\n\n return this.collections_[hashString];\n }\n\n static getOrCreateReporter(repoInfo: RepoInfo, creatorFunction: () => T): T {\n const hashString = repoInfo.toString();\n\n if (!this.reporters_[hashString]) {\n this.reporters_[hashString] = creatorFunction();\n }\n\n return this.reporters_[hashString];\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/stats/StatsManager.ts","/**\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\nimport { RepoInfo } from '../core/RepoInfo';\n\ndeclare const MozWebSocket: any;\n\nimport firebase from '../../app';\nimport { assert } from '../../utils/assert';\nimport { logWrapper, splitStringBySize } from '../core/util/util';\nimport { StatsManager } from '../core/stats/StatsManager';\nimport {\n FORGE_DOMAIN,\n FORGE_REF,\n LAST_SESSION_PARAM,\n PROTOCOL_VERSION,\n REFERER_PARAM,\n TRANSPORT_SESSION_PARAM,\n VERSION_PARAM,\n WEBSOCKET\n} from './Constants';\nimport { CONSTANTS as ENV_CONSTANTS } from '../../utils/constants';\nimport { PersistentStorage } from '../core/storage/storage';\nimport { jsonEval, stringify } from '../../utils/json';\nimport { isNodeSdk } from '../../utils/environment';\nimport { Transport } from './Transport';\nimport { StatsCollection } from '../core/stats/StatsCollection';\n\nconst WEBSOCKET_MAX_FRAME_SIZE = 16384;\nconst WEBSOCKET_KEEPALIVE_INTERVAL = 45000;\n\nlet WebSocketImpl = null;\nif (typeof MozWebSocket !== 'undefined') {\n WebSocketImpl = MozWebSocket;\n} else if (typeof WebSocket !== 'undefined') {\n WebSocketImpl = WebSocket;\n}\n\nexport function setWebSocketImpl(impl) {\n WebSocketImpl = impl;\n}\n\n/**\n * Create a new websocket connection with the given callbacks.\n * @constructor\n * @implements {Transport}\n */\nexport class WebSocketConnection implements Transport {\n keepaliveTimer: number | null = null;\n frames: string[] | null = null;\n totalFrames = 0;\n bytesSent = 0;\n bytesReceived = 0;\n connURL: string;\n onDisconnect: (a?: boolean) => void;\n onMessage: (msg: Object) => void;\n mySock: any | null;\n private log_: (...a: any[]) => void;\n private stats_: StatsCollection;\n private everConnected_: boolean;\n private isClosed_: boolean;\n\n /**\n * @param {string} connId identifier for this transport\n * @param {RepoInfo} repoInfo The info for the websocket endpoint.\n * @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport\n * session\n * @param {string=} lastSessionId Optional lastSessionId if there was a previous connection\n */\n constructor(public connId: string, repoInfo: RepoInfo,\n transportSessionId?: string, lastSessionId?: string) {\n this.log_ = logWrapper(this.connId);\n this.stats_ = StatsManager.getCollection(repoInfo);\n this.connURL = WebSocketConnection.connectionURL_(repoInfo, transportSessionId, lastSessionId);\n }\n\n /**\n * @param {RepoInfo} repoInfo The info for the websocket endpoint.\n * @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport\n * session\n * @param {string=} lastSessionId Optional lastSessionId if there was a previous connection\n * @return {string} connection url\n * @private\n */\n private static connectionURL_(repoInfo: RepoInfo, transportSessionId?: string, lastSessionId?: string): string {\n const urlParams: { [k: string]: string } = {};\n urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\n\n if (!isNodeSdk() &&\n typeof location !== 'undefined' &&\n location.href &&\n location.href.indexOf(FORGE_DOMAIN) !== -1) {\n urlParams[REFERER_PARAM] = FORGE_REF;\n }\n if (transportSessionId) {\n urlParams[TRANSPORT_SESSION_PARAM] = transportSessionId;\n }\n if (lastSessionId) {\n urlParams[LAST_SESSION_PARAM] = lastSessionId;\n }\n return repoInfo.connectionURL(WEBSOCKET, urlParams);\n }\n\n /**\n *\n * @param onMessage Callback when messages arrive\n * @param onDisconnect Callback with connection lost.\n */\n open(onMessage: (msg: Object) => void, onDisconnect: (a?: boolean) => void) {\n this.onDisconnect = onDisconnect;\n this.onMessage = onMessage;\n\n this.log_('Websocket connecting to ' + this.connURL);\n\n this.everConnected_ = false;\n // Assume failure until proven otherwise.\n PersistentStorage.set('previous_websocket_failure', true);\n\n try {\n if (isNodeSdk()) {\n const device = ENV_CONSTANTS.NODE_ADMIN ? 'AdminNode' : 'Node';\n // UA Format: Firebase////\n const options: { [k: string]: object } = {\n 'headers': {\n 'User-Agent': `Firebase/${PROTOCOL_VERSION}/${firebase.SDK_VERSION}/${process.platform}/${device}`\n }};\n\n // Plumb appropriate http_proxy environment variable into faye-websocket if it exists.\n const env = process['env'];\n const proxy = (this.connURL.indexOf('wss://') == 0)\n ? (env['HTTPS_PROXY'] || env['https_proxy'])\n : (env['HTTP_PROXY'] || env['http_proxy']);\n\n if (proxy) {\n options['proxy'] = {origin: proxy};\n }\n\n this.mySock = new WebSocketImpl(this.connURL, [], options);\n } else {\n this.mySock = new WebSocketImpl(this.connURL);\n }\n } catch (e) {\n this.log_('Error instantiating WebSocket.');\n const error = e.message || e.data;\n if (error) {\n this.log_(error);\n }\n this.onClosed_();\n return;\n }\n\n this.mySock.onopen = () => {\n this.log_('Websocket connected.');\n this.everConnected_ = true;\n };\n\n this.mySock.onclose = () => {\n this.log_('Websocket connection was disconnected.');\n this.mySock = null;\n this.onClosed_();\n };\n\n this.mySock.onmessage = (m: object) => {\n this.handleIncomingFrame(m);\n };\n\n this.mySock.onerror = (e: any) => {\n this.log_('WebSocket error. Closing connection.');\n const error = e.message || e.data;\n if (error) {\n this.log_(error);\n }\n this.onClosed_();\n };\n }\n\n /**\n * No-op for websockets, we don't need to do anything once the connection is confirmed as open\n */\n start() {};\n\n static forceDisallow_: Boolean;\n\n static forceDisallow() {\n WebSocketConnection.forceDisallow_ = true;\n }\n\n static isAvailable(): boolean {\n let isOldAndroid = false;\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n const oldAndroidRegex = /Android ([0-9]{0,}\\.[0-9]{0,})/;\n const oldAndroidMatch = navigator.userAgent.match(oldAndroidRegex);\n if (oldAndroidMatch && oldAndroidMatch.length > 1) {\n if (parseFloat(oldAndroidMatch[1]) < 4.4) {\n isOldAndroid = true;\n }\n }\n }\n\n return !isOldAndroid && WebSocketImpl !== null && !WebSocketConnection.forceDisallow_;\n }\n\n /**\n * Number of response before we consider the connection \"healthy.\"\n * @type {number}\n */\n static responsesRequiredToBeHealthy = 2;\n\n /**\n * Time to wait for the connection te become healthy before giving up.\n * @type {number}\n */\n static healthyTimeout = 30000;\n\n /**\n * Returns true if we previously failed to connect with this transport.\n * @return {boolean}\n */\n static previouslyFailed(): boolean {\n // If our persistent storage is actually only in-memory storage,\n // we default to assuming that it previously failed to be safe.\n return PersistentStorage.isInMemoryStorage ||\n PersistentStorage.get('previous_websocket_failure') === true;\n }\n\n markConnectionHealthy() {\n PersistentStorage.remove('previous_websocket_failure');\n }\n\n private appendFrame_(data: string) {\n this.frames.push(data);\n if (this.frames.length == this.totalFrames) {\n const fullMess = this.frames.join('');\n this.frames = null;\n const jsonMess = jsonEval(fullMess);\n\n //handle the message\n this.onMessage(jsonMess);\n }\n }\n\n /**\n * @param {number} frameCount The number of frames we are expecting from the server\n * @private\n */\n private handleNewFrameCount_(frameCount: number) {\n this.totalFrames = frameCount;\n this.frames = [];\n }\n\n /**\n * Attempts to parse a frame count out of some text. If it can't, assumes a value of 1\n * @param {!String} data\n * @return {?String} Any remaining data to be process, or null if there is none\n * @private\n */\n private extractFrameCount_(data: string): string | null {\n assert(this.frames === null, 'We already have a frame buffer');\n // TODO: The server is only supposed to send up to 9999 frames (i.e. length <= 4), but that isn't being enforced\n // currently. So allowing larger frame counts (length <= 6). See https://app.asana.com/0/search/8688598998380/8237608042508\n if (data.length <= 6) {\n const frameCount = Number(data);\n if (!isNaN(frameCount)) {\n this.handleNewFrameCount_(frameCount);\n return null;\n }\n }\n this.handleNewFrameCount_(1);\n return data;\n }\n\n /**\n * Process a websocket frame that has arrived from the server.\n * @param mess The frame data\n */\n handleIncomingFrame(mess: { [k: string]: any }) {\n if (this.mySock === null)\n return; // Chrome apparently delivers incoming packets even after we .close() the connection sometimes.\n const data = mess['data'] as string;\n this.bytesReceived += data.length;\n this.stats_.incrementCounter('bytes_received', data.length);\n\n this.resetKeepAlive();\n\n if (this.frames !== null) {\n // we're buffering\n this.appendFrame_(data);\n } else {\n // try to parse out a frame count, otherwise, assume 1 and process it\n const remainingData = this.extractFrameCount_(data);\n if (remainingData !== null) {\n this.appendFrame_(remainingData);\n }\n }\n }\n\n /**\n * Send a message to the server\n * @param {Object} data The JSON object to transmit\n */\n send(data: Object) {\n\n this.resetKeepAlive();\n\n const dataStr = stringify(data);\n this.bytesSent += dataStr.length;\n this.stats_.incrementCounter('bytes_sent', dataStr.length);\n\n //We can only fit a certain amount in each websocket frame, so we need to split this request\n //up into multiple pieces if it doesn't fit in one request.\n\n const dataSegs = splitStringBySize(dataStr, WEBSOCKET_MAX_FRAME_SIZE);\n\n //Send the length header\n if (dataSegs.length > 1) {\n this.sendString_(String(dataSegs.length));\n }\n\n //Send the actual data in segments.\n for (let i = 0; i < dataSegs.length; i++) {\n this.sendString_(dataSegs[i]);\n }\n }\n\n private shutdown_() {\n this.isClosed_ = true;\n if (this.keepaliveTimer) {\n clearInterval(this.keepaliveTimer);\n this.keepaliveTimer = null;\n }\n\n if (this.mySock) {\n this.mySock.close();\n this.mySock = null;\n }\n }\n\n private onClosed_() {\n if (!this.isClosed_) {\n this.log_('WebSocket is closing itself');\n this.shutdown_();\n\n // since this is an internal close, trigger the close listener\n if (this.onDisconnect) {\n this.onDisconnect(this.everConnected_);\n this.onDisconnect = null;\n }\n }\n }\n\n /**\n * External-facing close handler.\n * Close the websocket and kill the connection.\n */\n close() {\n if (!this.isClosed_) {\n this.log_('WebSocket is being closed');\n this.shutdown_();\n }\n }\n\n /**\n * Kill the current keepalive timer and start a new one, to ensure that it always fires N seconds after\n * the last activity.\n */\n resetKeepAlive() {\n clearInterval(this.keepaliveTimer);\n this.keepaliveTimer = setInterval(() => {\n //If there has been no websocket activity for a while, send a no-op\n if (this.mySock) {\n this.sendString_('0');\n }\n this.resetKeepAlive();\n }, Math.floor(WEBSOCKET_KEEPALIVE_INTERVAL)) as any;\n }\n\n /**\n * Send a string over the websocket.\n *\n * @param {string} str String to send.\n * @private\n */\n private sendString_(str: string) {\n // Firefox seems to sometimes throw exceptions (NS_ERROR_UNEXPECTED) from websocket .send()\n // calls for some unknown reason. We treat these as an error and disconnect.\n // See https://app.asana.com/0/58926111402292/68021340250410\n try {\n this.mySock.send(str);\n } catch (e) {\n this.log_('Exception thrown from WebSocket.send():', e.message || e.data, 'Closing connection.');\n setTimeout(this.onClosed_.bind(this), 0);\n }\n }\n}\n\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/realtime/WebSocketConnection.ts","/**\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\nimport { Path } from '../Path';\nimport { RepoInfo } from '../../RepoInfo';\nimport { warnIfPageIsSecure, fatal } from '../util';\n\n/**\n * @param {!string} pathString\n * @return {string}\n */\nfunction decodePath(pathString: string): string {\n let pathStringDecoded = '';\n const pieces = pathString.split('/');\n for (let i = 0; i < pieces.length; i++) {\n if (pieces[i].length > 0) {\n let piece = pieces[i];\n try {\n piece = decodeURIComponent(piece.replace(/\\+/g, ' '));\n } catch (e) {}\n pathStringDecoded += '/' + piece;\n }\n }\n return pathStringDecoded;\n}\n\n/**\n *\n * @param {!string} dataURL\n * @return {{repoInfo: !RepoInfo, path: !Path}}\n */\nexport const parseRepoInfo = function (dataURL: string): { repoInfo: RepoInfo, path: Path } {\n const parsedUrl = parseURL(dataURL),\n namespace = parsedUrl.subdomain;\n\n if (parsedUrl.domain === 'firebase') {\n fatal(parsedUrl.host +\n ' is no longer supported. ' +\n 'Please use .firebaseio.com instead');\n }\n\n // Catch common error of uninitialized namespace value.\n if (!namespace || namespace == 'undefined') {\n fatal('Cannot parse Firebase url. Please use https://.firebaseio.com');\n }\n\n if (!parsedUrl.secure) {\n warnIfPageIsSecure();\n }\n\n const webSocketOnly = (parsedUrl.scheme === 'ws') || (parsedUrl.scheme === 'wss');\n\n return {\n repoInfo: new RepoInfo(parsedUrl.host, parsedUrl.secure, namespace, webSocketOnly),\n path: new Path(parsedUrl.pathString)\n };\n};\n\n/**\n *\n * @param {!string} dataURL\n * @return {{host: string, port: number, domain: string, subdomain: string, secure: boolean, scheme: string, pathString: string}}\n */\nexport const parseURL = function (dataURL: string): {\n host: string,\n port: number,\n domain: string,\n subdomain: string,\n secure: boolean,\n scheme: string,\n pathString: string\n} {\n // Default to empty strings in the event of a malformed string.\n let host = '', domain = '', subdomain = '', pathString = '';\n\n // Always default to SSL, unless otherwise specified.\n let secure = true, scheme = 'https', port = 443;\n\n // Don't do any validation here. The caller is responsible for validating the result of parsing.\n if (typeof dataURL === 'string') {\n // Parse scheme.\n let colonInd = dataURL.indexOf('//');\n if (colonInd >= 0) {\n scheme = dataURL.substring(0, colonInd - 1);\n dataURL = dataURL.substring(colonInd + 2);\n }\n\n // Parse host and path.\n let slashInd = dataURL.indexOf('/');\n if (slashInd === -1) {\n slashInd = dataURL.length;\n }\n host = dataURL.substring(0, slashInd);\n pathString = decodePath(dataURL.substring(slashInd));\n\n const parts = host.split('.');\n if (parts.length === 3) {\n // Normalize namespaces to lowercase to share storage / connection.\n domain = parts[1];\n subdomain = parts[0].toLowerCase();\n } else if (parts.length === 2) {\n domain = parts[0];\n }\n\n // If we have a port, use scheme for determining if it's secure.\n colonInd = host.indexOf(':');\n if (colonInd >= 0) {\n secure = (scheme === 'https') || (scheme === 'wss');\n port = parseInt(host.substring(colonInd + 1), 10);\n }\n }\n\n return {\n host,\n port,\n domain,\n subdomain,\n secure,\n scheme,\n pathString,\n };\n};\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/libs/parser.ts","/**\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 * Check to make sure the appropriate number of arguments are provided for a public function.\n * Throws an error if it fails.\n *\n * @param {!string} fnName The function name\n * @param {!number} minCount The minimum number of arguments to allow for the function call\n * @param {!number} maxCount The maximum number of argument to allow for the function call\n * @param {!number} argCount The actual number of arguments provided.\n */\nexport const validateArgCount = function(fnName, minCount, maxCount, argCount) {\n var argError;\n if (argCount < minCount) {\n argError = 'at least ' + minCount;\n } else if (argCount > maxCount) {\n argError = (maxCount === 0) ? 'none' : ('no more than ' + maxCount);\n }\n if (argError) {\n var error = fnName + ' failed: Was called with ' + argCount +\n ((argCount === 1) ? ' argument.' : ' arguments.') +\n ' Expects ' + argError + '.';\n throw new Error(error);\n }\n};\n\n/**\n * Generates a string to prefix an error message about failed argument validation\n *\n * @param {!string} fnName The function name\n * @param {!number} argumentNumber The index of the argument\n * @param {boolean} optional Whether or not the argument is optional\n * @return {!string} The prefix to add to the error thrown for validation.\n */\nexport function errorPrefix(fnName, argumentNumber, optional) {\n var argName = '';\n switch (argumentNumber) {\n case 1:\n argName = optional ? 'first' : 'First';\n break;\n case 2:\n argName = optional ? 'second' : 'Second';\n break;\n case 3:\n argName = optional ? 'third' : 'Third';\n break;\n case 4:\n argName = optional ? 'fourth' : 'Fourth';\n break;\n default:\n throw new Error('errorPrefix called with argumentNumber > 4. Need to update it?');\n }\n\n var error = fnName + ' failed: ';\n\n error += argName + ' argument ';\n return error;\n};\n\n/**\n * @param {!string} fnName\n * @param {!number} argumentNumber\n * @param {!string} namespace\n * @param {boolean} optional\n */\nexport const validateNamespace = function(fnName, argumentNumber, namespace, optional) {\n if (optional && !(namespace))\n return;\n if (typeof namespace !== 'string') {\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\n 'must be a valid firebase namespace.');\n }\n};\n\nexport const validateCallback = function(fnName, argumentNumber, callback, optional) {\n if (optional && !(callback))\n return;\n if (typeof callback !== 'function')\n throw new Error(errorPrefix(fnName, argumentNumber, optional) + 'must be a valid function.');\n};\n\nexport const validateContextObject = function(fnName, argumentNumber, context, optional) {\n if (optional && !(context))\n return;\n if (typeof context !== 'object' || context === null)\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\n 'must be a valid context object.');\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/validation.ts","/**\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\nimport { nameCompare } from \"../util/util\";\nimport { NamedNode } from './Node';\n\nexport function NAME_ONLY_COMPARATOR(left: NamedNode, right: NamedNode) {\n return nameCompare(left.name, right.name);\n}\n\nexport function NAME_COMPARATOR(left: string, right: string) {\n return nameCompare(left, right);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/comparators.ts","/**\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\nimport { ChildrenNode } from './ChildrenNode';\nimport { LeafNode } from './LeafNode';\nimport { NamedNode, Node } from './Node';\nimport { forEach, contains } from '../../../utils/obj';\nimport { assert } from '../../../utils/assert';\nimport { buildChildSet } from './childSet';\nimport { NAME_COMPARATOR, NAME_ONLY_COMPARATOR } from './comparators';\nimport { IndexMap } from './IndexMap';\nimport { PRIORITY_INDEX, setNodeFromJSON } from './indexes/PriorityIndex';\nimport { SortedMap } from '../util/SortedMap';\n\nconst USE_HINZE = true;\n\n/**\n * Constructs a snapshot node representing the passed JSON and returns it.\n * @param {*} json JSON to create a node for.\n * @param {?string|?number=} priority Optional priority to use. This will be ignored if the\n * passed JSON contains a .priority property.\n * @return {!Node}\n */\nexport function nodeFromJSON(json: any | null,\n priority: string | number | null = null): Node {\n if (json === null) {\n return ChildrenNode.EMPTY_NODE;\n }\n\n if (typeof json === 'object' && '.priority' in json) {\n priority = json['.priority'];\n }\n\n assert(\n priority === null ||\n typeof priority === 'string' ||\n typeof priority === 'number' ||\n (typeof priority === 'object' && '.sv' in (priority as object)),\n 'Invalid priority type found: ' + (typeof priority)\n );\n\n if (typeof json === 'object' && '.value' in json && json['.value'] !== null) {\n json = json['.value'];\n }\n\n // Valid leaf nodes include non-objects or server-value wrapper objects\n if (typeof json !== 'object' || '.sv' in json) {\n const jsonLeaf = json as string | number | boolean | object;\n return new LeafNode(jsonLeaf, nodeFromJSON(priority));\n }\n\n if (!(json instanceof Array) && USE_HINZE) {\n const children: NamedNode[] = [];\n let childrenHavePriority = false;\n const hinzeJsonObj: { [k: string]: any } = json as object;\n forEach(hinzeJsonObj, (key: string, child: any) => {\n if (typeof key !== 'string' || key.substring(0, 1) !== '.') { // Ignore metadata nodes\n const childNode = nodeFromJSON(hinzeJsonObj[key]);\n if (!childNode.isEmpty()) {\n childrenHavePriority = childrenHavePriority || !childNode.getPriority().isEmpty();\n children.push(new NamedNode(key, childNode));\n }\n }\n });\n\n if (children.length == 0) {\n return ChildrenNode.EMPTY_NODE;\n }\n\n const childSet = buildChildSet(children, NAME_ONLY_COMPARATOR,\n (namedNode) => namedNode.name, NAME_COMPARATOR) as SortedMap;\n if (childrenHavePriority) {\n const sortedChildSet = buildChildSet(children, PRIORITY_INDEX.getCompare());\n return new ChildrenNode(childSet, nodeFromJSON(priority),\n new IndexMap({'.priority': sortedChildSet}, {'.priority': PRIORITY_INDEX}));\n } else {\n return new ChildrenNode(childSet, nodeFromJSON(priority),\n IndexMap.Default);\n }\n } else {\n let node: Node = ChildrenNode.EMPTY_NODE;\n const jsonObj = json as object;\n forEach(jsonObj, (key: string, childData: any) => {\n if (contains(jsonObj, key)) {\n if (key.substring(0, 1) !== '.') { // ignore metadata nodes.\n const childNode = nodeFromJSON(childData);\n if (childNode.isLeafNode() || !childNode.isEmpty())\n node = node.updateImmediateChild(key, childNode);\n }\n }\n });\n\n return node.updatePriority(nodeFromJSON(priority));\n }\n}\n\nsetNodeFromJSON(nodeFromJSON);\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/nodeFromJSON.ts","/**\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\nimport { Index } from \"./Index\";\nimport { Node, NamedNode } from \"../Node\";\nimport { nameCompare, MAX_NAME } from \"../../util/util\";\nimport { assert, assertionError } from \"../../../../utils/assert\";\nimport { ChildrenNode } from \"../ChildrenNode\";\n\nlet __EMPTY_NODE: ChildrenNode;\n\nexport class KeyIndex extends Index {\n static get __EMPTY_NODE() {\n return __EMPTY_NODE;\n }\n\n static set __EMPTY_NODE(val) {\n __EMPTY_NODE = val;\n }\n\n /**\n * @inheritDoc\n */\n compare(a: NamedNode, b: NamedNode): number {\n return nameCompare(a.name, b.name);\n }\n\n /**\n * @inheritDoc\n */\n isDefinedOn(node: Node): boolean {\n // We could probably return true here (since every node has a key), but it's never called\n // so just leaving unimplemented for now.\n throw assertionError('KeyIndex.isDefinedOn not expected to be called.');\n }\n\n\n /**\n * @inheritDoc\n */\n indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n return false; // The key for a node never changes.\n }\n\n\n /**\n * @inheritDoc\n */\n minPost() {\n return (NamedNode as any).MIN;\n }\n\n\n /**\n * @inheritDoc\n */\n maxPost(): NamedNode {\n // TODO: This should really be created once and cached in a static property, but\n // NamedNode isn't defined yet, so I can't use it in a static. Bleh.\n return new NamedNode(MAX_NAME, __EMPTY_NODE);\n }\n\n\n /**\n * @param {*} indexValue\n * @param {string} name\n * @return {!NamedNode}\n */\n makePost(indexValue: string, name: string): NamedNode {\n assert(typeof indexValue === 'string', 'KeyIndex indexValue must always be a string.');\n // We just use empty node, but it'll never be compared, since our comparator only looks at name.\n return new NamedNode(indexValue, __EMPTY_NODE);\n }\n\n\n /**\n * @return {!string} String representation for inclusion in a query spec\n */\n toString(): string {\n return '.key';\n }\n}\n\nexport const KEY_INDEX = new KeyIndex();\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/indexes/KeyIndex.ts","/**\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\nimport { assert } from '../../../utils/assert';\nimport { \n doubleToIEEE754String,\n} from \"../util/util\";\nimport { contains } from \"../../../utils/obj\";\nimport { Node } from './Node';\n\nlet MAX_NODE: Node;\n\nexport function setMaxNode(val: Node) {\n MAX_NODE = val;\n}\n\n/**\n * @param {(!string|!number)} priority\n * @return {!string}\n */\nexport const priorityHashText = function(priority: string | number): string {\n if (typeof priority === 'number')\n return 'number:' + doubleToIEEE754String(priority);\n else\n return 'string:' + priority;\n};\n\n/**\n * Validates that a priority snapshot Node is valid.\n *\n * @param {!Node} priorityNode\n */\nexport const validatePriorityNode = function(priorityNode: Node) {\n if (priorityNode.isLeafNode()) {\n const val = priorityNode.val();\n assert(typeof val === 'string' || typeof val === 'number' ||\n (typeof val === 'object' && contains(val, '.sv')),\n 'Priority must be a string or number.');\n } else {\n assert(priorityNode === MAX_NODE || priorityNode.isEmpty(),\n 'priority of unexpected type.');\n }\n // Don't call getPriority() on MAX_NODE to avoid hitting assertion.\n assert(priorityNode === MAX_NODE || priorityNode.getPriority().isEmpty(),\n \"Priority nodes can't have a priority of their own.\");\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/snap.ts","/**\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\nimport { assert } from '../../../utils/assert'\nimport {\n doubleToIEEE754String,\n sha1\n} from '../util/util';\nimport {\n priorityHashText,\n validatePriorityNode\n} from './snap';\nimport { Node } from './Node';\nimport { Path } from '../util/Path';\nimport { Index } from './indexes/Index';\nimport { ChildrenNodeConstructor } from './ChildrenNode';\n\nlet __childrenNodeConstructor: ChildrenNodeConstructor;\n\n/**\n * LeafNode is a class for storing leaf nodes in a DataSnapshot. It\n * implements Node and stores the value of the node (a string,\n * number, or boolean) accessible via getValue().\n */\nexport class LeafNode implements Node {\n static set __childrenNodeConstructor(val: ChildrenNodeConstructor) {\n __childrenNodeConstructor = val;\n }\n\n static get __childrenNodeConstructor() {\n return __childrenNodeConstructor;\n }\n\n /**\n * The sort order for comparing leaf nodes of different types. If two leaf nodes have\n * the same type, the comparison falls back to their value\n * @type {Array.}\n * @const\n */\n static VALUE_TYPE_ORDER = ['object', 'boolean', 'number', 'string'];\n\n private lazyHash_: string | null = null;\n\n /**\n * @implements {Node}\n * @param {!(string|number|boolean|Object)} value_ The value to store in this leaf node.\n * The object type is possible in the event of a deferred value\n * @param {!Node=} priorityNode_ The priority of this node.\n */\n constructor(private readonly value_: string | number | boolean | object,\n private priorityNode_: Node = LeafNode.__childrenNodeConstructor.EMPTY_NODE) {\n assert(this.value_ !== undefined && this.value_ !== null,\n 'LeafNode shouldn\\'t be created with null/undefined value.');\n\n validatePriorityNode(this.priorityNode_);\n }\n\n /** @inheritDoc */\n isLeafNode(): boolean {\n return true;\n }\n\n /** @inheritDoc */\n getPriority(): Node {\n return this.priorityNode_;\n }\n\n /** @inheritDoc */\n updatePriority(newPriorityNode: Node): Node {\n return new LeafNode(this.value_, newPriorityNode);\n }\n\n /** @inheritDoc */\n getImmediateChild(childName: string): Node {\n // Hack to treat priority as a regular child\n if (childName === '.priority') {\n return this.priorityNode_;\n } else {\n return LeafNode.__childrenNodeConstructor.EMPTY_NODE;\n }\n }\n\n /** @inheritDoc */\n getChild(path: Path): Node {\n if (path.isEmpty()) {\n return this;\n } else if (path.getFront() === '.priority') {\n return this.priorityNode_;\n } else {\n return LeafNode.__childrenNodeConstructor.EMPTY_NODE;\n }\n }\n\n /**\n * @inheritDoc\n */\n hasChild(): boolean {\n return false;\n }\n\n /** @inheritDoc */\n getPredecessorChildName(childName: String, childNode: Node): null {\n return null;\n }\n\n /** @inheritDoc */\n updateImmediateChild(childName: string, newChildNode: Node): Node {\n if (childName === '.priority') {\n return this.updatePriority(newChildNode);\n } else if (newChildNode.isEmpty() && childName !== '.priority') {\n return this;\n } else {\n return LeafNode.__childrenNodeConstructor.EMPTY_NODE\n .updateImmediateChild(childName, newChildNode)\n .updatePriority(this.priorityNode_);\n }\n }\n\n /** @inheritDoc */\n updateChild(path: Path, newChildNode: Node): Node {\n const front = path.getFront();\n if (front === null) {\n return newChildNode;\n } else if (newChildNode.isEmpty() && front !== '.priority') {\n return this;\n } else {\n assert(front !== '.priority' || path.getLength() === 1,\n '.priority must be the last token in a path');\n\n return this.updateImmediateChild(front, LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(path.popFront(), newChildNode));\n }\n }\n\n /** @inheritDoc */\n isEmpty(): boolean {\n return false;\n }\n\n /** @inheritDoc */\n numChildren(): number {\n return 0;\n }\n\n /** @inheritDoc */\n forEachChild(index: Index, action: (s: string, n: Node) => void): any {\n return false;\n }\n\n /**\n * @inheritDoc\n */\n val(exportFormat?: boolean): Object {\n if (exportFormat && !this.getPriority().isEmpty())\n return {'.value': this.getValue(), '.priority': this.getPriority().val()};\n else\n return this.getValue();\n }\n\n /** @inheritDoc */\n hash(): string {\n if (this.lazyHash_ === null) {\n let toHash = '';\n if (!this.priorityNode_.isEmpty())\n toHash += 'priority:' + priorityHashText(\n (this.priorityNode_.val() as number|string)) + ':';\n\n const type = typeof this.value_;\n toHash += type + ':';\n if (type === 'number') {\n toHash += doubleToIEEE754String(this.value_ as number);\n } else {\n toHash += this.value_;\n }\n this.lazyHash_ = sha1(toHash);\n }\n return this.lazyHash_;\n }\n\n /**\n * Returns the value of the leaf node.\n * @return {Object|string|number|boolean} The value of the node.\n */\n getValue(): object | string | number | boolean {\n return this.value_;\n }\n\n /**\n * @inheritDoc\n */\n compareTo(other: Node): number {\n if (other === LeafNode.__childrenNodeConstructor.EMPTY_NODE) {\n return 1;\n } else if (other instanceof LeafNode.__childrenNodeConstructor) {\n return -1;\n } else {\n assert(other.isLeafNode(), 'Unknown node type');\n return this.compareToLeafNode_(other as LeafNode);\n }\n }\n\n /**\n * Comparison specifically for two leaf nodes\n * @param {!LeafNode} otherLeaf\n * @return {!number}\n * @private\n */\n private compareToLeafNode_(otherLeaf: LeafNode): number {\n const otherLeafType = typeof otherLeaf.value_;\n const thisLeafType = typeof this.value_;\n const otherIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(otherLeafType);\n const thisIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(thisLeafType);\n assert(otherIndex >= 0, 'Unknown leaf type: ' + otherLeafType);\n assert(thisIndex >= 0, 'Unknown leaf type: ' + thisLeafType);\n if (otherIndex === thisIndex) {\n // Same type, compare values\n if (thisLeafType === 'object') {\n // Deferred value nodes are all equal, but we should also never get to this point...\n return 0;\n } else {\n // Note that this works because true > false, all others are number or string comparisons\n if (this.value_ < otherLeaf.value_) {\n return -1;\n } else if (this.value_ === otherLeaf.value_) {\n return 0;\n } else {\n return 1;\n }\n }\n } else {\n return thisIndex - otherIndex;\n }\n }\n\n /**\n * @inheritDoc\n */\n withIndex(): Node {\n return this;\n }\n\n /**\n * @inheritDoc\n */\n isIndexed(): boolean {\n return true;\n }\n\n /**\n * @inheritDoc\n */\n equals(other: Node): boolean {\n /**\n * @inheritDoc\n */\n if (other === this) {\n return true;\n }\n else if (other.isLeafNode()) {\n const otherLeaf = other as LeafNode;\n return this.value_ === otherLeaf.value_ && this.priorityNode_.equals(otherLeaf.priorityNode_);\n } else {\n return false;\n }\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/LeafNode.ts","/**\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\nimport { nameCompare } from './util';\nimport { stringLength } from '../../../utils/utf8';\n/**\n * An immutable object representing a parsed path. It's immutable so that you\n * can pass them around to other functions without worrying about them changing\n * it.\n */\n\nexport class Path {\n private pieces_: string[];\n private pieceNum_: number;\n\n /**\n * Singleton to represent an empty path\n *\n * @const\n */\n static get Empty() {\n return new Path('');\n }\n\n /**\n * @param {string|Array.} pathOrString Path string to parse,\n * or another path, or the raw tokens array\n * @param {number=} pieceNum\n */\n constructor(pathOrString: string | string[], pieceNum?: number) {\n if (pieceNum === void 0) {\n this.pieces_ = (pathOrString as string).split('/');\n\n // Remove empty pieces.\n let copyTo = 0;\n for (let i = 0; i < this.pieces_.length; i++) {\n if (this.pieces_[i].length > 0) {\n this.pieces_[copyTo] = this.pieces_[i];\n copyTo++;\n }\n }\n this.pieces_.length = copyTo;\n\n this.pieceNum_ = 0;\n } else {\n this.pieces_ = pathOrString as string[];\n this.pieceNum_ = pieceNum;\n }\n }\n\n getFront(): string | null {\n if (this.pieceNum_ >= this.pieces_.length)\n return null;\n\n return this.pieces_[this.pieceNum_];\n }\n\n /**\n * @return {number} The number of segments in this path\n */\n getLength(): number {\n return this.pieces_.length - this.pieceNum_;\n }\n\n /**\n * @return {!Path}\n */\n popFront(): Path {\n let pieceNum = this.pieceNum_;\n if (pieceNum < this.pieces_.length) {\n pieceNum++;\n }\n return new Path(this.pieces_, pieceNum);\n }\n\n /**\n * @return {?string}\n */\n getBack(): string | null {\n if (this.pieceNum_ < this.pieces_.length)\n return this.pieces_[this.pieces_.length - 1];\n\n return null;\n }\n\n toString(): string {\n let pathString = '';\n for (let i = this.pieceNum_; i < this.pieces_.length; i++) {\n if (this.pieces_[i] !== '')\n pathString += '/' + this.pieces_[i];\n }\n\n return pathString || '/';\n }\n\n toUrlEncodedString(): string {\n let pathString = '';\n for (let i = this.pieceNum_; i < this.pieces_.length; i++) {\n if (this.pieces_[i] !== '')\n pathString += '/' + encodeURIComponent(String(this.pieces_[i]));\n }\n\n return pathString || '/';\n }\n\n /**\n * Shallow copy of the parts of the path.\n *\n * @param {number=} begin\n * @return {!Array}\n */\n slice(begin: number = 0): string[] {\n return this.pieces_.slice(this.pieceNum_ + begin);\n }\n\n /**\n * @return {?Path}\n */\n parent(): Path | null {\n if (this.pieceNum_ >= this.pieces_.length)\n return null;\n\n const pieces = [];\n for (let i = this.pieceNum_; i < this.pieces_.length - 1; i++)\n pieces.push(this.pieces_[i]);\n\n return new Path(pieces, 0);\n }\n\n /**\n * @param {string|!Path} childPathObj\n * @return {!Path}\n */\n child(childPathObj: string | Path): Path {\n const pieces = [];\n for (let i = this.pieceNum_; i < this.pieces_.length; i++)\n pieces.push(this.pieces_[i]);\n\n if (childPathObj instanceof Path) {\n for (let i = childPathObj.pieceNum_; i < childPathObj.pieces_.length; i++) {\n pieces.push(childPathObj.pieces_[i]);\n }\n } else {\n const childPieces = childPathObj.split('/');\n for (let i = 0; i < childPieces.length; i++) {\n if (childPieces[i].length > 0)\n pieces.push(childPieces[i]);\n }\n }\n\n return new Path(pieces, 0);\n }\n\n /**\n * @return {boolean} True if there are no segments in this path\n */\n isEmpty(): boolean {\n return this.pieceNum_ >= this.pieces_.length;\n }\n\n /**\n * @param {!Path} outerPath\n * @param {!Path} innerPath\n * @return {!Path} The path from outerPath to innerPath\n */\n static relativePath(outerPath: Path, innerPath: Path): Path {\n const outer = outerPath.getFront(), inner = innerPath.getFront();\n if (outer === null) {\n return innerPath;\n } else if (outer === inner) {\n return Path.relativePath(outerPath.popFront(),\n innerPath.popFront());\n } else {\n throw new Error('INTERNAL ERROR: innerPath (' + innerPath + ') is not within ' +\n 'outerPath (' + outerPath + ')');\n }\n }\n\n /**\n * @param {!Path} left\n * @param {!Path} right\n * @return {number} -1, 0, 1 if left is less, equal, or greater than the right.\n */\n static comparePaths(left: Path, right: Path): number {\n const leftKeys = left.slice();\n const rightKeys = right.slice();\n for (let i = 0; i < leftKeys.length && i < rightKeys.length; i++) {\n const cmp = nameCompare(leftKeys[i], rightKeys[i]);\n if (cmp !== 0) return cmp;\n }\n if (leftKeys.length === rightKeys.length) return 0;\n return (leftKeys.length < rightKeys.length) ? -1 : 1;\n }\n\n /**\n *\n * @param {Path} other\n * @return {boolean} true if paths are the same.\n */\n equals(other: Path): boolean {\n if (this.getLength() !== other.getLength()) {\n return false;\n }\n\n for (let i = this.pieceNum_, j = other.pieceNum_; i <= this.pieces_.length; i++, j++) {\n if (this.pieces_[i] !== other.pieces_[j]) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n *\n * @param {!Path} other\n * @return {boolean} True if this path is a parent (or the same as) other\n */\n contains(other: Path): boolean {\n let i = this.pieceNum_;\n let j = other.pieceNum_;\n if (this.getLength() > other.getLength()) {\n return false;\n }\n while (i < this.pieces_.length) {\n if (this.pieces_[i] !== other.pieces_[j]) {\n return false;\n }\n ++i;\n ++j;\n }\n return true;\n }\n} // end Path\n\n/**\n * Dynamic (mutable) path used to count path lengths.\n *\n * This class is used to efficiently check paths for valid\n * length (in UTF8 bytes) and depth (used in path validation).\n *\n * Throws Error exception if path is ever invalid.\n *\n * The definition of a path always begins with '/'.\n */\nexport class ValidationPath {\n /** @type {!Array} */\n private parts_: string[];\n /** @type {number} Initialize to number of '/' chars needed in path. */\n private byteLength_: number;\n\n /**\n * @param {!Path} path Initial Path.\n * @param {string} errorPrefix_ Prefix for any error messages.\n */\n constructor(path: Path, private errorPrefix_: string) {\n /** @type {!Array} */\n this.parts_ = path.slice();\n /** @type {number} Initialize to number of '/' chars needed in path. */\n this.byteLength_ = Math.max(1, this.parts_.length);\n\n for (let i = 0; i < this.parts_.length; i++) {\n this.byteLength_ += stringLength(this.parts_[i]);\n }\n this.checkValid_();\n }\n\n /** @const {number} Maximum key depth. */\n static get MAX_PATH_DEPTH() {\n return 32;\n }\n\n /** @const {number} Maximum number of (UTF8) bytes in a Firebase path. */\n static get MAX_PATH_LENGTH_BYTES() {\n return 768\n }\n\n /** @param {string} child */\n push(child: string) {\n // Count the needed '/'\n if (this.parts_.length > 0) {\n this.byteLength_ += 1;\n }\n this.parts_.push(child);\n this.byteLength_ += stringLength(child);\n this.checkValid_();\n }\n\n pop() {\n const last = this.parts_.pop();\n this.byteLength_ -= stringLength(last);\n // Un-count the previous '/'\n if (this.parts_.length > 0) {\n this.byteLength_ -= 1;\n }\n }\n\n private checkValid_() {\n if (this.byteLength_ > ValidationPath.MAX_PATH_LENGTH_BYTES) {\n throw new Error(this.errorPrefix_ + 'has a key path longer than ' +\n ValidationPath.MAX_PATH_LENGTH_BYTES + ' bytes (' +\n this.byteLength_ + ').');\n }\n if (this.parts_.length > ValidationPath.MAX_PATH_DEPTH) {\n throw new Error(this.errorPrefix_ + 'path specified exceeds the maximum depth that can be written (' +\n ValidationPath.MAX_PATH_DEPTH +\n ') or object contains a cycle ' + this.toErrorString());\n }\n }\n\n /**\n * String for use in error messages - uses '.' notation for path.\n *\n * @return {string}\n */\n toErrorString(): string {\n if (this.parts_.length == 0) {\n return '';\n }\n return 'in property \\'' + this.parts_.join('.') + '\\'';\n }\n\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/Path.ts","/**\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\nimport { assert } from '../../utils/assert';\nimport { forEach } from '../../utils/obj';\nimport { PersistentStorage } from './storage/storage';\nimport { LONG_POLLING, WEBSOCKET } from '../realtime/Constants';\n\n\n/**\n * A class that holds metadata about a Repo object\n *\n * @constructor\n */\nexport class RepoInfo {\n host: string;\n domain: string;\n internalHost: string;\n\n /**\n * @param {string} host Hostname portion of the url for the repo\n * @param {boolean} secure Whether or not this repo is accessed over ssl\n * @param {string} namespace The namespace represented by the repo\n * @param {boolean} webSocketOnly Whether to prefer websockets over all other transports (used by Nest).\n * @param {string=} persistenceKey Override the default session persistence storage key\n */\n constructor(host: string,public secure: boolean, public namespace: string,\n public webSocketOnly: boolean, public persistenceKey: string = '') {\n this.host = host.toLowerCase();\n this.domain = this.host.substr(this.host.indexOf('.') + 1);\n this.internalHost = PersistentStorage.get('host:' + host) || this.host;\n }\n\n needsQueryParam(): boolean {\n return this.host !== this.internalHost;\n }\n\n isCacheableHost(): boolean {\n return this.internalHost.substr(0, 2) === 's-';\n }\n\n isDemoHost() {\n return this.domain === 'firebaseio-demo.com';\n }\n\n isCustomHost() {\n return this.domain !== 'firebaseio.com' && this.domain !== 'firebaseio-demo.com';\n }\n\n updateHost(newHost: string) {\n if (newHost !== this.internalHost) {\n this.internalHost = newHost;\n if (this.isCacheableHost()) {\n PersistentStorage.set('host:' + this.host, this.internalHost);\n }\n }\n }\n\n /**\n * Returns the websocket URL for this repo\n * @param {string} type of connection\n * @param {Object} params list\n * @return {string} The URL for this repo\n */\n connectionURL(type: string, params: { [k: string]: string }): string {\n assert(typeof type === 'string', 'typeof type must == string');\n assert(typeof params === 'object', 'typeof params must == object');\n\n let connURL: string;\n if (type === WEBSOCKET) {\n connURL = (this.secure ? 'wss://' : 'ws://') + this.internalHost + '/.ws?';\n } else if (type === LONG_POLLING) {\n connURL = (this.secure ? 'https://' : 'http://') + this.internalHost + '/.lp?';\n } else {\n throw new Error('Unknown connection type: ' + type);\n }\n if (this.needsQueryParam()) {\n params['ns'] = this.namespace;\n }\n\n const pairs: string[] = [];\n\n forEach(params, (key: string, value: string) => {\n pairs.push(key + '=' + value);\n });\n\n return connURL + pairs.join('&');\n }\n\n /** @return {string} */\n toString(): string {\n let str = this.toURLString();\n if (this.persistenceKey) {\n str += '<' + this.persistenceKey + '>';\n }\n return str;\n }\n\n /** @return {string} */\n toURLString(): string {\n return (this.secure ? 'https://' : 'http://') + this.host;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/RepoInfo.ts","/**\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\nimport { Path, ValidationPath } from './Path';\nimport { forEach, contains, safeGet } from '../../../utils/obj';\nimport { isInvalidJSONNumber } from './util';\nimport { errorPrefix as errorPrefixFxn } from '../../../utils/validation';\nimport { stringLength } from '../../../utils/utf8';\nimport { RepoInfo } from '../RepoInfo';\n\n/**\n * True for invalid Firebase keys\n * @type {RegExp}\n * @private\n */\nexport const INVALID_KEY_REGEX_ = /[\\[\\].#$\\/\\u0000-\\u001F\\u007F]/;\n\n/**\n * True for invalid Firebase paths.\n * Allows '/' in paths.\n * @type {RegExp}\n * @private\n */\nexport const INVALID_PATH_REGEX_ = /[\\[\\].#$\\u0000-\\u001F\\u007F]/;\n\n/**\n * Maximum number of characters to allow in leaf value\n * @type {number}\n * @private\n */\nexport const MAX_LEAF_SIZE_ = 10 * 1024 * 1024;\n\n\n/**\n * @param {*} key\n * @return {boolean}\n */\nexport const isValidKey = function (key: any): boolean {\n return typeof key === 'string' && key.length !== 0 &&\n !INVALID_KEY_REGEX_.test(key);\n};\n\n/**\n * @param {string} pathString\n * @return {boolean}\n */\nexport const isValidPathString = function (pathString: string): boolean {\n return typeof pathString === 'string' && pathString.length !== 0 &&\n !INVALID_PATH_REGEX_.test(pathString);\n};\n\n/**\n * @param {string} pathString\n * @return {boolean}\n */\nexport const isValidRootPathString = function (pathString: string): boolean {\n if (pathString) {\n // Allow '/.info/' at the beginning.\n pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\n }\n\n return isValidPathString(pathString);\n};\n\n/**\n * @param {*} priority\n * @return {boolean}\n */\nexport const isValidPriority = function (priority: any): boolean {\n return priority === null ||\n typeof priority === 'string' ||\n (typeof priority === 'number' && !isInvalidJSONNumber(priority)) ||\n ((priority && typeof priority === 'object') && contains(priority, '.sv'));\n};\n\n/**\n * Pre-validate a datum passed as an argument to Firebase function.\n *\n * @param {string} fnName\n * @param {number} argumentNumber\n * @param {*} data\n * @param {!Path} path\n * @param {boolean} optional\n */\nexport const validateFirebaseDataArg = function (fnName: string, argumentNumber: number,\n data: any, path: Path, optional: boolean) {\n if (optional && data === undefined)\n return;\n\n validateFirebaseData(\n errorPrefixFxn(fnName, argumentNumber, optional),\n data, path\n );\n};\n\n/**\n * Validate a data object client-side before sending to server.\n *\n * @param {string} errorPrefix\n * @param {*} data\n * @param {!Path|!ValidationPath} path_\n */\nexport const validateFirebaseData = function (errorPrefix: string, data: any, path_: Path | ValidationPath) {\n const path = path_ instanceof Path\n ? new ValidationPath(path_, errorPrefix)\n : path_;\n\n if (data === undefined) {\n throw new Error(errorPrefix + 'contains undefined ' + path.toErrorString());\n }\n if (typeof data === 'function') {\n throw new Error(errorPrefix + 'contains a function ' + path.toErrorString() +\n ' with contents = ' + data.toString());\n }\n if (isInvalidJSONNumber(data)) {\n throw new Error(errorPrefix + 'contains ' + data.toString() + ' ' + path.toErrorString());\n }\n\n // Check max leaf size, but try to avoid the utf8 conversion if we can.\n if (typeof data === 'string' &&\n data.length > MAX_LEAF_SIZE_ / 3 &&\n stringLength(data) > MAX_LEAF_SIZE_) {\n throw new Error(errorPrefix + 'contains a string greater than ' +\n MAX_LEAF_SIZE_ +\n ' utf8 bytes ' + path.toErrorString() +\n ' (\\'' + data.substring(0, 50) + '...\\')');\n }\n\n // TODO = Perf = Consider combining the recursive validation of keys into NodeFromJSON\n // to save extra walking of large objects.\n if ((data && typeof data === 'object')) {\n let hasDotValue = false, hasActualChild = false;\n forEach(data, function (key: string, value: any) {\n if (key === '.value') {\n hasDotValue = true;\n }\n else if (key !== '.priority' && key !== '.sv') {\n hasActualChild = true;\n if (!isValidKey(key)) {\n throw new Error(errorPrefix + ' contains an invalid key (' + key + ') ' +\n path.toErrorString() +\n '. Keys must be non-empty strings ' +\n 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"');\n }\n }\n\n path.push(key);\n validateFirebaseData(errorPrefix, value, path);\n path.pop();\n });\n\n if (hasDotValue && hasActualChild) {\n throw new Error(errorPrefix + ' contains \".value\" child ' +\n path.toErrorString() +\n ' in addition to actual children.');\n }\n }\n};\n\n/**\n * Pre-validate paths passed in the firebase function.\n *\n * @param {string} errorPrefix\n * @param {Array} mergePaths\n */\nexport const validateFirebaseMergePaths = function (errorPrefix: string, mergePaths: Path[]) {\n let i, curPath;\n for (i = 0; i < mergePaths.length; i++) {\n curPath = mergePaths[i];\n const keys = curPath.slice();\n for (let j = 0; j < keys.length; j++) {\n if (keys[j] === '.priority' && j === (keys.length - 1)) {\n // .priority is OK\n } else if (!isValidKey(keys[j])) {\n throw new Error(errorPrefix + 'contains an invalid key (' + keys[j] + ') in path ' +\n curPath.toString() +\n '. Keys must be non-empty strings ' +\n 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"');\n }\n }\n }\n\n // Check that update keys are not descendants of each other.\n // We rely on the property that sorting guarantees that ancestors come\n // right before descendants.\n mergePaths.sort(Path.comparePaths);\n let prevPath: Path | null = null;\n for (i = 0; i < mergePaths.length; i++) {\n curPath = mergePaths[i];\n if (prevPath !== null && prevPath.contains(curPath)) {\n throw new Error(errorPrefix + 'contains a path ' + prevPath.toString() +\n ' that is ancestor of another path ' + curPath.toString());\n }\n prevPath = curPath;\n }\n};\n\n/**\n * pre-validate an object passed as an argument to firebase function (\n * must be an object - e.g. for firebase.update()).\n *\n * @param {string} fnName\n * @param {number} argumentNumber\n * @param {*} data\n * @param {!Path} path\n * @param {boolean} optional\n */\nexport const validateFirebaseMergeDataArg = function (fnName: string, argumentNumber: number,\n data: any, path: Path, optional: boolean) {\n if (optional && data === undefined)\n return;\n\n const errorPrefix = errorPrefixFxn(fnName, argumentNumber, optional);\n\n if (!(data && typeof data === 'object') || Array.isArray(data)) {\n throw new Error(errorPrefix + ' must be an object containing the children to replace.');\n }\n\n const mergePaths: Path[] = [];\n forEach(data, function (key: string, value: any) {\n const curPath = new Path(key);\n validateFirebaseData(errorPrefix, value, path.child(curPath));\n if (curPath.getBack() === '.priority') {\n if (!isValidPriority(value)) {\n throw new Error(\n errorPrefix + 'contains an invalid value for \\'' + curPath.toString() + '\\', which must be a valid ' +\n 'Firebase priority (a string, finite number, server value, or null).');\n }\n }\n mergePaths.push(curPath);\n });\n validateFirebaseMergePaths(errorPrefix, mergePaths);\n};\n\nexport const validatePriority = function (fnName: string, argumentNumber: number, priority: any, optional: boolean) {\n if (optional && priority === undefined)\n return;\n if (isInvalidJSONNumber(priority))\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'is ' + priority.toString() +\n ', but must be a valid Firebase priority (a string, finite number, ' +\n 'server value, or null).');\n // Special case to allow importing data with a .sv.\n if (!isValidPriority(priority))\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a valid Firebase priority ' +\n '(a string, finite number, server value, or null).');\n};\n\nexport const validateEventType = function (fnName: string, argumentNumber: number,\n eventType: string, optional: boolean) {\n if (optional && eventType === undefined)\n return;\n\n switch (eventType) {\n case 'value':\n case 'child_added':\n case 'child_removed':\n case 'child_changed':\n case 'child_moved':\n break;\n default:\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a valid event type = \"value\", \"child_added\", \"child_removed\", ' +\n '\"child_changed\", or \"child_moved\".');\n }\n};\n\nexport const validateKey = function (fnName: string, argumentNumber: number,\n key: string, optional: boolean) {\n if (optional && key === undefined)\n return;\n if (!isValidKey(key))\n throw new Error(errorPrefixFxn(fnName, argumentNumber, optional) +\n 'was an invalid key = \"' + key +\n '\". Firebase keys must be non-empty strings and ' +\n 'can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\").');\n};\n\nexport const validatePathString = function (fnName: string, argumentNumber: number,\n pathString: string, optional: boolean) {\n if (optional && pathString === undefined)\n return;\n\n if (!isValidPathString(pathString))\n throw new Error(errorPrefixFxn(fnName, argumentNumber, optional) +\n 'was an invalid path = \"' +\n pathString +\n '\". Paths must be non-empty strings and ' +\n 'can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\"');\n};\n\nexport const validateRootPathString = function (fnName: string, argumentNumber: number,\n pathString: string, optional: boolean) {\n if (pathString) {\n // Allow '/.info/' at the beginning.\n pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\n }\n\n validatePathString(fnName, argumentNumber, pathString, optional);\n};\n\nexport const validateWritablePath = function (fnName: string, path: Path) {\n if (path.getFront() === '.info') {\n throw new Error(fnName + ' failed = Can\\'t modify data under /.info/');\n }\n};\n\nexport const validateUrl = function (fnName: string, argumentNumber: number,\n parsedUrl: { repoInfo: RepoInfo, path: Path }) {\n // TODO = Validate server better.\n const pathString = parsedUrl.path.toString();\n if (!(typeof parsedUrl.repoInfo.host === 'string') || parsedUrl.repoInfo.host.length === 0 ||\n !isValidKey(parsedUrl.repoInfo.namespace) ||\n (pathString.length !== 0 && !isValidRootPathString(pathString))) {\n throw new Error(errorPrefixFxn(fnName, argumentNumber, false) +\n 'must be a valid firebase URL and ' +\n 'the path can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\".');\n }\n};\n\nexport const validateCredential = function (fnName: string, argumentNumber: number, cred: any, optional: boolean) {\n if (optional && cred === undefined)\n return;\n if (!(typeof cred === 'string'))\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a valid credential (a string).');\n};\n\nexport const validateBoolean = function (fnName: string, argumentNumber: number, bool: any, optional: boolean) {\n if (optional && bool === undefined)\n return;\n if (typeof bool !== 'boolean')\n throw new Error(errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a boolean.');\n};\n\nexport const validateString = function (fnName: string, argumentNumber: number, string: any, optional: boolean) {\n if (optional && string === undefined)\n return;\n if (!(typeof string === 'string')) {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a valid string.');\n }\n};\n\nexport const validateObject = function (fnName: string, argumentNumber: number, obj: any, optional: boolean) {\n if (optional && obj === undefined)\n return;\n if (!(obj && typeof obj === 'object') || obj === null) {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a valid object.');\n }\n};\n\nexport const validateObjectContainsKey = function (fnName: string, argumentNumber: number, obj: any, key: string, optional: boolean, opt_type?: string) {\n const objectContainsKey = ((obj && typeof obj === 'object') && contains(obj, key));\n\n if (!objectContainsKey) {\n if (optional) {\n return;\n } else {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must contain the key \"' + key + '\"');\n }\n }\n\n if (opt_type) {\n const val = safeGet(obj, key);\n if ((opt_type === 'number' && !(typeof val === 'number')) ||\n (opt_type === 'string' && !(typeof val === 'string')) ||\n (opt_type === 'boolean' && !(typeof val === 'boolean')) ||\n (opt_type === 'function' && !(typeof val === 'function')) ||\n (opt_type === 'object' && !(typeof val === 'object') && val)) {\n if (optional) {\n throw new Error(errorPrefixFxn(fnName, argumentNumber, optional) +\n 'contains invalid value for key \"' + key + '\" (must be of type \"' + opt_type + '\")');\n } else {\n throw new Error(errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must contain the key \"' + key + '\" with type \"' + opt_type + '\"');\n }\n }\n }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/validation.ts","/**\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\nimport {\n validateArgCount,\n validateCallback\n} from '../../utils/validation';\nimport {\n validateWritablePath,\n validateFirebaseDataArg,\n validatePriority,\n validateFirebaseMergeDataArg,\n} from '../core/util/validation';\nimport { warn } from '../core/util/util';\nimport { Deferred } from '../../utils/promise';\nimport { Repo } from '../core/Repo';\nimport { Path } from '../core/util/Path';\n\n/**\n * @constructor\n */\nexport class OnDisconnect {\n /**\n * @param {!Repo} repo_\n * @param {!Path} path_\n */\n constructor(private repo_: Repo,\n private path_: Path) {\n }\n\n /**\n * @param {function(?Error)=} onComplete\n * @return {!firebase.Promise}\n */\n cancel(onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('OnDisconnect.cancel', 0, 1, arguments.length);\n validateCallback('OnDisconnect.cancel', 1, onComplete, true);\n const deferred = new Deferred();\n this.repo_.onDisconnectCancel(this.path_, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {function(?Error)=} onComplete\n * @return {!firebase.Promise}\n */\n remove(onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('OnDisconnect.remove', 0, 1, arguments.length);\n validateWritablePath('OnDisconnect.remove', this.path_);\n validateCallback('OnDisconnect.remove', 1, onComplete, true);\n const deferred = new Deferred();\n this.repo_.onDisconnectSet(this.path_, null, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {*} value\n * @param {function(?Error)=} onComplete\n * @return {!firebase.Promise}\n */\n set(value: any, onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('OnDisconnect.set', 1, 2, arguments.length);\n validateWritablePath('OnDisconnect.set', this.path_);\n validateFirebaseDataArg('OnDisconnect.set', 1, value, this.path_, false);\n validateCallback('OnDisconnect.set', 2, onComplete, true);\n const deferred = new Deferred();\n this.repo_.onDisconnectSet(this.path_, value, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {*} value\n * @param {number|string|null} priority\n * @param {function(?Error)=} onComplete\n * @return {!firebase.Promise}\n */\n setWithPriority(value: any, priority: number | string | null, onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('OnDisconnect.setWithPriority', 2, 3, arguments.length);\n validateWritablePath('OnDisconnect.setWithPriority', this.path_);\n validateFirebaseDataArg('OnDisconnect.setWithPriority',\n 1, value, this.path_, false);\n validatePriority('OnDisconnect.setWithPriority', 2, priority, false);\n validateCallback('OnDisconnect.setWithPriority', 3, onComplete, true);\n\n const deferred = new Deferred();\n this.repo_.onDisconnectSetWithPriority(this.path_, value, priority, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {!Object} objectToMerge\n * @param {function(?Error)=} onComplete\n * @return {!firebase.Promise}\n */\n update(objectToMerge: object, onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('OnDisconnect.update', 1, 2, arguments.length);\n validateWritablePath('OnDisconnect.update', this.path_);\n if (Array.isArray(objectToMerge)) {\n const newObjectToMerge: { [k: string]: any } = {};\n for (let i = 0; i < objectToMerge.length; ++i) {\n newObjectToMerge['' + i] = objectToMerge[i];\n }\n objectToMerge = newObjectToMerge;\n warn(\n 'Passing an Array to firebase.database.onDisconnect().update() is deprecated. Use set() if you want to overwrite the ' +\n 'existing data, or an Object with integer keys if you really do want to only update some of the children.'\n );\n }\n validateFirebaseMergeDataArg('OnDisconnect.update', 1, objectToMerge,\n this.path_, false);\n validateCallback('OnDisconnect.update', 2, onComplete, true);\n const deferred = new Deferred();\n this.repo_.onDisconnectUpdate(this.path_, objectToMerge, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/onDisconnect.ts","/**\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\nimport { DataSnapshot } from './DataSnapshot';\n\nexport class TransactionResult {\n /**\n * A type for the resolve value of Firebase.transaction.\n * @constructor\n * @dict\n * @param {boolean} committed\n * @param {DataSnapshot} snapshot\n */\n constructor(public committed: boolean, public snapshot: DataSnapshot) {\n\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/TransactionResult.ts","/**\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\nimport { assert } from \"../../../utils/assert\";\n\n/**\n * Fancy ID generator that creates 20-character string identifiers with the\n * following properties:\n *\n * 1. They're based on timestamp so that they sort *after* any existing ids.\n * 2. They contain 72-bits of random data after the timestamp so that IDs won't\n * collide with other clients' IDs.\n * 3. They sort *lexicographically* (so the timestamp is converted to characters\n * that will sort properly).\n * 4. They're monotonically increasing. Even if you generate more than one in\n * the same timestamp, the latter ones will sort after the former ones. We do\n * this by using the previous random bits but \"incrementing\" them by 1 (only\n * in the case of a timestamp collision).\n */\nexport const nextPushId = (function() {\n // Modeled after base64 web-safe chars, but ordered by ASCII.\n const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';\n\n // Timestamp of last push, used to prevent local collisions if you push twice\n // in one ms.\n let lastPushTime = 0;\n\n // We generate 72-bits of randomness which get turned into 12 characters and\n // appended to the timestamp to prevent collisions with other clients. We\n // store the last characters we generated because in the event of a collision,\n // we'll use those same characters except \"incremented\" by one.\n const lastRandChars: number[] = [];\n\n return function(now: number) {\n const duplicateTime = (now === lastPushTime);\n lastPushTime = now;\n\n let i;\n const timeStampChars = new Array(8);\n for (i = 7; i >= 0; i--) {\n timeStampChars[i] = PUSH_CHARS.charAt(now % 64);\n // NOTE: Can't use << here because javascript will convert to int and lose\n // the upper bits.\n now = Math.floor(now / 64);\n }\n assert(now === 0, 'Cannot push at time == 0');\n\n let id = timeStampChars.join('');\n\n if (!duplicateTime) {\n for (i = 0; i < 12; i++) {\n lastRandChars[i] = Math.floor(Math.random() * 64);\n }\n } else {\n // If the timestamp hasn't changed since last push, use the same random\n // number, except incremented by 1.\n for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {\n lastRandChars[i] = 0;\n }\n lastRandChars[i]++;\n }\n for (i = 0; i < 12; i++) {\n id += PUSH_CHARS.charAt(lastRandChars[i]);\n }\n assert(id.length === 20, 'nextPushId: Length should be 20.');\n\n return id;\n };\n})();\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/NextPushId.ts","/**\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\nimport { Path } from \"../util/Path\";\nimport { Index } from \"./indexes/Index\";\n\n/**\n * Node is an interface defining the common functionality for nodes in\n * a DataSnapshot.\n *\n * @interface\n */\nexport interface Node {\n /**\n * Whether this node is a leaf node.\n * @return {boolean} Whether this is a leaf node.\n */\n isLeafNode(): boolean;\n\n\n /**\n * Gets the priority of the node.\n * @return {!Node} The priority of the node.\n */\n getPriority(): Node;\n\n\n /**\n * Returns a duplicate node with the new priority.\n * @param {!Node} newPriorityNode New priority to set for the node.\n * @return {!Node} Node with new priority.\n */\n updatePriority(newPriorityNode: Node): Node;\n\n\n /**\n * Returns the specified immediate child, or null if it doesn't exist.\n * @param {string} childName The name of the child to retrieve.\n * @return {!Node} The retrieved child, or an empty node.\n */\n getImmediateChild(childName: string): Node;\n\n\n /**\n * Returns a child by path, or null if it doesn't exist.\n * @param {!Path} path The path of the child to retrieve.\n * @return {!Node} The retrieved child or an empty node.\n */\n getChild(path: Path): Node;\n\n\n /**\n * Returns the name of the child immediately prior to the specified childNode, or null.\n * @param {!string} childName The name of the child to find the predecessor of.\n * @param {!Node} childNode The node to find the predecessor of.\n * @param {!Index} index The index to use to determine the predecessor\n * @return {?string} The name of the predecessor child, or null if childNode is the first child.\n */\n getPredecessorChildName(childName: String, childNode: Node, index: Index): string | null;\n\n /**\n * Returns a duplicate node, with the specified immediate child updated.\n * Any value in the node will be removed.\n * @param {string} childName The name of the child to update.\n * @param {!Node} newChildNode The new child node\n * @return {!Node} The updated node.\n */\n updateImmediateChild(childName: string, newChildNode: Node): Node;\n\n\n /**\n * Returns a duplicate node, with the specified child updated. Any value will\n * be removed.\n * @param {!Path} path The path of the child to update.\n * @param {!Node} newChildNode The new child node, which may be an empty node\n * @return {!Node} The updated node.\n */\n updateChild(path: Path, newChildNode: Node): Node;\n\n /**\n * True if the immediate child specified exists\n * @param {!string} childName\n * @return {boolean}\n */\n hasChild(childName: string): boolean;\n\n /**\n * @return {boolean} True if this node has no value or children.\n */\n isEmpty(): boolean;\n\n\n /**\n * @return {number} The number of children of this node.\n */\n numChildren(): number;\n\n\n /**\n * Calls action for each child.\n * @param {!Index} index\n * @param {function(string, !Node)} action Action to be called for\n * each child. It's passed the child name and the child node.\n * @return {*} The first truthy value return by action, or the last falsey one\n */\n forEachChild(index: Index, action: (a: string, b: Node) => void): any;\n\n /**\n * @param {boolean=} exportFormat True for export format (also wire protocol format).\n * @return {*} Value of this node as JSON.\n */\n val(exportFormat?: boolean): Object;\n\n /**\n * @return {string} hash representing the node contents.\n */\n hash(): string;\n\n /**\n * @param {!Node} other Another node\n * @return {!number} -1 for less than, 0 for equal, 1 for greater than other\n */\n compareTo(other: Node): number;\n\n /**\n * @param {!Node} other\n * @return {boolean} Whether or not this snapshot equals other\n */\n equals(other: Node): boolean;\n\n /**\n * @param {!Index} indexDefinition\n * @return {!Node} This node, with the specified index now available\n */\n withIndex(indexDefinition: Index): Node;\n\n /**\n * @param {!Index} indexDefinition\n * @return {boolean}\n */\n isIndexed(indexDefinition: Index): boolean;\n}\n\n/**\n *\n * @param {!string} name\n * @param {!Node} node\n * @constructor\n * @struct\n */\nexport class NamedNode {\n constructor(public name: string, public node: Node) {}\n\n /**\n *\n * @param {!string} name\n * @param {!Node} node\n * @return {NamedNode}\n */\n static Wrap(name: string, node: Node) {\n return new NamedNode(name, node);\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/Node.ts","/**\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\nimport { Node, NamedNode } from \"../Node\";\nimport { MIN_NAME, MAX_NAME } from \"../../util/util\";\nimport { Comparator } from '../../util/SortedMap';\n\n/**\n *\n * @constructor\n */\nexport abstract class Index {\n /**\n * @param {!NamedNode} a\n * @param {!NamedNode} b\n * @return {number}\n */\n abstract compare(a: NamedNode, b: NamedNode): number;\n\n /**\n * @param {!Node} node\n * @return {boolean}\n */\n abstract isDefinedOn(node: Node): boolean;\n\n\n /**\n * @return {function(!NamedNode, !NamedNode):number} A standalone comparison function for\n * this index\n */\n getCompare(): Comparator {\n return this.compare.bind(this);\n }\n\n\n /**\n * Given a before and after value for a node, determine if the indexed value has changed. Even if they are different,\n * it's possible that the changes are isolated to parts of the snapshot that are not indexed.\n *\n * @param {!Node} oldNode\n * @param {!Node} newNode\n * @return {boolean} True if the portion of the snapshot being indexed changed between oldNode and newNode\n */\n indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n const oldWrapped = new NamedNode(MIN_NAME, oldNode);\n const newWrapped = new NamedNode(MIN_NAME, newNode);\n return this.compare(oldWrapped, newWrapped) !== 0;\n }\n\n\n /**\n * @return {!NamedNode} a node wrapper that will sort equal to or less than\n * any other node wrapper, using this index\n */\n minPost(): NamedNode {\n return (NamedNode as any).MIN;\n }\n\n\n /**\n * @return {!NamedNode} a node wrapper that will sort greater than or equal to\n * any other node wrapper, using this index\n */\n abstract maxPost(): NamedNode;\n\n\n /**\n * @param {*} indexValue\n * @param {string} name\n * @return {!NamedNode}\n */\n abstract makePost(indexValue: any, name: string): NamedNode;\n\n\n /**\n * @return {!string} String representation for inclusion in a query spec\n */\n abstract toString(): string;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/indexes/Index.ts","/**\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\nimport { Index } from './Index';\nimport { nameCompare, MAX_NAME } from \"../../util/util\";\nimport { NamedNode, Node } from '../Node';\nimport { LeafNode } from \"../LeafNode\";\n\nlet nodeFromJSON: (a: any) => Node;\nlet MAX_NODE: Node;\n\nexport function setNodeFromJSON(val: (a: any) => Node) {\n nodeFromJSON = val;\n}\n\nexport function setMaxNode(val: Node) {\n MAX_NODE = val;\n}\n\n\n/**\n * @constructor\n * @extends {Index}\n * @private\n */\nexport class PriorityIndex extends Index {\n /**\n * @inheritDoc\n */\n compare(a: NamedNode, b: NamedNode): number {\n const aPriority = a.node.getPriority();\n const bPriority = b.node.getPriority();\n const indexCmp = aPriority.compareTo(bPriority);\n if (indexCmp === 0) {\n return nameCompare(a.name, b.name);\n } else {\n return indexCmp;\n }\n }\n\n\n /**\n * @inheritDoc\n */\n isDefinedOn(node: Node): boolean {\n return !node.getPriority().isEmpty();\n }\n\n\n /**\n * @inheritDoc\n */\n indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n return !oldNode.getPriority().equals(newNode.getPriority());\n }\n\n\n /**\n * @inheritDoc\n */\n minPost(): NamedNode {\n return (NamedNode as any).MIN;\n }\n\n\n /**\n * @inheritDoc\n */\n maxPost(): NamedNode {\n return new NamedNode(MAX_NAME, new LeafNode('[PRIORITY-POST]', MAX_NODE));\n }\n\n\n /**\n * @param {*} indexValue\n * @param {string} name\n * @return {!NamedNode}\n */\n makePost(indexValue: any, name: string): NamedNode {\n const priorityNode = nodeFromJSON(indexValue);\n return new NamedNode(name, new LeafNode('[PRIORITY-POST]', priorityNode));\n }\n\n\n /**\n * @return {!string} String representation for inclusion in a query spec\n */\n toString(): string {\n return '.priority';\n }\n}\n\nexport const PRIORITY_INDEX = new PriorityIndex();\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/indexes/PriorityIndex.ts","/**\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 Implementation of an immutable SortedMap using a Left-leaning\n * Red-Black Tree, adapted from the implementation in Mugs\n * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen\n * (mads379@gmail.com).\n *\n * Original paper on Left-leaning Red-Black Trees:\n * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf\n *\n * Invariant 1: No red node has a red child\n * Invariant 2: Every leaf path has the same number of black nodes\n * Invariant 3: Only the left child can be red (left leaning)\n */\n\n\n// TODO: There are some improvements I'd like to make to improve memory / perf:\n// * Create two prototypes, LLRedNode and LLBlackNode, instead of storing a\n// color property in every node.\n// TODO: It would also be good (and possibly necessary) to create a base\n// interface for LLRBNode and LLRBEmptyNode.\n\nexport type Comparator = (key1: K, key2: K) => number;\n\n/**\n * An iterator over an LLRBNode.\n */\nexport class SortedMapIterator {\n /** @private\n * @type {Array.}\n */\n private nodeStack_: (LLRBNode | LLRBEmptyNode)[] = [];\n\n /**\n * @template K, V, T\n * @param {LLRBNode|LLRBEmptyNode} node Node to iterate.\n * @param {?K} startKey\n * @param {function(K, K): number} comparator\n * @param {boolean} isReverse_ Whether or not to iterate in reverse\n * @param {(function(K, V):T)=} resultGenerator_\n */\n constructor(node: LLRBNode | LLRBEmptyNode,\n startKey: K | null,\n comparator: Comparator,\n private isReverse_: boolean,\n private resultGenerator_: ((k: K, v: V) => T) | null = null) {\n\n let cmp = 1;\n while (!node.isEmpty()) {\n node = node as LLRBNode;\n cmp = startKey ? comparator(node.key, startKey) : 1;\n // flip the comparison if we're going in reverse\n if (isReverse_) cmp *= -1;\n\n if (cmp < 0) {\n // This node is less than our start key. ignore it\n if (this.isReverse_) {\n node = node.left;\n } else {\n node = node.right;\n }\n } else if (cmp === 0) {\n // This node is exactly equal to our start key. Push it on the stack, but stop iterating;\n this.nodeStack_.push(node);\n break;\n } else {\n // This node is greater than our start key, add it to the stack and move to the next one\n this.nodeStack_.push(node);\n if (this.isReverse_) {\n node = node.right;\n } else {\n node = node.left;\n }\n }\n }\n }\n\n getNext(): T {\n if (this.nodeStack_.length === 0)\n return null;\n\n let node = this.nodeStack_.pop();\n let result: T;\n if (this.resultGenerator_)\n result = this.resultGenerator_(node.key, node.value);\n else\n result = {key: node.key, value: node.value} as any;\n\n if (this.isReverse_) {\n node = node.left;\n while (!node.isEmpty()) {\n this.nodeStack_.push(node);\n node = node.right;\n }\n } else {\n node = node.right;\n while (!node.isEmpty()) {\n this.nodeStack_.push(node);\n node = node.left;\n }\n }\n\n return result;\n }\n\n hasNext(): boolean {\n return this.nodeStack_.length > 0;\n }\n\n peek(): T {\n if (this.nodeStack_.length === 0)\n return null;\n\n const node = this.nodeStack_[this.nodeStack_.length - 1];\n if (this.resultGenerator_) {\n return this.resultGenerator_(node.key, node.value);\n } else {\n return {key: node.key, value: node.value} as any;\n }\n }\n}\n\n\n/**\n * Represents a node in a Left-leaning Red-Black tree.\n */\nexport class LLRBNode {\n color: boolean;\n left: LLRBNode | LLRBEmptyNode;\n right: LLRBNode | LLRBEmptyNode;\n\n /**\n * @template K, V\n * @param {!K} key Key associated with this node.\n * @param {!V} value Value associated with this node.\n * @param {?boolean} color Whether this node is red.\n * @param {?(LLRBNode|LLRBEmptyNode)=} left Left child.\n * @param {?(LLRBNode|LLRBEmptyNode)=} right Right child.\n */\n constructor(public key: K,\n public value: V,\n color: boolean | null,\n left?: LLRBNode | LLRBEmptyNode | null,\n right?: LLRBNode | LLRBEmptyNode | null) {\n this.color = color != null ? color : LLRBNode.RED;\n this.left = left != null ? left : SortedMap.EMPTY_NODE as LLRBEmptyNode;\n this.right = right != null ? right : SortedMap.EMPTY_NODE as LLRBEmptyNode;\n }\n\n static RED = true;\n static BLACK = false;\n\n /**\n * Returns a copy of the current node, optionally replacing pieces of it.\n *\n * @param {?K} key New key for the node, or null.\n * @param {?V} value New value for the node, or null.\n * @param {?boolean} color New color for the node, or null.\n * @param {?LLRBNode|LLRBEmptyNode} left New left child for the node, or null.\n * @param {?LLRBNode|LLRBEmptyNode} right New right child for the node, or null.\n * @return {!LLRBNode} The node copy.\n */\n copy(key: K | null, value: V | null, color: boolean | null,\n left: LLRBNode | LLRBEmptyNode | null,\n right: LLRBNode | LLRBEmptyNode | null): LLRBNode {\n return new LLRBNode(\n (key != null) ? key : this.key,\n (value != null) ? value : this.value,\n (color != null) ? color : this.color,\n (left != null) ? left : this.left,\n (right != null) ? right : this.right);\n }\n\n /**\n * @return {number} The total number of nodes in the tree.\n */\n count(): number {\n return this.left.count() + 1 + this.right.count();\n }\n\n /**\n * @return {boolean} True if the tree is empty.\n */\n isEmpty(): boolean {\n return false;\n }\n\n /**\n * Traverses the tree in key order and calls the specified action function\n * for each node.\n *\n * @param {function(!K, !V):*} action Callback function to be called for each\n * node. If it returns true, traversal is aborted.\n * @return {*} The first truthy value returned by action, or the last falsey\n * value returned by action\n */\n inorderTraversal(action: (k: K, v: V) => any): boolean {\n return this.left.inorderTraversal(action) ||\n action(this.key, this.value) ||\n this.right.inorderTraversal(action);\n }\n\n /**\n * Traverses the tree in reverse key order and calls the specified action function\n * for each node.\n *\n * @param {function(!Object, !Object)} action Callback function to be called for each\n * node. If it returns true, traversal is aborted.\n * @return {*} True if traversal was aborted.\n */\n reverseTraversal(action: (k: K, v: V) => void): boolean {\n return this.right.reverseTraversal(action) ||\n action(this.key, this.value) ||\n this.left.reverseTraversal(action);\n }\n\n /**\n * @return {!Object} The minimum node in the tree.\n * @private\n */\n private min_(): LLRBNode {\n if (this.left.isEmpty()) {\n return this;\n } else {\n return (this.left as LLRBNode).min_();\n }\n }\n\n /**\n * @return {!K} The maximum key in the tree.\n */\n minKey(): K {\n return this.min_().key;\n }\n\n /**\n * @return {!K} The maximum key in the tree.\n */\n maxKey(): K {\n if (this.right.isEmpty()) {\n return this.key;\n } else {\n return this.right.maxKey();\n }\n }\n\n /**\n *\n * @param {!Object} key Key to insert.\n * @param {!Object} value Value to insert.\n * @param {Comparator} comparator Comparator.\n * @return {!LLRBNode} New tree, with the key/value added.\n */\n insert(key: K, value: V, comparator: Comparator): LLRBNode {\n let cmp, n;\n n = this;\n cmp = comparator(key, n.key);\n if (cmp < 0) {\n n = n.copy(null, null, null, n.left.insert(key, value, comparator), null);\n } else if (cmp === 0) {\n n = n.copy(null, value, null, null, null);\n } else {\n n = n.copy(null, null, null, null, n.right.insert(key, value, comparator));\n }\n return n.fixUp_();\n }\n\n /**\n * @private\n * @return {!LLRBNode|LLRBEmptyNode} New tree, with the minimum key removed.\n */\n private removeMin_(): LLRBNode | LLRBEmptyNode {\n if (this.left.isEmpty()) {\n return SortedMap.EMPTY_NODE as LLRBEmptyNode;\n }\n let n: LLRBNode = this;\n if (!n.left.isRed_() && !n.left.left.isRed_())\n n = n.moveRedLeft_();\n n = n.copy(null, null, null, (n.left as LLRBNode).removeMin_(), null);\n return n.fixUp_();\n }\n\n /**\n * @param {!Object} key The key of the item to remove.\n * @param {Comparator} comparator Comparator.\n * @return {!LLRBNode|LLRBEmptyNode} New tree, with the specified item removed.\n */\n remove(key: K, comparator: Comparator): LLRBNode | LLRBEmptyNode {\n let n, smallest;\n n = this;\n if (comparator(key, n.key) < 0) {\n if (!n.left.isEmpty() && !n.left.isRed_() && !n.left.left.isRed_()) {\n n = n.moveRedLeft_();\n }\n n = n.copy(null, null, null, n.left.remove(key, comparator), null);\n } else {\n if (n.left.isRed_()) n = n.rotateRight_();\n if (!n.right.isEmpty() && !n.right.isRed_() && !n.right.left.isRed_()) {\n n = n.moveRedRight_();\n }\n if (comparator(key, n.key) === 0) {\n if (n.right.isEmpty()) {\n return SortedMap.EMPTY_NODE as LLRBEmptyNode;\n } else {\n smallest = (n.right as LLRBNode).min_();\n n = n.copy(smallest.key, smallest.value, null, null,\n (n.right as LLRBNode).removeMin_());\n }\n }\n n = n.copy(null, null, null, null, n.right.remove(key, comparator));\n }\n return n.fixUp_();\n }\n\n /**\n * @private\n * @return {boolean} Whether this is a RED node.\n */\n isRed_(): boolean {\n return this.color;\n }\n\n /**\n * @private\n * @return {!LLRBNode} New tree after performing any needed rotations.\n */\n private fixUp_(): LLRBNode {\n let n = this as any;\n if (n.right.isRed_() && !n.left.isRed_()) n = n.rotateLeft_();\n if (n.left.isRed_() && n.left.left.isRed_()) n = n.rotateRight_();\n if (n.left.isRed_() && n.right.isRed_()) n = n.colorFlip_();\n return n;\n }\n\n /**\n * @private\n * @return {!LLRBNode} New tree, after moveRedLeft.\n */\n private moveRedLeft_(): LLRBNode {\n let n = this.colorFlip_();\n if (n.right.left.isRed_()) {\n n = n.copy(null, null, null, null, (n.right as LLRBNode).rotateRight_());\n n = n.rotateLeft_();\n n = n.colorFlip_();\n }\n return n;\n }\n\n /**\n * @private\n * @return {!LLRBNode} New tree, after moveRedRight.\n */\n private moveRedRight_(): LLRBNode {\n let n = this.colorFlip_();\n if (n.left.left.isRed_()) {\n n = n.rotateRight_();\n n = n.colorFlip_();\n }\n return n;\n }\n\n /**\n * @private\n * @return {!LLRBNode} New tree, after rotateLeft.\n */\n private rotateLeft_(): LLRBNode {\n const nl = this.copy(null, null, LLRBNode.RED, null, this.right.left);\n return this.right.copy(null, null, this.color, nl, null) as LLRBNode;\n }\n\n /**\n * @private\n * @return {!LLRBNode} New tree, after rotateRight.\n */\n private rotateRight_(): LLRBNode {\n const nr = this.copy(null, null, LLRBNode.RED, this.left.right, null);\n return this.left.copy(null, null, this.color, null, nr) as LLRBNode;\n }\n\n /**\n * @private\n * @return {!LLRBNode} New tree, after colorFlip.\n */\n private colorFlip_(): LLRBNode {\n const left = this.left.copy(null, null, !this.left.color, null, null);\n const right = this.right.copy(null, null, !this.right.color, null, null);\n return this.copy(null, null, !this.color, left, right);\n }\n\n /**\n * For testing.\n *\n * @private\n * @return {boolean} True if all is well.\n */\n private checkMaxDepth_(): boolean {\n const blackDepth = this.check_();\n return (Math.pow(2.0, blackDepth) <= this.count() + 1);\n }\n\n /**\n * @private\n * @return {number} Not sure what this returns exactly. :-).\n */\n check_(): number {\n let blackDepth;\n if (this.isRed_() && this.left.isRed_()) {\n throw new Error('Red node has red child(' + this.key + ',' +\n this.value + ')');\n }\n if (this.right.isRed_()) {\n throw new Error('Right child of (' + this.key + ',' +\n this.value + ') is red');\n }\n blackDepth = this.left.check_();\n if (blackDepth !== this.right.check_()) {\n throw new Error('Black depths differ');\n } else {\n return blackDepth + (this.isRed_() ? 0 : 1);\n }\n }\n}\n\n\n/**\n * Represents an empty node (a leaf node in the Red-Black Tree).\n */\nexport class LLRBEmptyNode {\n key: K;\n value: V;\n left: LLRBNode | LLRBEmptyNode;\n right: LLRBNode | LLRBEmptyNode;\n color: boolean;\n\n /**\n * Returns a copy of the current node.\n *\n * @return {!LLRBEmptyNode} The node copy.\n */\n copy(key: K | null, value: V | null, color: boolean | null,\n left: LLRBNode | LLRBEmptyNode | null,\n right: LLRBNode | LLRBEmptyNode | null): LLRBEmptyNode {\n return this;\n }\n\n /**\n * Returns a copy of the tree, with the specified key/value added.\n *\n * @param {!K} key Key to be added.\n * @param {!V} value Value to be added.\n * @param {Comparator} comparator Comparator.\n * @return {!LLRBNode} New tree, with item added.\n */\n insert(key: K, value: V, comparator: Comparator): LLRBNode {\n return new LLRBNode(key, value, null);\n }\n\n /**\n * Returns a copy of the tree, with the specified key removed.\n *\n * @param {!K} key The key to remove.\n * @param {Comparator} comparator Comparator.\n * @return {!LLRBEmptyNode} New tree, with item removed.\n */\n remove(key: K, comparator: Comparator): LLRBEmptyNode {\n return this;\n }\n\n /**\n * @return {number} The total number of nodes in the tree.\n */\n count(): number {\n return 0;\n }\n\n /**\n * @return {boolean} True if the tree is empty.\n */\n isEmpty(): boolean {\n return true;\n }\n\n /**\n * Traverses the tree in key order and calls the specified action function\n * for each node.\n *\n * @param {function(!K, !V):*} action Callback function to be called for each\n * node. If it returns true, traversal is aborted.\n * @return {boolean} True if traversal was aborted.\n */\n inorderTraversal(action: (k: K, v: V) => any): boolean {\n return false;\n }\n\n /**\n * Traverses the tree in reverse key order and calls the specified action function\n * for each node.\n *\n * @param {function(!K, !V)} action Callback function to be called for each\n * node. If it returns true, traversal is aborted.\n * @return {boolean} True if traversal was aborted.\n */\n reverseTraversal(action: (k: K, v: V) => void): boolean {\n return false;\n }\n\n /**\n * @return {null}\n */\n minKey(): null {\n return null;\n }\n\n /**\n * @return {null}\n */\n maxKey(): null {\n return null;\n }\n\n /**\n * @private\n * @return {number} Not sure what this returns exactly. :-).\n */\n check_(): number {\n return 0;\n }\n\n /**\n * @private\n * @return {boolean} Whether this node is red.\n */\n isRed_() {\n return false;\n }\n}\n\n/**\n * An immutable sorted map implementation, based on a Left-leaning Red-Black\n * tree.\n */\nexport class SortedMap {\n /**\n * Always use the same empty node, to reduce memory.\n * @const\n */\n static EMPTY_NODE = new LLRBEmptyNode();\n\n /**\n * @template K, V\n * @param {function(K, K):number} comparator_ Key comparator.\n * @param {LLRBNode=} root_ (Optional) Root node for the map.\n */\n constructor(private comparator_: Comparator,\n private root_: LLRBNode | LLRBEmptyNode = SortedMap.EMPTY_NODE as LLRBEmptyNode) {\n }\n\n /**\n * Returns a copy of the map, with the specified key/value added or replaced.\n * (TODO: We should perhaps rename this method to 'put')\n *\n * @param {!K} key Key to be added.\n * @param {!V} value Value to be added.\n * @return {!SortedMap.} New map, with item added.\n */\n insert(key: K, value: V): SortedMap {\n return new SortedMap(\n this.comparator_,\n this.root_.insert(key, value, this.comparator_)\n .copy(null, null, LLRBNode.BLACK, null, null));\n }\n\n /**\n * Returns a copy of the map, with the specified key removed.\n *\n * @param {!K} key The key to remove.\n * @return {!SortedMap.} New map, with item removed.\n */\n remove(key: K): SortedMap {\n return new SortedMap(\n this.comparator_,\n this.root_.remove(key, this.comparator_)\n .copy(null, null, LLRBNode.BLACK, null, null));\n }\n\n /**\n * Returns the value of the node with the given key, or null.\n *\n * @param {!K} key The key to look up.\n * @return {?V} The value of the node with the given key, or null if the\n * key doesn't exist.\n */\n get(key: K): V | null {\n let cmp;\n let node = this.root_;\n while (!node.isEmpty()) {\n cmp = this.comparator_(key, node.key);\n if (cmp === 0) {\n return node.value;\n } else if (cmp < 0) {\n node = node.left;\n } else if (cmp > 0) {\n node = node.right;\n }\n }\n return null;\n }\n\n /**\n * Returns the key of the item *before* the specified key, or null if key is the first item.\n * @param {K} key The key to find the predecessor of\n * @return {?K} The predecessor key.\n */\n getPredecessorKey(key: K): K | null {\n let cmp, node = this.root_, rightParent = null;\n while (!node.isEmpty()) {\n cmp = this.comparator_(key, node.key);\n if (cmp === 0) {\n if (!node.left.isEmpty()) {\n node = node.left;\n while (!node.right.isEmpty())\n node = node.right;\n return node.key;\n } else if (rightParent) {\n return rightParent.key;\n } else {\n return null; // first item.\n }\n } else if (cmp < 0) {\n node = node.left;\n } else if (cmp > 0) {\n rightParent = node;\n node = node.right;\n }\n }\n\n throw new Error('Attempted to find predecessor key for a nonexistent key. What gives?');\n }\n\n /**\n * @return {boolean} True if the map is empty.\n */\n isEmpty(): boolean {\n return this.root_.isEmpty();\n }\n\n /**\n * @return {number} The total number of nodes in the map.\n */\n count(): number {\n return this.root_.count();\n }\n\n /**\n * @return {?K} The minimum key in the map.\n */\n minKey(): K | null {\n return this.root_.minKey();\n }\n\n /**\n * @return {?K} The maximum key in the map.\n */\n maxKey(): K | null {\n return this.root_.maxKey();\n }\n\n /**\n * Traverses the map in key order and calls the specified action function\n * for each key/value pair.\n *\n * @param {function(!K, !V):*} action Callback function to be called\n * for each key/value pair. If action returns true, traversal is aborted.\n * @return {*} The first truthy value returned by action, or the last falsey\n * value returned by action\n */\n inorderTraversal(action: (k: K, v: V) => any): boolean {\n return this.root_.inorderTraversal(action);\n }\n\n /**\n * Traverses the map in reverse key order and calls the specified action function\n * for each key/value pair.\n *\n * @param {function(!Object, !Object)} action Callback function to be called\n * for each key/value pair. If action returns true, traversal is aborted.\n * @return {*} True if the traversal was aborted.\n */\n reverseTraversal(action: (k: K, v: V) => void): boolean {\n return this.root_.reverseTraversal(action);\n }\n\n /**\n * Returns an iterator over the SortedMap.\n * @template T\n * @param {(function(K, V):T)=} resultGenerator\n * @return {SortedMapIterator.} The iterator.\n */\n getIterator(resultGenerator?: (k: K, v: V) => T): SortedMapIterator {\n return new SortedMapIterator(this.root_,\n null,\n this.comparator_,\n false,\n resultGenerator);\n }\n\n getIteratorFrom(key: K, resultGenerator?: (k: K, v: V) => T): SortedMapIterator {\n return new SortedMapIterator(this.root_,\n key,\n this.comparator_,\n false,\n resultGenerator);\n }\n\n getReverseIteratorFrom(key: K, resultGenerator?: (k: K, v: V) => T): SortedMapIterator {\n return new SortedMapIterator(this.root_,\n key,\n this.comparator_,\n true,\n resultGenerator);\n }\n\n getReverseIterator(resultGenerator?: (k: K, v: V) => T): SortedMapIterator {\n return new SortedMapIterator(this.root_,\n null,\n this.comparator_,\n true,\n resultGenerator);\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/SortedMap.ts","/**\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\nimport { LLRBNode } from '../util/SortedMap';\nimport { SortedMap } from '../util/SortedMap';\nimport { NamedNode } from './Node';\n\nconst LOG_2 = Math.log(2);\n\n/**\n * @constructor\n */\nclass Base12Num {\n count: number;\n private current_: number;\n private bits_: number;\n\n /**\n * @param {number} length\n */\n constructor(length: number) {\n const logBase2 = (num: number) => parseInt((Math.log(num) / LOG_2 as any), 10);\n const bitMask = (bits: number) => parseInt(Array(bits + 1).join('1'), 2);\n this.count = logBase2(length + 1);\n this.current_ = this.count - 1;\n const mask = bitMask(this.count);\n this.bits_ = (length + 1) & mask;\n }\n\n /**\n * @return {boolean}\n */\n nextBitIsOne(): boolean {\n //noinspection JSBitwiseOperatorUsage\n const result = !(this.bits_ & (0x1 << this.current_));\n this.current_--;\n return result;\n }\n}\n\n/**\n * Takes a list of child nodes and constructs a SortedSet using the given comparison\n * function\n *\n * Uses the algorithm described in the paper linked here:\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.1458\n *\n * @template K, V\n * @param {Array.} childList Unsorted list of children\n * @param {function(!NamedNode, !NamedNode):number} cmp The comparison method to be used\n * @param {(function(NamedNode):K)=} keyFn An optional function to extract K from a node wrapper, if K's\n * type is not NamedNode\n * @param {(function(K, K):number)=} mapSortFn An optional override for comparator used by the generated sorted map\n * @return {SortedMap.}\n */\nexport const buildChildSet = function(childList: NamedNode[],\n cmp: (a: NamedNode, b: NamedNode) => number,\n keyFn?: (a: NamedNode) => K,\n mapSortFn?: (a: K, b: K) => number): SortedMap {\n childList.sort(cmp);\n\n const buildBalancedTree = function(low: number, high: number): LLRBNode | null {\n const length = high - low;\n let namedNode: NamedNode;\n let key: K;\n if (length == 0) {\n return null;\n } else if (length == 1) {\n namedNode = childList[low];\n key = keyFn ? keyFn(namedNode) : namedNode as any as K;\n return new LLRBNode(key, namedNode.node as any as V, LLRBNode.BLACK, null, null);\n } else {\n const middle = parseInt((length / 2 as any), 10) + low;\n const left = buildBalancedTree(low, middle);\n const right = buildBalancedTree(middle + 1, high);\n namedNode = childList[middle];\n key = keyFn ? keyFn(namedNode) : namedNode as any as K;\n return new LLRBNode(key, namedNode.node as any as V, LLRBNode.BLACK, left, right);\n }\n };\n\n const buildFrom12Array = function (base12: Base12Num): LLRBNode {\n let node: LLRBNode = null;\n let root = null;\n let index = childList.length;\n\n const buildPennant = function (chunkSize: number, color: boolean) {\n const low = index - chunkSize;\n const high = index;\n index -= chunkSize;\n const childTree = buildBalancedTree(low + 1, high);\n const namedNode = childList[low];\n const key: K = keyFn ? keyFn(namedNode) : namedNode as any as K;\n attachPennant(new LLRBNode(key, namedNode.node as any as V, color, null, childTree));\n };\n\n const attachPennant = function (pennant: LLRBNode) {\n if (node) {\n node.left = pennant;\n node = pennant;\n } else {\n root = pennant;\n node = pennant;\n }\n };\n\n for (let i = 0; i < base12.count; ++i) {\n const isOne = base12.nextBitIsOne();\n // The number of nodes taken in each slice is 2^(arr.length - (i + 1))\n const chunkSize = Math.pow(2, base12.count - (i + 1));\n if (isOne) {\n buildPennant(chunkSize, LLRBNode.BLACK);\n } else {\n // current == 2\n buildPennant(chunkSize, LLRBNode.BLACK);\n buildPennant(chunkSize, LLRBNode.RED);\n }\n }\n return root;\n };\n\n const base12 = new Base12Num(childList.length);\n const root = buildFrom12Array(base12);\n\n return new SortedMap(mapSortFn || (cmp as any), root);\n};\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/childSet.ts","/**\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\nimport { assert } from '../../../utils/assert';\nimport { buildChildSet } from './childSet';\nimport { contains, clone, map, safeGet } from '../../../utils/obj';\nimport { NamedNode, Node } from './Node';\nimport { PRIORITY_INDEX } from './indexes/PriorityIndex';\nimport { KEY_INDEX } from './indexes/KeyIndex';\nimport { SortedMap } from '../util/SortedMap';\nimport { Index } from './indexes/Index';\n\nlet _defaultIndexMap: IndexMap;\n\nconst fallbackObject = {};\n\n/**\n *\n * @param {Object.>} indexes\n * @param {Object.} indexSet\n * @constructor\n */\nexport class IndexMap {\n /**\n * The default IndexMap for nodes without a priority\n * @type {!IndexMap}\n * @const\n */\n static get Default(): IndexMap {\n assert(fallbackObject && PRIORITY_INDEX, 'ChildrenNode.ts has not been loaded');\n _defaultIndexMap = _defaultIndexMap || new IndexMap(\n {'.priority': fallbackObject},\n {'.priority': PRIORITY_INDEX}\n );\n return _defaultIndexMap;\n }\n\n constructor(private indexes_: { [k: string]: SortedMap | /*FallbackType*/object },\n private indexSet_: { [k: string]: Index }) {\n }\n\n /**\n *\n * @param {!string} indexKey\n * @return {?SortedMap.}\n */\n get(indexKey: string): SortedMap | null {\n const sortedMap = safeGet(this.indexes_, indexKey);\n if (!sortedMap) throw new Error('No index defined for ' + indexKey);\n\n if (sortedMap === fallbackObject) {\n // The index exists, but it falls back to just name comparison. Return null so that the calling code uses the\n // regular child map\n return null;\n } else {\n return sortedMap;\n }\n }\n\n /**\n * @param {!Index} indexDefinition\n * @return {boolean}\n */\n hasIndex(indexDefinition: Index): boolean {\n return contains(this.indexSet_, indexDefinition.toString());\n }\n\n /**\n * @param {!Index} indexDefinition\n * @param {!SortedMap.} existingChildren\n * @return {!IndexMap}\n */\n addIndex(indexDefinition: Index, existingChildren: SortedMap): IndexMap {\n assert(indexDefinition !== KEY_INDEX,\n 'KeyIndex always exists and isn\\'t meant to be added to the IndexMap.');\n const childList = [];\n let sawIndexedValue = false;\n const iter = existingChildren.getIterator(NamedNode.Wrap);\n let next = iter.getNext();\n while (next) {\n sawIndexedValue = sawIndexedValue || indexDefinition.isDefinedOn(next.node);\n childList.push(next);\n next = iter.getNext();\n }\n let newIndex;\n if (sawIndexedValue) {\n newIndex = buildChildSet(childList, indexDefinition.getCompare());\n } else {\n newIndex = fallbackObject;\n }\n const indexName = indexDefinition.toString();\n const newIndexSet = clone(this.indexSet_);\n newIndexSet[indexName] = indexDefinition;\n const newIndexes = clone(this.indexes_);\n newIndexes[indexName] = newIndex;\n return new IndexMap(newIndexes, newIndexSet);\n }\n\n\n /**\n * Ensure that this node is properly tracked in any indexes that we're maintaining\n * @param {!NamedNode} namedNode\n * @param {!SortedMap.} existingChildren\n * @return {!IndexMap}\n */\n addToIndexes(namedNode: NamedNode, existingChildren: SortedMap): IndexMap {\n const newIndexes = map(this.indexes_, (indexedChildren: SortedMap, indexName: string) => {\n const index = safeGet(this.indexSet_, indexName);\n assert(index, 'Missing index implementation for ' + indexName);\n if (indexedChildren === fallbackObject) {\n // Check to see if we need to index everything\n if (index.isDefinedOn(namedNode.node)) {\n // We need to build this index\n const childList = [];\n const iter = existingChildren.getIterator(NamedNode.Wrap);\n let next = iter.getNext();\n while (next) {\n if (next.name != namedNode.name) {\n childList.push(next);\n }\n next = iter.getNext();\n }\n childList.push(namedNode);\n return buildChildSet(childList, index.getCompare());\n } else {\n // No change, this remains a fallback\n return fallbackObject;\n }\n } else {\n const existingSnap = existingChildren.get(namedNode.name);\n let newChildren = indexedChildren;\n if (existingSnap) {\n newChildren = newChildren.remove(new NamedNode(namedNode.name, existingSnap));\n }\n return newChildren.insert(namedNode, namedNode.node);\n }\n });\n return new IndexMap(newIndexes, this.indexSet_);\n }\n\n /**\n * Create a new IndexMap instance with the given value removed\n * @param {!NamedNode} namedNode\n * @param {!SortedMap.} existingChildren\n * @return {!IndexMap}\n */\n removeFromIndexes(namedNode: NamedNode, existingChildren: SortedMap): IndexMap {\n const newIndexes = map(this.indexes_, function (indexedChildren: SortedMap) {\n if (indexedChildren === fallbackObject) {\n // This is the fallback. Just return it, nothing to do in this case\n return indexedChildren;\n } else {\n const existingSnap = existingChildren.get(namedNode.name);\n if (existingSnap) {\n return indexedChildren.remove(new NamedNode(namedNode.name, existingSnap));\n } else {\n // No record of this child\n return indexedChildren;\n }\n }\n });\n return new IndexMap(newIndexes, this.indexSet_);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/IndexMap.ts","/**\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\nimport { assert } from \"../../../utils/assert\";\nimport {\n sha1,\n MAX_NAME,\n MIN_NAME\n} from '../util/util';\nimport { SortedMap, SortedMapIterator } from '../util/SortedMap';\nimport { Node, NamedNode } from './Node';\nimport {\n validatePriorityNode,\n priorityHashText,\n setMaxNode\n} from './snap';\nimport { PRIORITY_INDEX, setMaxNode as setPriorityMaxNode } from './indexes/PriorityIndex';\nimport { KEY_INDEX, KeyIndex } from './indexes/KeyIndex';\nimport { IndexMap } from './IndexMap';\nimport { LeafNode } from './LeafNode';\nimport { NAME_COMPARATOR } from './comparators';\nimport { Index } from './indexes/Index';\nimport { Path } from '../util/Path';\n\nexport interface ChildrenNodeConstructor {\n new(children_: SortedMap, priorityNode_: Node | null, indexMap_: IndexMap): ChildrenNode;\n EMPTY_NODE: ChildrenNode;\n}\n\n// TODO: For memory savings, don't store priorityNode_ if it's empty.\n\nlet EMPTY_NODE: ChildrenNode;\n\n/**\n * ChildrenNode is a class for storing internal nodes in a DataSnapshot\n * (i.e. nodes with children). It implements Node and stores the\n * list of children in the children property, sorted by child name.\n *\n * @constructor\n * @implements {Node}\n */\nexport class ChildrenNode implements Node {\n private lazyHash_: string | null = null;\n\n static get EMPTY_NODE(): ChildrenNode {\n return EMPTY_NODE || (EMPTY_NODE = new ChildrenNode(new SortedMap(NAME_COMPARATOR), null, IndexMap.Default));\n }\n\n /**\n *\n * @param {!SortedMap.} children_ List of children\n * of this node..\n * @param {?Node} priorityNode_ The priority of this node (as a snapshot node).\n * @param {!IndexMap} indexMap_\n */\n constructor(private readonly children_: SortedMap,\n private readonly priorityNode_: Node | null,\n private indexMap_: IndexMap) {\n\n /**\n * Note: The only reason we allow null priority is for EMPTY_NODE, since we can't use\n * EMPTY_NODE as the priority of EMPTY_NODE. We might want to consider making EMPTY_NODE its own\n * class instead of an empty ChildrenNode.\n */\n if (this.priorityNode_) {\n validatePriorityNode(this.priorityNode_);\n }\n\n if (this.children_.isEmpty()) {\n assert(!this.priorityNode_ || this.priorityNode_.isEmpty(), 'An empty node cannot have a priority');\n }\n }\n\n /** @inheritDoc */\n isLeafNode(): boolean {\n return false;\n }\n\n /** @inheritDoc */\n getPriority(): Node {\n return this.priorityNode_ || EMPTY_NODE;\n }\n\n /** @inheritDoc */\n updatePriority(newPriorityNode: Node): Node {\n if (this.children_.isEmpty()) {\n // Don't allow priorities on empty nodes\n return this;\n } else {\n return new ChildrenNode(this.children_, newPriorityNode, this.indexMap_);\n }\n }\n\n /** @inheritDoc */\n getImmediateChild(childName: string): Node {\n // Hack to treat priority as a regular child\n if (childName === '.priority') {\n return this.getPriority();\n } else {\n const child = this.children_.get(childName);\n return child === null ? EMPTY_NODE : child;\n }\n }\n\n /** @inheritDoc */\n getChild(path: Path): Node {\n const front = path.getFront();\n if (front === null)\n return this;\n\n return this.getImmediateChild(front).getChild(path.popFront());\n }\n\n /** @inheritDoc */\n hasChild(childName: string): boolean {\n return this.children_.get(childName) !== null;\n }\n\n /** @inheritDoc */\n updateImmediateChild(childName: string, newChildNode: Node): Node {\n assert(newChildNode, 'We should always be passing snapshot nodes');\n if (childName === '.priority') {\n return this.updatePriority(newChildNode);\n } else {\n const namedNode = new NamedNode(childName, newChildNode);\n let newChildren, newIndexMap, newPriority;\n if (newChildNode.isEmpty()) {\n newChildren = this.children_.remove(childName);\n newIndexMap = this.indexMap_.removeFromIndexes(namedNode, this.children_\n );\n } else {\n newChildren = this.children_.insert(childName, newChildNode);\n newIndexMap = this.indexMap_.addToIndexes(namedNode, this.children_);\n }\n\n newPriority = newChildren.isEmpty() ? EMPTY_NODE : this.priorityNode_;\n return new ChildrenNode(newChildren, newPriority, newIndexMap);\n }\n }\n\n /** @inheritDoc */\n updateChild(path: Path, newChildNode: Node): Node {\n const front = path.getFront();\n if (front === null) {\n return newChildNode;\n } else {\n assert(path.getFront() !== '.priority' || path.getLength() === 1,\n '.priority must be the last token in a path');\n const newImmediateChild = this.getImmediateChild(front).updateChild(path.popFront(), newChildNode);\n return this.updateImmediateChild(front, newImmediateChild);\n }\n }\n\n /** @inheritDoc */\n isEmpty(): boolean {\n return this.children_.isEmpty();\n }\n\n /** @inheritDoc */\n numChildren(): number {\n return this.children_.count();\n }\n\n /**\n * @private\n * @type {RegExp}\n */\n private static INTEGER_REGEXP_ = /^(0|[1-9]\\d*)$/;\n\n /** @inheritDoc */\n val(exportFormat?: boolean): object {\n if (this.isEmpty())\n return null;\n\n const obj: { [k: string]: Object } = {};\n let numKeys = 0, maxKey = 0, allIntegerKeys = true;\n this.forEachChild(PRIORITY_INDEX, function (key: string, childNode: Node) {\n obj[key] = childNode.val(exportFormat);\n\n numKeys++;\n if (allIntegerKeys && ChildrenNode.INTEGER_REGEXP_.test(key)) {\n maxKey = Math.max(maxKey, Number(key));\n } else {\n allIntegerKeys = false;\n }\n });\n\n if (!exportFormat && allIntegerKeys && maxKey < 2 * numKeys) {\n // convert to array.\n const array: Object[] = [];\n for (let key in obj)\n array[key as any as number] = obj[key];\n\n return array;\n } else {\n if (exportFormat && !this.getPriority().isEmpty()) {\n obj['.priority'] = this.getPriority().val();\n }\n return obj;\n }\n }\n\n\n /** @inheritDoc */\n hash(): string {\n if (this.lazyHash_ === null) {\n let toHash = '';\n if (!this.getPriority().isEmpty())\n toHash += 'priority:' + priorityHashText(\n (this.getPriority().val() as string | number)) + ':';\n\n this.forEachChild(PRIORITY_INDEX, function (key, childNode) {\n const childHash = childNode.hash();\n if (childHash !== '')\n toHash += ':' + key + ':' + childHash;\n });\n\n this.lazyHash_ = (toHash === '') ? '' : sha1(toHash);\n }\n return this.lazyHash_;\n }\n\n\n /** @inheritDoc */\n getPredecessorChildName(childName: string, childNode: Node, index: Index): string {\n const idx = this.resolveIndex_(index);\n if (idx) {\n const predecessor = idx.getPredecessorKey(new NamedNode(childName, childNode));\n return predecessor ? predecessor.name : null;\n } else {\n return this.children_.getPredecessorKey(childName);\n }\n }\n\n /**\n * @param {!Index} indexDefinition\n * @return {?string}\n */\n getFirstChildName(indexDefinition: Index): string | null {\n const idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n const minKey = idx.minKey();\n return minKey && minKey.name;\n } else {\n return this.children_.minKey();\n }\n }\n\n /**\n * @param {!Index} indexDefinition\n * @return {?NamedNode}\n */\n getFirstChild(indexDefinition: Index): NamedNode | null {\n const minKey = this.getFirstChildName(indexDefinition);\n if (minKey) {\n return new NamedNode(minKey, this.children_.get(minKey));\n } else {\n return null;\n }\n }\n\n /**\n * Given an index, return the key name of the largest value we have, according to that index\n * @param {!Index} indexDefinition\n * @return {?string}\n */\n getLastChildName(indexDefinition: Index): string | null {\n const idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n const maxKey = idx.maxKey();\n return maxKey && maxKey.name;\n } else {\n return this.children_.maxKey();\n }\n }\n\n /**\n * @param {!Index} indexDefinition\n * @return {?NamedNode}\n */\n getLastChild(indexDefinition: Index): NamedNode | null {\n const maxKey = this.getLastChildName(indexDefinition);\n if (maxKey) {\n return new NamedNode(maxKey, this.children_.get(maxKey));\n } else {\n return null;\n }\n }\n\n\n /**\n * @inheritDoc\n */\n forEachChild(index: Index, action: (key: string, node: Node) => void): any {\n const idx = this.resolveIndex_(index);\n if (idx) {\n return idx.inorderTraversal(function (wrappedNode) {\n return action(wrappedNode.name, wrappedNode.node);\n });\n } else {\n return this.children_.inorderTraversal(action);\n }\n }\n\n /**\n * @param {!Index} indexDefinition\n * @return {SortedMapIterator}\n */\n getIterator(indexDefinition: Index): SortedMapIterator {\n return this.getIteratorFrom(indexDefinition.minPost(), indexDefinition);\n }\n\n /**\n *\n * @param {!NamedNode} startPost\n * @param {!Index} indexDefinition\n * @return {!SortedMapIterator}\n */\n getIteratorFrom(startPost: NamedNode, indexDefinition: Index): SortedMapIterator {\n const idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n return idx.getIteratorFrom(startPost, (key) => key);\n } else {\n const iterator = this.children_.getIteratorFrom(startPost.name, NamedNode.Wrap);\n let next = iterator.peek();\n while (next != null && indexDefinition.compare(next, startPost) < 0) {\n iterator.getNext();\n next = iterator.peek();\n }\n return iterator;\n }\n }\n\n /**\n * @param {!Index} indexDefinition\n * @return {!SortedMapIterator}\n */\n getReverseIterator(indexDefinition: Index): SortedMapIterator {\n return this.getReverseIteratorFrom(indexDefinition.maxPost(), indexDefinition);\n }\n\n /**\n * @param {!NamedNode} endPost\n * @param {!Index} indexDefinition\n * @return {!SortedMapIterator}\n */\n getReverseIteratorFrom(endPost: NamedNode,\n indexDefinition: Index): SortedMapIterator {\n const idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n return idx.getReverseIteratorFrom(endPost, function (key) { return key; });\n } else {\n const iterator = this.children_.getReverseIteratorFrom(endPost.name, NamedNode.Wrap);\n let next = iterator.peek();\n while (next != null && indexDefinition.compare(next, endPost) > 0) {\n iterator.getNext();\n next = iterator.peek();\n }\n return iterator;\n }\n }\n\n /**\n * @inheritDoc\n */\n compareTo(other: ChildrenNode): number {\n if (this.isEmpty()) {\n if (other.isEmpty()) {\n return 0;\n } else {\n return -1;\n }\n } else if (other.isLeafNode() || other.isEmpty()) {\n return 1;\n } else if (other === MAX_NODE) {\n return -1;\n } else {\n // Must be another node with children.\n return 0;\n }\n }\n\n /**\n * @inheritDoc\n */\n withIndex(indexDefinition: Index): Node {\n if (indexDefinition === KEY_INDEX || this.indexMap_.hasIndex(indexDefinition)) {\n return this;\n } else {\n const newIndexMap = this.indexMap_.addIndex(indexDefinition, this.children_);\n return new ChildrenNode(this.children_, this.priorityNode_, newIndexMap);\n }\n }\n\n /**\n * @inheritDoc\n */\n isIndexed(index: Index): boolean {\n return index === KEY_INDEX || this.indexMap_.hasIndex(index);\n }\n\n /**\n * @inheritDoc\n */\n equals(other: Node): boolean {\n if (other === this) {\n return true;\n }\n else if (other.isLeafNode()) {\n return false;\n } else {\n const otherChildrenNode = other as ChildrenNode;\n if (!this.getPriority().equals(otherChildrenNode.getPriority())) {\n return false;\n } else if (this.children_.count() === otherChildrenNode.children_.count()) {\n const thisIter = this.getIterator(PRIORITY_INDEX);\n const otherIter = otherChildrenNode.getIterator(PRIORITY_INDEX);\n let thisCurrent = thisIter.getNext();\n let otherCurrent = otherIter.getNext();\n while (thisCurrent && otherCurrent) {\n if (thisCurrent.name !== otherCurrent.name || !thisCurrent.node.equals(otherCurrent.node)) {\n return false;\n }\n thisCurrent = thisIter.getNext();\n otherCurrent = otherIter.getNext();\n }\n return thisCurrent === null && otherCurrent === null;\n } else {\n return false;\n }\n }\n }\n\n\n /**\n * Returns a SortedMap ordered by index, or null if the default (by-key) ordering can be used\n * instead.\n *\n * @private\n * @param {!Index} indexDefinition\n * @return {?SortedMap.}\n */\n private resolveIndex_(indexDefinition: Index): SortedMap | null {\n if (indexDefinition === KEY_INDEX) {\n return null;\n } else {\n return this.indexMap_.get(indexDefinition.toString());\n }\n }\n\n}\n\n/**\n * @constructor\n * @extends {ChildrenNode}\n * @private\n */\nexport class MaxNode extends ChildrenNode {\n constructor() {\n super(new SortedMap(NAME_COMPARATOR), ChildrenNode.EMPTY_NODE, IndexMap.Default);\n }\n\n compareTo(other: Node): number {\n if (other === this) {\n return 0;\n } else {\n return 1;\n }\n }\n\n\n equals(other: Node): boolean {\n // Not that we every compare it, but MAX_NODE is only ever equal to itself\n return other === this;\n }\n\n\n getPriority(): MaxNode {\n return this;\n }\n\n\n getImmediateChild(childName: string): ChildrenNode {\n return ChildrenNode.EMPTY_NODE;\n }\n\n\n isEmpty(): boolean {\n return false;\n }\n}\n\n/**\n * Marker that will sort higher than any other snapshot.\n * @type {!MAX_NODE}\n * @const\n */\nexport const MAX_NODE = new MaxNode();\n\n/**\n * Document NamedNode extensions\n */\ndeclare module './Node' {\n interface NamedNode {\n MIN: NamedNode,\n MAX: NamedNode\n }\n}\n\nObject.defineProperties(NamedNode, {\n MIN: {\n value: new NamedNode(MIN_NAME, ChildrenNode.EMPTY_NODE)\n },\n MAX: {\n value: new NamedNode(MAX_NAME, MAX_NODE)\n }\n});\n\n/**\n * Reference Extensions\n */\nKeyIndex.__EMPTY_NODE = ChildrenNode.EMPTY_NODE;\nLeafNode.__childrenNodeConstructor = ChildrenNode;\nsetMaxNode(MAX_NODE);\nsetPriorityMaxNode(MAX_NODE);\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/ChildrenNode.ts","/**\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\nimport { Index } from \"./Index\";\nimport { NamedNode, Node } from '../Node';\nimport { nameCompare } from \"../../util/util\";\nimport { nodeFromJSON } from \"../nodeFromJSON\";\n\n/**\n * @constructor\n * @extends {Index}\n * @private\n */\nexport class ValueIndex extends Index {\n /**\n * @inheritDoc\n */\n compare(a: NamedNode, b: NamedNode): number {\n const indexCmp = a.node.compareTo(b.node);\n if (indexCmp === 0) {\n return nameCompare(a.name, b.name);\n } else {\n return indexCmp;\n }\n }\n\n /**\n * @inheritDoc\n */\n isDefinedOn(node: Node): boolean {\n return true;\n }\n\n /**\n * @inheritDoc\n */\n indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n return !oldNode.equals(newNode);\n }\n\n /**\n * @inheritDoc\n */\n minPost(): NamedNode {\n return (NamedNode as any).MIN;\n }\n\n /**\n * @inheritDoc\n */\n maxPost(): NamedNode {\n return (NamedNode as any).MAX;\n }\n\n /**\n * @param {*} indexValue\n * @param {string} name\n * @return {!NamedNode}\n */\n makePost(indexValue: object, name: string): NamedNode {\n const valueNode = nodeFromJSON(indexValue);\n return new NamedNode(name, valueNode);\n }\n\n /**\n * @return {!string} String representation for inclusion in a query spec\n */\n toString(): string {\n return '.value';\n };\n}\n\nexport const VALUE_INDEX = new ValueIndex();\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/indexes/ValueIndex.ts","/**\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\nimport { assert } from '../../utils/assert';\nimport { KEY_INDEX } from '../core/snap/indexes/KeyIndex';\nimport { PRIORITY_INDEX } from '../core/snap/indexes/PriorityIndex';\nimport { VALUE_INDEX } from '../core/snap/indexes/ValueIndex';\nimport { PathIndex } from '../core/snap/indexes/PathIndex';\nimport { MIN_NAME, MAX_NAME, ObjectToUniqueKey } from '../core/util/util';\nimport { Path } from '../core/util/Path';\nimport {\n isValidPriority,\n validateEventType,\n validatePathString,\n validateFirebaseDataArg,\n validateKey,\n} from '../core/util/validation';\nimport { errorPrefix, validateArgCount, validateCallback, validateContextObject } from '../../utils/validation';\nimport { ValueEventRegistration, ChildEventRegistration, EventRegistration } from '../core/view/EventRegistration';\nimport { Deferred, attachDummyErrorHandler } from '../../utils/promise';\nimport { Repo } from '../core/Repo';\nimport { QueryParams } from '../core/view/QueryParams';\nimport { Reference } from './Reference';\nimport { DataSnapshot } from './DataSnapshot';\n\nlet __referenceConstructor: new(repo: Repo, path: Path) => Query;\n\nexport interface SnapshotCallback {\n (a: DataSnapshot, b?: string): any\n}\n\n/**\n * A Query represents a filter to be applied to a firebase location. This object purely represents the\n * query expression (and exposes our public API to build the query). The actual query logic is in ViewBase.js.\n *\n * Since every Firebase reference is a query, Firebase inherits from this object.\n */\nexport class Query {\n static set __referenceConstructor(val) {\n __referenceConstructor = val;\n }\n\n static get __referenceConstructor() {\n assert(__referenceConstructor, 'Reference.ts has not been loaded');\n return __referenceConstructor;\n }\n\n constructor(public repo: Repo, public path: Path, private queryParams_: QueryParams, private orderByCalled_: boolean) {}\n\n /**\n * Validates start/end values for queries.\n * @param {!QueryParams} params\n * @private\n */\n private static validateQueryEndpoints_(params: QueryParams) {\n let startNode = null;\n let endNode = null;\n if (params.hasStart()) {\n startNode = params.getIndexStartValue();\n }\n if (params.hasEnd()) {\n endNode = params.getIndexEndValue();\n }\n\n if (params.getIndex() === KEY_INDEX) {\n const tooManyArgsError = 'Query: When ordering by key, you may only pass one argument to ' +\n 'startAt(), endAt(), or equalTo().';\n const wrongArgTypeError = 'Query: When ordering by key, the argument passed to startAt(), endAt(),' +\n 'or equalTo() must be a string.';\n if (params.hasStart()) {\n const startName = params.getIndexStartName();\n if (startName != MIN_NAME) {\n throw new Error(tooManyArgsError);\n } else if (typeof(startNode) !== 'string') {\n throw new Error(wrongArgTypeError);\n }\n }\n if (params.hasEnd()) {\n const endName = params.getIndexEndName();\n if (endName != MAX_NAME) {\n throw new Error(tooManyArgsError);\n } else if (typeof(endNode) !== 'string') {\n throw new Error(wrongArgTypeError);\n }\n }\n }\n else if (params.getIndex() === PRIORITY_INDEX) {\n if ((startNode != null && !isValidPriority(startNode)) ||\n (endNode != null && !isValidPriority(endNode))) {\n throw new Error('Query: When ordering by priority, the first argument passed to startAt(), ' +\n 'endAt(), or equalTo() must be a valid priority value (null, a number, or a string).');\n }\n } else {\n assert((params.getIndex() instanceof PathIndex) ||\n (params.getIndex() === VALUE_INDEX), 'unknown index type.');\n if ((startNode != null && typeof startNode === 'object') ||\n (endNode != null && typeof endNode === 'object')) {\n throw new Error('Query: First argument passed to startAt(), endAt(), or equalTo() cannot be ' +\n 'an object.');\n }\n }\n }\n\n /**\n * Validates that limit* has been called with the correct combination of parameters\n * @param {!QueryParams} params\n * @private\n */\n private static validateLimit_(params: QueryParams) {\n if (params.hasStart() && params.hasEnd() && params.hasLimit() && !params.hasAnchoredLimit()) {\n throw new Error(\n 'Query: Can\\'t combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.'\n );\n }\n }\n\n /**\n * Validates that no other order by call has been made\n * @param {!string} fnName\n * @private\n */\n private validateNoPreviousOrderByCall_(fnName: string) {\n if (this.orderByCalled_ === true) {\n throw new Error(fnName + ': You can\\'t combine multiple orderBy calls.');\n }\n }\n\n /**\n * @return {!QueryParams}\n */\n getQueryParams(): QueryParams {\n return this.queryParams_;\n }\n\n /**\n * @return {!Reference}\n */\n getRef(): Reference {\n validateArgCount('Query.ref', 0, 0, arguments.length);\n // This is a slight hack. We cannot goog.require('fb.api.Firebase'), since Firebase requires fb.api.Query.\n // However, we will always export 'Firebase' to the global namespace, so it's guaranteed to exist by the time this\n // method gets called.\n return (new Query.__referenceConstructor(this.repo, this.path) as Reference);\n }\n\n /**\n * @param {!string} eventType\n * @param {!function(DataSnapshot, string=)} callback\n * @param {(function(Error)|Object)=} cancelCallbackOrContext\n * @param {Object=} context\n * @return {!function(DataSnapshot, string=)}\n */\n on(eventType: string, callback: SnapshotCallback,\n cancelCallbackOrContext?: ((a: Error) => any) | Object, context?: Object): SnapshotCallback {\n validateArgCount('Query.on', 2, 4, arguments.length);\n validateEventType('Query.on', 1, eventType, false);\n validateCallback('Query.on', 2, callback, false);\n\n const ret = Query.getCancelAndContextArgs_('Query.on', cancelCallbackOrContext, context);\n\n if (eventType === 'value') {\n this.onValueEvent(callback, ret.cancel, ret.context);\n } else {\n const callbacks: { [k: string]: typeof callback } = {};\n callbacks[eventType] = callback;\n this.onChildEvent(callbacks, ret.cancel, ret.context);\n }\n return callback;\n }\n\n /**\n * @param {!function(!DataSnapshot)} callback\n * @param {?function(Error)} cancelCallback\n * @param {?Object} context\n * @protected\n */\n protected onValueEvent(callback: (a: DataSnapshot) => void, cancelCallback: ((a: Error) => void) | null, context: Object | null) {\n const container = new ValueEventRegistration(callback, cancelCallback || null, context || null);\n this.repo.addEventCallbackForQuery(this, container);\n }\n\n /**\n * @param {!Object.} callbacks\n * @param {?function(Error)} cancelCallback\n * @param {?Object} context\n * @protected\n */\n onChildEvent(callbacks: { [k: string]: SnapshotCallback },\n cancelCallback: ((a: Error) => any) | null, context: Object | null) {\n const container = new ChildEventRegistration(callbacks, cancelCallback, context);\n this.repo.addEventCallbackForQuery(this, container);\n }\n\n /**\n * @param {string=} eventType\n * @param {(function(!DataSnapshot, ?string=))=} callback\n * @param {Object=} context\n */\n off(eventType?: string, callback?: SnapshotCallback, context?: Object) {\n validateArgCount('Query.off', 0, 3, arguments.length);\n validateEventType('Query.off', 1, eventType, true);\n validateCallback('Query.off', 2, callback, true);\n validateContextObject('Query.off', 3, context, true);\n\n let container: EventRegistration | null = null;\n let callbacks: { [k: string]: typeof callback } | null = null;\n if (eventType === 'value') {\n const valueCallback = callback || null;\n container = new ValueEventRegistration(valueCallback, null, context || null);\n } else if (eventType) {\n if (callback) {\n callbacks = {};\n callbacks[eventType] = callback;\n }\n container = new ChildEventRegistration(callbacks, null, context || null);\n }\n this.repo.removeEventCallbackForQuery(this, container);\n }\n\n /**\n * Attaches a listener, waits for the first event, and then removes the listener\n * @param {!string} eventType\n * @param {!function(!DataSnapshot, string=)} userCallback\n * @param cancelOrContext\n * @param context\n * @return {!firebase.Promise}\n */\n once(eventType: string, \n userCallback?: SnapshotCallback,\n cancelOrContext?: ((a: Error) => void) | Object,\n context?: Object): Promise {\n validateArgCount('Query.once', 1, 4, arguments.length);\n validateEventType('Query.once', 1, eventType, false);\n validateCallback('Query.once', 2, userCallback, true);\n\n const ret = Query.getCancelAndContextArgs_('Query.once', cancelOrContext, context);\n\n // TODO: Implement this more efficiently (in particular, use 'get' wire protocol for 'value' event)\n // TODO: consider actually wiring the callbacks into the promise. We cannot do this without a breaking change\n // because the API currently expects callbacks will be called synchronously if the data is cached, but this is\n // against the Promise specification.\n let firstCall = true;\n const deferred = new Deferred();\n attachDummyErrorHandler(deferred.promise);\n\n const onceCallback = (snapshot: DataSnapshot) => {\n // NOTE: Even though we unsubscribe, we may get called multiple times if a single action (e.g. set() with JSON)\n // triggers multiple events (e.g. child_added or child_changed).\n if (firstCall) {\n firstCall = false;\n this.off(eventType, onceCallback);\n\n if (userCallback) {\n userCallback.bind(ret.context)(snapshot);\n }\n deferred.resolve(snapshot);\n }\n };\n\n this.on(eventType, onceCallback, /*cancel=*/ (err) => {\n this.off(eventType, onceCallback);\n\n if (ret.cancel)\n ret.cancel.bind(ret.context)(err);\n deferred.reject(err);\n });\n return deferred.promise;\n }\n\n /**\n * Set a limit and anchor it to the start of the window.\n * @param {!number} limit\n * @return {!Query}\n */\n limitToFirst(limit: number): Query {\n validateArgCount('Query.limitToFirst', 1, 1, arguments.length);\n if (typeof limit !== 'number' || Math.floor(limit) !== limit || limit <= 0) {\n throw new Error('Query.limitToFirst: First argument must be a positive integer.');\n }\n if (this.queryParams_.hasLimit()) {\n throw new Error('Query.limitToFirst: Limit was already set (by another call to limit, ' +\n 'limitToFirst, or limitToLast).');\n }\n\n return new Query(this.repo, this.path, this.queryParams_.limitToFirst(limit), this.orderByCalled_);\n }\n\n /**\n * Set a limit and anchor it to the end of the window.\n * @param {!number} limit\n * @return {!Query}\n */\n limitToLast(limit: number): Query {\n validateArgCount('Query.limitToLast', 1, 1, arguments.length);\n if (typeof limit !== 'number' || Math.floor(limit) !== limit || limit <= 0) {\n throw new Error('Query.limitToLast: First argument must be a positive integer.');\n }\n if (this.queryParams_.hasLimit()) {\n throw new Error('Query.limitToLast: Limit was already set (by another call to limit, ' +\n 'limitToFirst, or limitToLast).');\n }\n\n return new Query(this.repo, this.path, this.queryParams_.limitToLast(limit),\n this.orderByCalled_);\n }\n\n /**\n * Given a child path, return a new query ordered by the specified grandchild path.\n * @param {!string} path\n * @return {!Query}\n */\n orderByChild(path: string): Query {\n validateArgCount('Query.orderByChild', 1, 1, arguments.length);\n if (path === '$key') {\n throw new Error('Query.orderByChild: \"$key\" is invalid. Use Query.orderByKey() instead.');\n } else if (path === '$priority') {\n throw new Error('Query.orderByChild: \"$priority\" is invalid. Use Query.orderByPriority() instead.');\n } else if (path === '$value') {\n throw new Error('Query.orderByChild: \"$value\" is invalid. Use Query.orderByValue() instead.');\n }\n validatePathString('Query.orderByChild', 1, path, false);\n this.validateNoPreviousOrderByCall_('Query.orderByChild');\n const parsedPath = new Path(path);\n if (parsedPath.isEmpty()) {\n throw new Error('Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.');\n }\n const index = new PathIndex(parsedPath);\n const newParams = this.queryParams_.orderBy(index);\n Query.validateQueryEndpoints_(newParams);\n\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n }\n\n /**\n * Return a new query ordered by the KeyIndex\n * @return {!Query}\n */\n orderByKey(): Query {\n validateArgCount('Query.orderByKey', 0, 0, arguments.length);\n this.validateNoPreviousOrderByCall_('Query.orderByKey');\n const newParams = this.queryParams_.orderBy(KEY_INDEX);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n }\n\n /**\n * Return a new query ordered by the PriorityIndex\n * @return {!Query}\n */\n orderByPriority(): Query {\n validateArgCount('Query.orderByPriority', 0, 0, arguments.length);\n this.validateNoPreviousOrderByCall_('Query.orderByPriority');\n const newParams = this.queryParams_.orderBy(PRIORITY_INDEX);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n }\n\n /**\n * Return a new query ordered by the ValueIndex\n * @return {!Query}\n */\n orderByValue(): Query {\n validateArgCount('Query.orderByValue', 0, 0, arguments.length);\n this.validateNoPreviousOrderByCall_('Query.orderByValue');\n const newParams = this.queryParams_.orderBy(VALUE_INDEX);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n }\n\n /**\n * @param {number|string|boolean|null} value\n * @param {?string=} name\n * @return {!Query}\n */\n startAt(value: number | string | boolean | null = null, name?: string | null): Query {\n validateArgCount('Query.startAt', 0, 2, arguments.length);\n validateFirebaseDataArg('Query.startAt', 1, value, this.path, true);\n validateKey('Query.startAt', 2, name, true);\n\n const newParams = this.queryParams_.startAt(value, name);\n Query.validateLimit_(newParams);\n Query.validateQueryEndpoints_(newParams);\n if (this.queryParams_.hasStart()) {\n throw new Error('Query.startAt: Starting point was already set (by another call to startAt ' +\n 'or equalTo).');\n }\n\n // Calling with no params tells us to start at the beginning.\n if (value === undefined) {\n value = null;\n name = null;\n }\n return new Query(this.repo, this.path, newParams, this.orderByCalled_);\n }\n\n /**\n * @param {number|string|boolean|null} value\n * @param {?string=} name\n * @return {!Query}\n */\n endAt(value: number | string | boolean | null = null, name?: string | null): Query {\n validateArgCount('Query.endAt', 0, 2, arguments.length);\n validateFirebaseDataArg('Query.endAt', 1, value, this.path, true);\n validateKey('Query.endAt', 2, name, true);\n\n const newParams = this.queryParams_.endAt(value, name);\n Query.validateLimit_(newParams);\n Query.validateQueryEndpoints_(newParams);\n if (this.queryParams_.hasEnd()) {\n throw new Error('Query.endAt: Ending point was already set (by another call to endAt or ' +\n 'equalTo).');\n }\n\n return new Query(this.repo, this.path, newParams, this.orderByCalled_);\n }\n\n /**\n * Load the selection of children with exactly the specified value, and, optionally,\n * the specified name.\n * @param {number|string|boolean|null} value\n * @param {string=} name\n * @return {!Query}\n */\n equalTo(value: number | string | boolean | null, name?: string) {\n validateArgCount('Query.equalTo', 1, 2, arguments.length);\n validateFirebaseDataArg('Query.equalTo', 1, value, this.path, false);\n validateKey('Query.equalTo', 2, name, true);\n if (this.queryParams_.hasStart()) {\n throw new Error('Query.equalTo: Starting point was already set (by another call to startAt or ' +\n 'equalTo).');\n }\n if (this.queryParams_.hasEnd()) {\n throw new Error('Query.equalTo: Ending point was already set (by another call to endAt or ' +\n 'equalTo).');\n }\n return this.startAt(value, name).endAt(value, name);\n }\n\n /**\n * @return {!string} URL for this location.\n */\n toString(): string {\n validateArgCount('Query.toString', 0, 0, arguments.length);\n\n return this.repo.toString() + this.path.toUrlEncodedString();\n }\n\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n // for end-users.\n toJSON() {\n // An optional spacer argument is unnecessary for a string.\n validateArgCount('Query.toJSON', 0, 1, arguments.length);\n return this.toString();\n }\n\n /**\n * An object representation of the query parameters used by this Query.\n * @return {!Object}\n */\n queryObject(): Object {\n return this.queryParams_.getQueryObject();\n }\n\n /**\n * @return {!string}\n */\n queryIdentifier(): string {\n const obj = this.queryObject();\n const id = ObjectToUniqueKey(obj);\n return (id === '{}') ? 'default' : id;\n }\n\n /**\n * Return true if this query and the provided query are equivalent; otherwise, return false.\n * @param {Query} other\n * @return {boolean}\n */\n isEqual(other: Query): boolean {\n validateArgCount('Query.isEqual', 1, 1, arguments.length);\n if (!(other instanceof Query)) {\n const error = 'Query.isEqual failed: First argument must be an instance of firebase.database.Query.';\n throw new Error(error);\n }\n\n const sameRepo = (this.repo === other.repo);\n const samePath = this.path.equals(other.path);\n const sameQueryIdentifier = (this.queryIdentifier() === other.queryIdentifier());\n\n return (sameRepo && samePath && sameQueryIdentifier);\n }\n\n /**\n * Helper used by .on and .once to extract the context and or cancel arguments.\n * @param {!string} fnName The function name (on or once)\n * @param {(function(Error)|Object)=} cancelOrContext\n * @param {Object=} context\n * @return {{cancel: ?function(Error), context: ?Object}}\n * @private\n */\n private static getCancelAndContextArgs_(fnName: string, cancelOrContext?: ((a: Error) => void) | Object,\n context?: Object): { cancel: ((a: Error) => void) | null, context: Object | null } {\n const ret: { cancel: ((a: Error) => void) | null, context: Object | null } = {cancel: null, context: null};\n if (cancelOrContext && context) {\n ret.cancel = (cancelOrContext as (a: Error) => void);\n validateCallback(fnName, 3, ret.cancel, true);\n\n ret.context = context;\n validateContextObject(fnName, 4, ret.context, true);\n } else if (cancelOrContext) { // we have either a cancel callback or a context.\n if (typeof cancelOrContext === 'object' && cancelOrContext !== null) { // it's a context!\n ret.context = cancelOrContext;\n } else if (typeof cancelOrContext === 'function') {\n ret.cancel = cancelOrContext;\n } else {\n throw new Error(errorPrefix(fnName, 3, true) +\n ' must either be a cancel callback or a context object.');\n }\n }\n return ret;\n }\n\n get ref(): Reference {\n return this.getRef();\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/Query.ts","/**\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\nimport { assert } from \"../../../utils/assert\";\nimport { Path } from '../util/Path';\n\n/**\n *\n * @enum\n */\nexport enum OperationType {\n OVERWRITE,\n MERGE,\n ACK_USER_WRITE,\n LISTEN_COMPLETE\n}\n\n/**\n * @interface\n */\nexport interface Operation {\n /**\n * @type {!OperationSource}\n */\n source: OperationSource;\n\n /**\n * @type {!OperationType}\n */\n type: OperationType;\n\n /**\n * @type {!Path}\n */\n path: Path;\n\n /**\n * @param {string} childName\n * @return {?Operation}\n */\n operationForChild(childName: string): Operation | null;\n}\n\n/**\n * @param {boolean} fromUser\n * @param {boolean} fromServer\n * @param {?string} queryId\n * @param {boolean} tagged\n * @constructor\n */\nexport class OperationSource {\n constructor(public fromUser: boolean,\n public fromServer: boolean,\n public queryId: string | null,\n public tagged: boolean) {\n assert(!tagged || fromServer, 'Tagged queries must be from server.');\n }\n /**\n * @const\n * @type {!OperationSource}\n */\n static User = new OperationSource(/*fromUser=*/true, false, null, /*tagged=*/false);\n\n /**\n * @const\n * @type {!OperationSource}\n */\n static Server = new OperationSource(false, /*fromServer=*/true, null, /*tagged=*/false);\n\n /**\n * @param {string} queryId\n * @return {!OperationSource}\n */\n static forServerTaggedQuery = function(queryId: string): OperationSource {\n return new OperationSource(false, /*fromServer=*/true, queryId, /*tagged=*/true);\n };\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/operation/Operation.ts","/**\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\nimport { assert } from \"../../../../utils/assert\";\nimport { nameCompare, MAX_NAME } from \"../../util/util\";\nimport { Index } from \"./Index\";\nimport { ChildrenNode, MAX_NODE } from \"../ChildrenNode\";\nimport { NamedNode, Node } from '../Node';\nimport { nodeFromJSON } from \"../nodeFromJSON\";\nimport { Path } from '../../util/Path';\n\n/**\n * @param {!Path} indexPath\n * @constructor\n * @extends {Index}\n */\nexport class PathIndex extends Index {\n constructor(private indexPath_: Path) {\n super();\n\n assert(!indexPath_.isEmpty() && indexPath_.getFront() !== '.priority',\n 'Can\\'t create PathIndex with empty path or .priority key');\n }\n\n /**\n * @param {!Node} snap\n * @return {!Node}\n * @protected\n */\n protected extractChild(snap: Node): Node {\n return snap.getChild(this.indexPath_);\n }\n\n\n /**\n * @inheritDoc\n */\n isDefinedOn(node: Node): boolean {\n return !node.getChild(this.indexPath_).isEmpty();\n }\n\n\n /**\n * @inheritDoc\n */\n compare(a: NamedNode, b: NamedNode): number {\n const aChild = this.extractChild(a.node);\n const bChild = this.extractChild(b.node);\n const indexCmp = aChild.compareTo(bChild);\n if (indexCmp === 0) {\n return nameCompare(a.name, b.name);\n } else {\n return indexCmp;\n }\n }\n\n\n /**\n * @inheritDoc\n */\n makePost(indexValue: object, name: string): NamedNode {\n const valueNode = nodeFromJSON(indexValue);\n const node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, valueNode);\n return new NamedNode(name, node);\n }\n\n\n /**\n * @inheritDoc\n */\n maxPost(): NamedNode {\n const node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, MAX_NODE);\n return new NamedNode(MAX_NAME, node);\n }\n\n\n /**\n * @inheritDoc\n */\n toString(): string {\n return this.indexPath_.slice().join('/');\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/snap/indexes/PathIndex.ts","/**\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\nimport { validateArgCount, validateCallback } from '../../utils/validation';\nimport { validatePathString } from '../core/util/validation';\nimport { Path } from '../core/util/Path';\nimport { PRIORITY_INDEX } from '../core/snap/indexes/PriorityIndex';\nimport { Node } from '../core/snap/Node';\nimport { Reference } from './Reference';\nimport { Index } from '../core/snap/indexes/Index';\nimport { ChildrenNode } from '../core/snap/ChildrenNode';\n\n/**\n * Class representing a firebase data snapshot. It wraps a SnapshotNode and\n * surfaces the public methods (val, forEach, etc.) we want to expose.\n */\nexport class DataSnapshot {\n /**\n * @param {!Node} node_ A SnapshotNode to wrap.\n * @param {!Reference} ref_ The ref of the location this snapshot came from.\n * @param {!Index} index_ The iteration order for this snapshot\n */\n constructor(private readonly node_: Node,\n private readonly ref_: Reference,\n private readonly index_: Index) {\n }\n\n /**\n * Retrieves the snapshot contents as JSON. Returns null if the snapshot is\n * empty.\n *\n * @return {*} JSON representation of the DataSnapshot contents, or null if empty.\n */\n val(): any {\n validateArgCount('DataSnapshot.val', 0, 0, arguments.length);\n return this.node_.val();\n }\n\n /**\n * Returns the snapshot contents as JSON, including priorities of node. Suitable for exporting\n * the entire node contents.\n * @return {*} JSON representation of the DataSnapshot contents, or null if empty.\n */\n exportVal(): any {\n validateArgCount('DataSnapshot.exportVal', 0, 0, arguments.length);\n return this.node_.val(true);\n }\n\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n // for end-users\n toJSON(): any {\n // Optional spacer argument is unnecessary because we're depending on recursion rather than stringifying the content\n validateArgCount('DataSnapshot.toJSON', 0, 1, arguments.length);\n return this.exportVal();\n }\n\n /**\n * Returns whether the snapshot contains a non-null value.\n *\n * @return {boolean} Whether the snapshot contains a non-null value, or is empty.\n */\n exists(): boolean {\n validateArgCount('DataSnapshot.exists', 0, 0, arguments.length);\n return !this.node_.isEmpty();\n }\n\n /**\n * Returns a DataSnapshot of the specified child node's contents.\n *\n * @param {!string} childPathString Path to a child.\n * @return {!DataSnapshot} DataSnapshot for child node.\n */\n child(childPathString: string): DataSnapshot {\n validateArgCount('DataSnapshot.child', 0, 1, arguments.length);\n // Ensure the childPath is a string (can be a number)\n childPathString = String(childPathString);\n validatePathString('DataSnapshot.child', 1, childPathString, false);\n\n const childPath = new Path(childPathString);\n const childRef = this.ref_.child(childPath);\n return new DataSnapshot(this.node_.getChild(childPath), childRef, PRIORITY_INDEX);\n }\n\n /**\n * Returns whether the snapshot contains a child at the specified path.\n *\n * @param {!string} childPathString Path to a child.\n * @return {boolean} Whether the child exists.\n */\n hasChild(childPathString: string): boolean {\n validateArgCount('DataSnapshot.hasChild', 1, 1, arguments.length);\n validatePathString('DataSnapshot.hasChild', 1, childPathString, false);\n\n const childPath = new Path(childPathString);\n return !this.node_.getChild(childPath).isEmpty();\n }\n\n /**\n * Returns the priority of the object, or null if no priority was set.\n *\n * @return {string|number|null} The priority.\n */\n getPriority(): string | number | null {\n validateArgCount('DataSnapshot.getPriority', 0, 0, arguments.length);\n\n // typecast here because we never return deferred values or internal priorities (MAX_PRIORITY)\n return (this.node_.getPriority().val() as string | number | null);\n }\n\n /**\n * Iterates through child nodes and calls the specified action for each one.\n *\n * @param {function(!DataSnapshot)} action Callback function to be called\n * for each child.\n * @return {boolean} True if forEach was canceled by action returning true for\n * one of the child nodes.\n */\n forEach(action: (d: DataSnapshot) => void): boolean {\n validateArgCount('DataSnapshot.forEach', 1, 1, arguments.length);\n validateCallback('DataSnapshot.forEach', 1, action, false);\n\n if (this.node_.isLeafNode())\n return false;\n\n const childrenNode = (this.node_ as ChildrenNode);\n // Sanitize the return value to a boolean. ChildrenNode.forEachChild has a weird return type...\n return !!childrenNode.forEachChild(this.index_, (key, node) => {\n return action(new DataSnapshot(node, this.ref_.child(key), PRIORITY_INDEX));\n });\n }\n\n /**\n * Returns whether this DataSnapshot has children.\n * @return {boolean} True if the DataSnapshot contains 1 or more child nodes.\n */\n hasChildren(): boolean {\n validateArgCount('DataSnapshot.hasChildren', 0, 0, arguments.length);\n\n if (this.node_.isLeafNode())\n return false;\n else\n return !this.node_.isEmpty();\n }\n\n get key() {\n return this.ref_.getKey();\n }\n\n /**\n * Returns the number of children for this DataSnapshot.\n * @return {number} The number of children that this DataSnapshot contains.\n */\n numChildren(): number {\n validateArgCount('DataSnapshot.numChildren', 0, 0, arguments.length);\n\n return this.node_.numChildren();\n }\n\n /**\n * @return {Reference} The Firebase reference for the location this snapshot's data came from.\n */\n getRef(): Reference {\n validateArgCount('DataSnapshot.ref', 0, 0, arguments.length);\n\n return this.ref_;\n }\n\n get ref() {\n return this.getRef();\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/DataSnapshot.ts","/**\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\nimport { stringify } from '../../../utils/json';\nimport { Path } from '../util/Path';\nimport { EventRegistration } from './EventRegistration';\nimport { DataSnapshot } from '../../api/DataSnapshot';\n\n/**\n * Encapsulates the data needed to raise an event\n * @interface\n */\nexport interface Event {\n /**\n * @return {!Path}\n */\n getPath(): Path;\n\n /**\n * @return {!string}\n */\n getEventType(): string;\n\n /**\n * @return {!function()}\n */\n getEventRunner(): () => void;\n\n /**\n * @return {!string}\n */\n toString(): string;\n}\n\n\n/**\n * Encapsulates the data needed to raise an event\n * @implements {Event}\n */\nexport class DataEvent implements Event {\n /**\n * @param {!string} eventType One of: value, child_added, child_changed, child_moved, child_removed\n * @param {!EventRegistration} eventRegistration The function to call to with the event data. User provided\n * @param {!DataSnapshot} snapshot The data backing the event\n * @param {?string=} prevName Optional, the name of the previous child for child_* events.\n */\n constructor(public eventType: 'value' | ' child_added' | ' child_changed' | ' child_moved' | ' child_removed',\n public eventRegistration: EventRegistration,\n public snapshot: DataSnapshot,\n public prevName?: string | null) {\n }\n\n /**\n * @inheritDoc\n */\n getPath(): Path {\n const ref = this.snapshot.getRef();\n if (this.eventType === 'value') {\n return ref.path;\n } else {\n return ref.getParent().path;\n }\n }\n\n /**\n * @inheritDoc\n */\n getEventType(): string {\n return this.eventType;\n }\n\n /**\n * @inheritDoc\n */\n getEventRunner(): () => void {\n return this.eventRegistration.getEventRunner(this);\n }\n\n /**\n * @inheritDoc\n */\n toString(): string {\n return this.getPath().toString() + ':' + this.eventType + ':' +\n stringify(this.snapshot.exportVal());\n }\n}\n\n\nexport class CancelEvent implements Event {\n /**\n * @param {EventRegistration} eventRegistration\n * @param {Error} error\n * @param {!Path} path\n */\n constructor(public eventRegistration: EventRegistration,\n public error: Error,\n public path: Path) {\n }\n\n /**\n * @inheritDoc\n */\n getPath(): Path {\n return this.path;\n }\n\n /**\n * @inheritDoc\n */\n getEventType(): string {\n return 'cancel';\n }\n\n /**\n * @inheritDoc\n */\n getEventRunner(): () => void {\n return this.eventRegistration.getEventRunner(this);\n }\n\n /**\n * @inheritDoc\n */\n toString(): string {\n return this.path.toString() + ':cancel';\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/Event.ts","/**\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\nimport { DataSnapshot } from '../../api/DataSnapshot';\nimport { DataEvent, CancelEvent, Event } from './Event';\nimport { contains, getCount, getAnyKey, every } from '../../../utils/obj';\nimport { assert } from '../../../utils/assert';\nimport { Path } from '../util/Path';\nimport { Change } from './Change';\nimport { Query } from '../../api/Query';\n\n/**\n * An EventRegistration is basically an event type ('value', 'child_added', etc.) and a callback\n * to be notified of that type of event.\n *\n * That said, it can also contain a cancel callback to be notified if the event is canceled. And\n * currently, this code is organized around the idea that you would register multiple child_ callbacks\n * together, as a single EventRegistration. Though currently we don't do that.\n */\nexport interface EventRegistration {\n /**\n * True if this container has a callback to trigger for this event type\n * @param {!string} eventType\n * @return {boolean}\n */\n respondsTo(eventType: string): boolean;\n\n /**\n * @param {!Change} change\n * @param {!Query} query\n * @return {!Event}\n */\n createEvent(change: Change, query: Query): Event;\n\n /**\n * Given event data, return a function to trigger the user's callback\n * @param {!Event} eventData\n * @return {function()}\n */\n getEventRunner(eventData: Event): () => void;\n\n /**\n * @param {!Error} error\n * @param {!Path} path\n * @return {?CancelEvent}\n */\n createCancelEvent(error: Error, path: Path): CancelEvent | null;\n\n /**\n * @param {!EventRegistration} other\n * @return {boolean}\n */\n matches(other: EventRegistration): boolean;\n\n /**\n * False basically means this is a \"dummy\" callback container being used as a sentinel\n * to remove all callback containers of a particular type. (e.g. if the user does\n * ref.off('value') without specifying a specific callback).\n *\n * (TODO: Rework this, since it's hacky)\n *\n * @return {boolean}\n */\n hasAnyCallback(): boolean;\n}\n\n\n/**\n * Represents registration for 'value' events.\n */\nexport class ValueEventRegistration implements EventRegistration {\n /**\n * @param {?function(!DataSnapshot)} callback_\n * @param {?function(Error)} cancelCallback_\n * @param {?Object} context_\n */\n constructor(private callback_: ((d: DataSnapshot) => void) | null,\n private cancelCallback_: ((e: Error) => void) | null,\n private context_: Object | null) {\n }\n\n /**\n * @inheritDoc\n */\n respondsTo(eventType: string): boolean {\n return eventType === 'value';\n }\n\n /**\n * @inheritDoc\n */\n createEvent(change: Change, query: Query): DataEvent {\n const index = query.getQueryParams().getIndex();\n return new DataEvent('value', this, new DataSnapshot(change.snapshotNode, query.getRef(), index));\n }\n\n /**\n * @inheritDoc\n */\n getEventRunner(eventData: CancelEvent | DataEvent): () => void {\n const ctx = this.context_;\n if (eventData.getEventType() === 'cancel') {\n assert(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback');\n const cancelCB = this.cancelCallback_;\n return function () {\n // We know that error exists, we checked above that this is a cancel event\n cancelCB.call(ctx, (eventData as CancelEvent).error);\n };\n } else {\n const cb = this.callback_;\n return function () {\n cb.call(ctx, (eventData as DataEvent).snapshot);\n };\n }\n }\n\n /**\n * @inheritDoc\n */\n createCancelEvent(error: Error, path: Path): CancelEvent | null {\n if (this.cancelCallback_) {\n return new CancelEvent(this, error, path);\n } else {\n return null;\n }\n }\n\n /**\n * @inheritDoc\n */\n matches(other: EventRegistration): boolean {\n if (!(other instanceof ValueEventRegistration)) {\n return false;\n } else if (!other.callback_ || !this.callback_) {\n // If no callback specified, we consider it to match any callback.\n return true;\n } else {\n return other.callback_ === this.callback_ && other.context_ === this.context_;\n }\n }\n\n /**\n * @inheritDoc\n */\n hasAnyCallback(): boolean {\n return this.callback_ !== null;\n }\n}\n\n/**\n * Represents the registration of 1 or more child_xxx events.\n *\n * Currently, it is always exactly 1 child_xxx event, but the idea is we might let you\n * register a group of callbacks together in the future.\n *\n * @constructor\n * @implements {EventRegistration}\n */\nexport class ChildEventRegistration implements EventRegistration {\n /**\n * @param {?Object.} callbacks_\n * @param {?function(Error)} cancelCallback_\n * @param {Object=} context_\n */\n constructor(private callbacks_: ({ [k: string]: (d: DataSnapshot, s?: string | null) => void }) | null,\n private cancelCallback_: ((e: Error) => void) | null,\n private context_?: Object) {\n }\n\n /**\n * @inheritDoc\n */\n respondsTo(eventType: string): boolean {\n let eventToCheck = eventType === 'children_added' ? 'child_added' : eventType;\n eventToCheck = eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;\n return contains(this.callbacks_, eventToCheck);\n }\n\n /**\n * @inheritDoc\n */\n createCancelEvent(error: Error, path: Path): CancelEvent | null {\n if (this.cancelCallback_) {\n return new CancelEvent(this, error, path);\n } else {\n return null;\n }\n }\n\n /**\n * @inheritDoc\n */\n createEvent(change: Change, query: Query): DataEvent {\n assert(change.childName != null, 'Child events should have a childName.');\n const ref = query.getRef().child(/** @type {!string} */ (change.childName));\n const index = query.getQueryParams().getIndex();\n return new DataEvent(change.type as any, this, new DataSnapshot(change.snapshotNode, ref, index as any),\n change.prevName);\n }\n\n /**\n * @inheritDoc\n */\n getEventRunner(eventData: CancelEvent | DataEvent): () => void {\n const ctx = this.context_;\n if (eventData.getEventType() === 'cancel') {\n assert(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback');\n const cancelCB = this.cancelCallback_;\n return function () {\n // We know that error exists, we checked above that this is a cancel event\n cancelCB.call(ctx, (eventData as CancelEvent).error);\n };\n } else {\n const cb = this.callbacks_[(eventData as DataEvent).eventType];\n return function () {\n cb.call(ctx, (eventData as DataEvent).snapshot, (eventData as DataEvent).prevName);\n }\n }\n }\n\n /**\n * @inheritDoc\n */\n matches(other: EventRegistration): boolean {\n if (other instanceof ChildEventRegistration) {\n if (!this.callbacks_ || !other.callbacks_) {\n return true;\n } else if (this.context_ === other.context_) {\n const otherCount = getCount(other.callbacks_);\n const thisCount = getCount(this.callbacks_);\n if (otherCount === thisCount) {\n // If count is 1, do an exact match on eventType, if either is defined but null, it's a match.\n // If event types don't match, not a match\n // If count is not 1, exact match across all\n\n if (otherCount === 1) {\n const otherKey = /** @type {!string} */ (getAnyKey(other.callbacks_));\n const thisKey = /** @type {!string} */ (getAnyKey(this.callbacks_));\n return (thisKey === otherKey && (\n !other.callbacks_[otherKey] ||\n !this.callbacks_[thisKey] ||\n other.callbacks_[otherKey] === this.callbacks_[thisKey]\n )\n );\n } else {\n // Exact match on each key.\n return every(this.callbacks_, (eventType, cb) => other.callbacks_[eventType] === cb);\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * @inheritDoc\n */\n hasAnyCallback(): boolean {\n return (this.callbacks_ !== null);\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/EventRegistration.ts","/**\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\nimport { isEmpty, getCount, forEach, contains } from '../../../utils/obj';\n\n/**\n * Implements a set with a count of elements.\n *\n * @template K, V\n */\nexport class CountedSet {\n set: { [k: string]: V } = {};\n\n /**\n * @param {!K} item\n * @param {V} val\n */\n add(item: K, val: V) {\n this.set[item as any] = val !== null ? val : (true as any);\n }\n\n /**\n * @param {!K} key\n * @return {boolean}\n */\n contains(key: K) {\n return contains(this.set, key);\n }\n\n /**\n * @param {!K} item\n * @return {V}\n */\n get(item: K): V | void {\n return this.contains(item) ? this.set[item as any] : undefined;\n }\n\n /**\n * @param {!K} item\n */\n remove(item: K) {\n delete this.set[item as any];\n }\n\n /**\n * Deletes everything in the set\n */\n clear() {\n this.set = {};\n }\n\n /**\n * True if there's nothing in the set\n * @return {boolean}\n */\n isEmpty(): boolean {\n return isEmpty(this.set);\n }\n\n /**\n * @return {number} The number of items in the set\n */\n count(): number {\n return getCount(this.set);\n }\n\n /**\n * Run a function on each k,v pair in the set\n * @param {function(K, V)} fn\n */\n each(fn: (k: K, v: V) => void) {\n forEach(this.set, (k: K, v: V) => fn(k, v));\n }\n\n /**\n * Mostly for debugging\n * @return {Array.} The keys present in this CountedSet\n */\n keys(): K[] {\n const keys: K[] = [];\n forEach(this.set, (k: K) => {\n keys.push(k);\n });\n return keys;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/CountedSet.ts","/**\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\nimport { Path } from \"./util/Path\";\nimport { PRIORITY_INDEX } from \"./snap/indexes/PriorityIndex\";\nimport { CountedSet } from \"./util/CountedSet\";\nimport { Node } from './snap/Node';\n\n/**\n * Helper class to store a sparse set of snapshots.\n *\n * @constructor\n */\nexport class SparseSnapshotTree {\n /**\n * @private\n * @type {Node}\n */\n private value_: Node | null = null;\n\n /**\n * @private\n * @type {CountedSet}\n */\n private children_: CountedSet | null = null;\n\n /**\n * Gets the node stored at the given path if one exists.\n *\n * @param {!Path} path Path to look up snapshot for.\n * @return {?Node} The retrieved node, or null.\n */\n find(path: Path): Node | null {\n if (this.value_ != null) {\n return this.value_.getChild(path);\n } else if (!path.isEmpty() && this.children_ != null) {\n const childKey = path.getFront();\n path = path.popFront();\n if (this.children_.contains(childKey)) {\n const childTree = this.children_.get(childKey) as SparseSnapshotTree;\n return childTree.find(path);\n } else {\n return null;\n }\n } else {\n return null;\n }\n }\n\n /**\n * Stores the given node at the specified path. If there is already a node\n * at a shallower path, it merges the new data into that snapshot node.\n *\n * @param {!Path} path Path to look up snapshot for.\n * @param {!Node} data The new data, or null.\n */\n remember(path: Path, data: Node) {\n if (path.isEmpty()) {\n this.value_ = data;\n this.children_ = null;\n } else if (this.value_ !== null) {\n this.value_ = this.value_.updateChild(path, data);\n } else {\n if (this.children_ == null) {\n this.children_ = new CountedSet();\n }\n\n const childKey = path.getFront();\n if (!this.children_.contains(childKey)) {\n this.children_.add(childKey, new SparseSnapshotTree());\n }\n\n const child = this.children_.get(childKey) as SparseSnapshotTree;\n path = path.popFront();\n child.remember(path, data);\n }\n }\n\n /**\n * Purge the data at path from the cache.\n *\n * @param {!Path} path Path to look up snapshot for.\n * @return {boolean} True if this node should now be removed.\n */\n forget(path: Path): boolean {\n if (path.isEmpty()) {\n this.value_ = null;\n this.children_ = null;\n return true;\n } else {\n if (this.value_ !== null) {\n if (this.value_.isLeafNode()) {\n // We're trying to forget a node that doesn't exist\n return false;\n } else {\n const value = this.value_;\n this.value_ = null;\n\n const self = this;\n value.forEachChild(PRIORITY_INDEX, function(key, tree) {\n self.remember(new Path(key), tree);\n });\n\n return this.forget(path);\n }\n } else if (this.children_ !== null) {\n const childKey = path.getFront();\n path = path.popFront();\n if (this.children_.contains(childKey)) {\n const safeToRemove = (this.children_.get(childKey) as SparseSnapshotTree).forget(path);\n if (safeToRemove) {\n this.children_.remove(childKey);\n }\n }\n\n if (this.children_.isEmpty()) {\n this.children_ = null;\n return true;\n } else {\n return false;\n }\n\n } else {\n return true;\n }\n }\n }\n\n /**\n * Recursively iterates through all of the stored tree and calls the\n * callback on each one.\n *\n * @param {!Path} prefixPath Path to look up node for.\n * @param {!Function} func The function to invoke for each tree.\n */\n forEachTree(prefixPath: Path, func: (a: Path, b: Node) => any) {\n if (this.value_ !== null) {\n func(prefixPath, this.value_);\n } else {\n this.forEachChild((key, tree) => {\n const path = new Path(prefixPath.toString() + '/' + key);\n tree.forEachTree(path, func);\n });\n }\n }\n\n /**\n * Iterates through each immediate child and triggers the callback.\n *\n * @param {!Function} func The function to invoke for each child.\n */\n forEachChild(func: (a: string, b: SparseSnapshotTree) => void) {\n if (this.children_ !== null) {\n this.children_.each((key, tree) => {\n func(key, tree);\n });\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/SparseSnapshotTree.ts","/**\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\nimport { assert } from '../../../utils/assert';\nimport { Path } from './Path';\nimport { SparseSnapshotTree } from '../SparseSnapshotTree';\nimport { LeafNode } from '../snap/LeafNode';\nimport { nodeFromJSON } from '../snap/nodeFromJSON';\nimport { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';\nimport { Node } from '../snap/Node';\nimport { ChildrenNode } from '../snap/ChildrenNode';\n\n/**\n * Generate placeholders for deferred values.\n * @param {?Object} values\n * @return {!Object}\n */\nexport const generateWithValues = function (values: { [k: string]: any } | null): { [k: string]: any } {\n values = values || {};\n values['timestamp'] = values['timestamp'] || new Date().getTime();\n return values;\n};\n\n\n/**\n * Value to use when firing local events. When writing server values, fire\n * local events with an approximate value, otherwise return value as-is.\n * @param {(Object|string|number|boolean)} value\n * @param {!Object} serverValues\n * @return {!(string|number|boolean)}\n */\nexport const resolveDeferredValue = function (value: { [k: string]: any } | string | number | boolean,\n serverValues: { [k: string]: any }): string | number | boolean {\n if (!value || (typeof value !== 'object')) {\n return value as string | number | boolean;\n } else {\n assert('.sv' in value, 'Unexpected leaf node or priority contents');\n return serverValues[value['.sv']];\n }\n};\n\n\n/**\n * Recursively replace all deferred values and priorities in the tree with the\n * specified generated replacement values.\n * @param {!SparseSnapshotTree} tree\n * @param {!Object} serverValues\n * @return {!SparseSnapshotTree}\n */\nexport const resolveDeferredValueTree = function (tree: SparseSnapshotTree, serverValues: Object): SparseSnapshotTree {\n const resolvedTree = new SparseSnapshotTree();\n tree.forEachTree(new Path(''), function (path, node) {\n resolvedTree.remember(path, resolveDeferredValueSnapshot(node, serverValues));\n });\n return resolvedTree;\n};\n\n\n/**\n * Recursively replace all deferred values and priorities in the node with the\n * specified generated replacement values. If there are no server values in the node,\n * it'll be returned as-is.\n * @param {!Node} node\n * @param {!Object} serverValues\n * @return {!Node}\n */\nexport const resolveDeferredValueSnapshot = function (node: Node, serverValues: Object): Node {\n const rawPri = node.getPriority().val() as object | boolean | null | number | string;\n const priority = resolveDeferredValue(rawPri, serverValues);\n let newNode: Node;\n\n if (node.isLeafNode()) {\n const leafNode = node as LeafNode;\n const value = resolveDeferredValue(leafNode.getValue(), serverValues);\n if (value !== leafNode.getValue() || priority !== leafNode.getPriority().val()) {\n return new LeafNode(value, nodeFromJSON(priority));\n } else {\n return node;\n }\n } else {\n const childrenNode = node as ChildrenNode;\n newNode = childrenNode;\n if (priority !== childrenNode.getPriority().val()) {\n newNode = newNode.updatePriority(new LeafNode(priority));\n }\n childrenNode.forEachChild(PRIORITY_INDEX, function (childName, childNode) {\n const newChildNode = resolveDeferredValueSnapshot(childNode, serverValues);\n if (newChildNode !== childNode) {\n newNode = newNode.updateImmediateChild(childName, newChildNode);\n }\n });\n return newNode;\n }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/ServerValues.ts","/**\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\nimport { assert } from \"../../../utils/assert\";\nimport { Path } from \"../util/Path\";\nimport { Operation, OperationSource, OperationType } from './Operation';\nimport { ImmutableTree } from '../util/ImmutableTree';\n\nexport class AckUserWrite implements Operation {\n /** @inheritDoc */\n type = OperationType.ACK_USER_WRITE;\n\n /** @inheritDoc */\n source = OperationSource.User;\n\n /**\n *\n * @param {!Path} path\n * @param {!ImmutableTree} affectedTree A tree containing true for each affected path. Affected paths can't overlap.\n * @param {!boolean} revert\n */\n constructor(/**@inheritDoc */ public path: Path,\n /**@inheritDoc */ public affectedTree: ImmutableTree,\n /**@inheritDoc */ public revert: boolean) {\n\n }\n\n /**\n * @inheritDoc\n */\n operationForChild(childName: string): AckUserWrite {\n if (!this.path.isEmpty()) {\n assert(this.path.getFront() === childName, 'operationForChild called for unrelated child.');\n return new AckUserWrite(this.path.popFront(), this.affectedTree, this.revert);\n } else if (this.affectedTree.value != null) {\n assert(this.affectedTree.children.isEmpty(),\n 'affectedTree should not have overlapping affected paths.');\n // All child locations are affected as well; just return same operation.\n return this;\n } else {\n const childTree = this.affectedTree.subtree(new Path(childName));\n return new AckUserWrite(Path.Empty, childTree, this.revert);\n }\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/operation/AckUserWrite.ts","/**\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\nimport { SortedMap } from './SortedMap';\nimport { Path } from './Path';\nimport { stringCompare } from './util';\nimport { forEach } from '../../../utils/obj';\n\nlet emptyChildrenSingleton: SortedMap>;\n\n/**\n * Singleton empty children collection.\n *\n * @const\n * @type {!SortedMap.>}\n */\nconst EmptyChildren = (): SortedMap> => {\n if (!emptyChildrenSingleton) {\n emptyChildrenSingleton = new SortedMap>(stringCompare);\n }\n return emptyChildrenSingleton;\n};\n\n/**\n * A tree with immutable elements.\n */\nexport class ImmutableTree {\n static Empty = new ImmutableTree(null);\n\n /**\n * @template T\n * @param {!Object.} obj\n * @return {!ImmutableTree.}\n */\n static fromObject(obj: { [k: string]: T }): ImmutableTree {\n let tree: ImmutableTree = ImmutableTree.Empty;\n forEach(obj, (childPath: string, childSnap: T) => {\n tree = tree.set(new Path(childPath), childSnap);\n });\n return tree;\n }\n\n /**\n * @template T\n * @param {?T} value\n * @param {SortedMap.>=} children\n */\n constructor(public readonly value: T | null,\n public readonly children: SortedMap> = EmptyChildren()) {\n }\n\n /**\n * True if the value is empty and there are no children\n * @return {boolean}\n */\n isEmpty(): boolean {\n return this.value === null && this.children.isEmpty();\n }\n\n /**\n * Given a path and predicate, return the first node and the path to that node\n * where the predicate returns true.\n *\n * TODO Do a perf test -- If we're creating a bunch of {path: value:} objects\n * on the way back out, it may be better to pass down a pathSoFar obj.\n *\n * @param {!Path} relativePath The remainder of the path\n * @param {function(T):boolean} predicate The predicate to satisfy to return a\n * node\n * @return {?{path:!Path, value:!T}}\n */\n findRootMostMatchingPathAndValue(relativePath: Path,\n predicate: (a: T) => boolean): { path: Path, value: T } | null {\n if (this.value != null && predicate(this.value)) {\n return {path: Path.Empty, value: this.value};\n } else {\n if (relativePath.isEmpty()) {\n return null;\n } else {\n const front = relativePath.getFront();\n const child = this.children.get(front);\n if (child !== null) {\n const childExistingPathAndValue =\n child.findRootMostMatchingPathAndValue(relativePath.popFront(),\n predicate);\n if (childExistingPathAndValue != null) {\n const fullPath = new Path(front).child(childExistingPathAndValue.path);\n return {path: fullPath, value: childExistingPathAndValue.value};\n } else {\n return null;\n }\n } else {\n return null;\n }\n }\n }\n }\n\n /**\n * Find, if it exists, the shortest subpath of the given path that points a defined\n * value in the tree\n * @param {!Path} relativePath\n * @return {?{path: !Path, value: !T}}\n */\n findRootMostValueAndPath(relativePath: Path): { path: Path, value: T } | null {\n return this.findRootMostMatchingPathAndValue(relativePath, () => true);\n }\n\n /**\n * @param {!Path} relativePath\n * @return {!ImmutableTree.} The subtree at the given path\n */\n subtree(relativePath: Path): ImmutableTree {\n if (relativePath.isEmpty()) {\n return this;\n } else {\n const front = relativePath.getFront();\n const childTree = this.children.get(front);\n if (childTree !== null) {\n return childTree.subtree(relativePath.popFront());\n } else {\n return ImmutableTree.Empty;\n }\n }\n }\n\n /**\n * Sets a value at the specified path.\n *\n * @param {!Path} relativePath Path to set value at.\n * @param {?T} toSet Value to set.\n * @return {!ImmutableTree.} Resulting tree.\n */\n set(relativePath: Path, toSet: T | null): ImmutableTree {\n if (relativePath.isEmpty()) {\n return new ImmutableTree(toSet, this.children);\n } else {\n const front = relativePath.getFront();\n const child = this.children.get(front) || ImmutableTree.Empty;\n const newChild = child.set(relativePath.popFront(), toSet);\n const newChildren = this.children.insert(front, newChild);\n return new ImmutableTree(this.value, newChildren);\n }\n }\n\n /**\n * Removes the value at the specified path.\n *\n * @param {!Path} relativePath Path to value to remove.\n * @return {!ImmutableTree.} Resulting tree.\n */\n remove(relativePath: Path): ImmutableTree {\n if (relativePath.isEmpty()) {\n if (this.children.isEmpty()) {\n return ImmutableTree.Empty;\n } else {\n return new ImmutableTree(null, this.children);\n }\n } else {\n const front = relativePath.getFront();\n const child = this.children.get(front);\n if (child) {\n const newChild = child.remove(relativePath.popFront());\n let newChildren;\n if (newChild.isEmpty()) {\n newChildren = this.children.remove(front);\n } else {\n newChildren = this.children.insert(front, newChild);\n }\n if (this.value === null && newChildren.isEmpty()) {\n return ImmutableTree.Empty;\n } else {\n return new ImmutableTree(this.value, newChildren);\n }\n } else {\n return this;\n }\n }\n }\n\n /**\n * Gets a value from the tree.\n *\n * @param {!Path} relativePath Path to get value for.\n * @return {?T} Value at path, or null.\n */\n get(relativePath: Path): T | null {\n if (relativePath.isEmpty()) {\n return this.value;\n } else {\n const front = relativePath.getFront();\n const child = this.children.get(front);\n if (child) {\n return child.get(relativePath.popFront());\n } else {\n return null;\n }\n }\n }\n\n /**\n * Replace the subtree at the specified path with the given new tree.\n *\n * @param {!Path} relativePath Path to replace subtree for.\n * @param {!ImmutableTree} newTree New tree.\n * @return {!ImmutableTree} Resulting tree.\n */\n setTree(relativePath: Path, newTree: ImmutableTree): ImmutableTree {\n if (relativePath.isEmpty()) {\n return newTree;\n } else {\n const front = relativePath.getFront();\n const child = this.children.get(front) || ImmutableTree.Empty;\n const newChild = child.setTree(relativePath.popFront(), newTree);\n let newChildren;\n if (newChild.isEmpty()) {\n newChildren = this.children.remove(front);\n } else {\n newChildren = this.children.insert(front, newChild);\n }\n return new ImmutableTree(this.value, newChildren);\n }\n }\n\n /**\n * Performs a depth first fold on this tree. Transforms a tree into a single\n * value, given a function that operates on the path to a node, an optional\n * current value, and a map of child names to folded subtrees\n * @template V\n * @param {function(Path, ?T, Object.):V} fn\n * @return {V}\n */\n fold(fn: (path: Path, value: T, children: { [k: string]: V }) => V): V {\n return this.fold_(Path.Empty, fn);\n }\n\n /**\n * Recursive helper for public-facing fold() method\n * @template V\n * @param {!Path} pathSoFar\n * @param {function(Path, ?T, Object.):V} fn\n * @return {V}\n * @private\n */\n private fold_(pathSoFar: Path, fn: (path: Path, value: T | null, children: { [k: string]: V }) => V): V {\n const accum: {[k: string]: V} = {};\n this.children.inorderTraversal(function (childKey: string, childTree: ImmutableTree) {\n accum[childKey] = childTree.fold_(pathSoFar.child(childKey), fn);\n });\n return fn(pathSoFar, this.value, accum);\n }\n\n /**\n * Find the first matching value on the given path. Return the result of applying f to it.\n * @template V\n * @param {!Path} path\n * @param {!function(!Path, !T):?V} f\n * @return {?V}\n */\n findOnPath(path: Path, f: (path: Path, value: T) => (V | null)): V | null {\n return this.findOnPath_(path, Path.Empty, f);\n }\n\n private findOnPath_(pathToFollow: Path, pathSoFar: Path, f: (path: Path, value: T) => (V | null)): V | null {\n const result = this.value ? f(pathSoFar, this.value) : false;\n if (result) {\n return result;\n } else {\n if (pathToFollow.isEmpty()) {\n return null;\n } else {\n const front = pathToFollow.getFront()!;\n const nextChild = this.children.get(front);\n if (nextChild) {\n return nextChild.findOnPath_(pathToFollow.popFront(), pathSoFar.child(front), f);\n } else {\n return null;\n }\n }\n }\n }\n\n /**\n *\n * @param {!Path} path\n * @param {!function(!Path, !T)} f\n * @returns {!ImmutableTree.}\n */\n foreachOnPath(path: Path, f: (path: Path, value: T) => void): ImmutableTree {\n return this.foreachOnPath_(path, Path.Empty, f);\n }\n\n private foreachOnPath_(pathToFollow: Path, currentRelativePath: Path,\n f: (path: Path, value: T) => void): ImmutableTree {\n if (pathToFollow.isEmpty()) {\n return this;\n } else {\n if (this.value) {\n f(currentRelativePath, this.value);\n }\n const front = pathToFollow.getFront();\n const nextChild = this.children.get(front);\n if (nextChild) {\n return nextChild.foreachOnPath_(pathToFollow.popFront(),\n currentRelativePath.child(front), f);\n } else {\n return ImmutableTree.Empty;\n }\n }\n }\n\n /**\n * Calls the given function for each node in the tree that has a value.\n *\n * @param {function(!Path, !T)} f A function to be called with\n * the path from the root of the tree to a node, and the value at that node.\n * Called in depth-first order.\n */\n foreach(f: (path: Path, value: T) => void) {\n this.foreach_(Path.Empty, f);\n }\n\n private foreach_(currentRelativePath: Path, f: (path: Path, value: T) => void) {\n this.children.inorderTraversal(function (childName, childTree) {\n childTree.foreach_(currentRelativePath.child(childName), f);\n });\n if (this.value) {\n f(currentRelativePath, this.value);\n }\n }\n\n /**\n *\n * @param {function(string, !T)} f\n */\n foreachChild(f: (name: string, value: T) => void) {\n this.children.inorderTraversal((childName: string, childTree: ImmutableTree) => {\n if (childTree.value) {\n f(childName, childTree.value);\n }\n });\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/ImmutableTree.ts","/**\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\nimport { Path } from \"../util/Path\";\nimport { Operation, OperationSource, OperationType } from './Operation';\n\n/**\n * @param {!OperationSource} source\n * @param {!Path} path\n * @constructor\n * @implements {Operation}\n */\nexport class ListenComplete implements Operation {\n /** @inheritDoc */\n type = OperationType.LISTEN_COMPLETE;\n\n constructor(public source: OperationSource, public path: Path) {\n }\n\n operationForChild(childName: string): ListenComplete {\n if (this.path.isEmpty()) {\n return new ListenComplete(this.source, Path.Empty);\n } else {\n return new ListenComplete(this.source, this.path.popFront());\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/operation/ListenComplete.ts","/**\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\nimport { Operation, OperationSource, OperationType } from './Operation';\nimport { Path } from \"../util/Path\";\nimport { Node } from '../snap/Node';\n\n/**\n * @param {!OperationSource} source\n * @param {!Path} path\n * @param {!Node} snap\n * @constructor\n * @implements {Operation}\n */\nexport class Overwrite implements Operation {\n /** @inheritDoc */\n type = OperationType.OVERWRITE;\n\n constructor(public source: OperationSource,\n public path: Path,\n public snap: Node) {\n }\n\n operationForChild(childName: string): Overwrite {\n if (this.path.isEmpty()) {\n return new Overwrite(this.source, Path.Empty,\n this.snap.getImmediateChild(childName));\n } else {\n return new Overwrite(this.source, this.path.popFront(), this.snap);\n }\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/operation/Overwrite.ts","/**\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\nimport { Operation, OperationSource, OperationType } from './Operation';\nimport { Overwrite } from \"./Overwrite\";\nimport { Path } from \"../util/Path\";\nimport { assert } from \"../../../utils/assert\";\nimport { ImmutableTree } from '../util/ImmutableTree';\nimport { Node } from '../snap/Node';\n\n/**\n * @param {!OperationSource} source\n * @param {!Path} path\n * @param {!ImmutableTree.} children\n * @constructor\n * @implements {Operation}\n */\nexport class Merge implements Operation {\n /** @inheritDoc */\n type = OperationType.MERGE;\n\n constructor(/**@inheritDoc */ public source: OperationSource,\n /**@inheritDoc */ public path: Path,\n /**@inheritDoc */ public children: ImmutableTree) {\n }\n\n /**\n * @inheritDoc\n */\n operationForChild(childName: string): Operation {\n if (this.path.isEmpty()) {\n const childTree = this.children.subtree(new Path(childName));\n if (childTree.isEmpty()) {\n // This child is unaffected\n return null;\n } else if (childTree.value) {\n // We have a snapshot for the child in question. This becomes an overwrite of the child.\n return new Overwrite(this.source, Path.Empty, childTree.value);\n } else {\n // This is a merge at a deeper level\n return new Merge(this.source, Path.Empty, childTree);\n }\n } else {\n assert(this.path.getFront() === childName,\n 'Can\\'t get a merge for a child not on the path of the operation');\n return new Merge(this.source, this.path.popFront(), this.children);\n }\n }\n\n /**\n * @inheritDoc\n */\n toString(): string {\n return 'Operation(' + this.path + ': ' + this.source.toString() + ' merge: ' + this.children.toString() + ')';\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/operation/Merge.ts","/**\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\nimport { Node } from '../snap/Node';\nimport { Path } from '../util/Path';\n\n/**\n * A cache node only stores complete children. Additionally it holds a flag whether the node can be considered fully\n * initialized in the sense that we know at one point in time this represented a valid state of the world, e.g.\n * initialized with data from the server, or a complete overwrite by the client. The filtered flag also tracks\n * whether a node potentially had children removed due to a filter.\n */\nexport class CacheNode {\n /**\n * @param {!Node} node_\n * @param {boolean} fullyInitialized_\n * @param {boolean} filtered_\n */\n constructor(private node_: Node,\n private fullyInitialized_: boolean,\n private filtered_: boolean) {\n\n }\n\n /**\n * Returns whether this node was fully initialized with either server data or a complete overwrite by the client\n * @return {boolean}\n */\n isFullyInitialized(): boolean {\n return this.fullyInitialized_;\n }\n\n /**\n * Returns whether this node is potentially missing children due to a filter applied to the node\n * @return {boolean}\n */\n isFiltered(): boolean {\n return this.filtered_;\n }\n\n /**\n * @param {!Path} path\n * @return {boolean}\n */\n isCompleteForPath(path: Path): boolean {\n if (path.isEmpty()) {\n return this.isFullyInitialized() && !this.filtered_;\n }\n\n const childKey = path.getFront();\n return this.isCompleteForChild(childKey);\n }\n\n /**\n * @param {!string} key\n * @return {boolean}\n */\n isCompleteForChild(key: string): boolean {\n return (this.isFullyInitialized() && !this.filtered_) || this.node_.hasChild(key);\n }\n\n /**\n * @return {!Node}\n */\n getNode(): Node {\n return this.node_;\n }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/CacheNode.ts","/**\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\nimport { ChildrenNode } from '../snap/ChildrenNode';\nimport { CacheNode } from './CacheNode';\nimport { Node } from '../snap/Node';\n\n/**\n * Stores the data we have cached for a view.\n *\n * serverSnap is the cached server data, eventSnap is the cached event data (server data plus any local writes).\n *\n * @constructor\n */\nexport class ViewCache {\n /**\n *\n * @param {!CacheNode} eventCache_\n * @param {!CacheNode} serverCache_\n */\n constructor(private readonly eventCache_: CacheNode,\n private readonly serverCache_: CacheNode) {\n }\n\n /**\n * @const\n * @type {ViewCache}\n */\n static Empty = new ViewCache(\n new CacheNode(ChildrenNode.EMPTY_NODE, /*fullyInitialized=*/false, /*filtered=*/false),\n new CacheNode(ChildrenNode.EMPTY_NODE, /*fullyInitialized=*/false, /*filtered=*/false)\n );\n\n /**\n * @param {!Node} eventSnap\n * @param {boolean} complete\n * @param {boolean} filtered\n * @return {!ViewCache}\n */\n updateEventSnap(eventSnap: Node, complete: boolean, filtered: boolean): ViewCache {\n return new ViewCache(new CacheNode(eventSnap, complete, filtered), this.serverCache_);\n }\n\n /**\n * @param {!Node} serverSnap\n * @param {boolean} complete\n * @param {boolean} filtered\n * @return {!ViewCache}\n */\n updateServerSnap(serverSnap: Node, complete: boolean, filtered: boolean): ViewCache {\n return new ViewCache(this.eventCache_, new CacheNode(serverSnap, complete, filtered));\n }\n\n /**\n * @return {!CacheNode}\n */\n getEventCache(): CacheNode {\n return this.eventCache_;\n }\n\n /**\n * @return {?Node}\n */\n getCompleteEventSnap(): Node | null {\n return (this.eventCache_.isFullyInitialized()) ? this.eventCache_.getNode() : null;\n }\n\n /**\n * @return {!CacheNode}\n */\n getServerCache(): CacheNode {\n return this.serverCache_;\n }\n\n /**\n * @return {?Node}\n */\n getCompleteServerSnap(): Node | null {\n return this.serverCache_.isFullyInitialized() ? this.serverCache_.getNode() : null;\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/ViewCache.ts","/**\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\nimport { Node } from '../snap/Node';\n\n/**\n * @constructor\n * @struct\n * @param {!string} type The event type\n * @param {!Node} snapshotNode The data\n * @param {string=} childName The name for this child, if it's a child event\n * @param {Node=} oldSnap Used for intermediate processing of child changed events\n * @param {string=} prevName The name for the previous child, if applicable\n */\nexport class Change {\n constructor(public type: string,\n public snapshotNode: Node,\n public childName?: string,\n public oldSnap?: Node,\n public prevName?: string) {\n };\n\n /**\n * @param {!Node} snapshot\n * @return {!Change}\n */\n static valueChange(snapshot: Node): Change {\n return new Change(Change.VALUE, snapshot);\n };\n\n /**\n * @param {string} childKey\n * @param {!Node} snapshot\n * @return {!Change}\n */\n static childAddedChange(childKey: string, snapshot: Node): Change {\n return new Change(Change.CHILD_ADDED, snapshot, childKey);\n };\n\n /**\n * @param {string} childKey\n * @param {!Node} snapshot\n * @return {!Change}\n */\n static childRemovedChange(childKey: string, snapshot: Node): Change {\n return new Change(Change.CHILD_REMOVED, snapshot, childKey);\n };\n\n /**\n * @param {string} childKey\n * @param {!Node} newSnapshot\n * @param {!Node} oldSnapshot\n * @return {!Change}\n */\n static childChangedChange(childKey: string, newSnapshot: Node, oldSnapshot: Node): Change {\n return new Change(Change.CHILD_CHANGED, newSnapshot, childKey, oldSnapshot);\n };\n\n /**\n * @param {string} childKey\n * @param {!Node} snapshot\n * @return {!Change}\n */\n static childMovedChange(childKey: string, snapshot: Node): Change {\n return new Change(Change.CHILD_MOVED, snapshot, childKey);\n };\n\n //event types\n /** Event type for a child added */\n static CHILD_ADDED = 'child_added';\n\n /** Event type for a child removed */\n static CHILD_REMOVED = 'child_removed';\n\n /** Event type for a child changed */\n static CHILD_CHANGED = 'child_changed';\n\n /** Event type for a child moved */\n static CHILD_MOVED = 'child_moved';\n\n /** Event type for a value change */\n static VALUE = 'value';\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/Change.ts","/**\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\nimport { assert } from \"../../../../utils/assert\";\nimport { Change } from \"../Change\";\nimport { ChildrenNode } from \"../../snap/ChildrenNode\";\nimport { PRIORITY_INDEX } from \"../../snap/indexes/PriorityIndex\";\nimport { NodeFilter } from './NodeFilter';\nimport { Index } from '../../snap/indexes/Index';\nimport { Path } from '../../util/Path';\nimport { CompleteChildSource } from '../CompleteChildSource';\nimport { ChildChangeAccumulator } from '../ChildChangeAccumulator';\nimport { Node } from '../../snap/Node';\n\n/**\n * Doesn't really filter nodes but applies an index to the node and keeps track of any changes\n *\n * @constructor\n * @implements {NodeFilter}\n * @param {!Index} index\n */\nexport class IndexedFilter implements NodeFilter {\n constructor(private readonly index_: Index) {\n }\n\n updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path,\n source: CompleteChildSource,\n optChangeAccumulator: ChildChangeAccumulator | null): Node {\n assert(snap.isIndexed(this.index_), 'A node must be indexed if only a child is updated');\n const oldChild = snap.getImmediateChild(key);\n // Check if anything actually changed.\n if (oldChild.getChild(affectedPath).equals(newChild.getChild(affectedPath))) {\n // There's an edge case where a child can enter or leave the view because affectedPath was set to null.\n // In this case, affectedPath will appear null in both the old and new snapshots. So we need\n // to avoid treating these cases as \"nothing changed.\"\n if (oldChild.isEmpty() == newChild.isEmpty()) {\n // Nothing changed.\n\n // This assert should be valid, but it's expensive (can dominate perf testing) so don't actually do it.\n //assert(oldChild.equals(newChild), 'Old and new snapshots should be equal.');\n return snap;\n }\n }\n\n if (optChangeAccumulator != null) {\n if (newChild.isEmpty()) {\n if (snap.hasChild(key)) {\n optChangeAccumulator.trackChildChange(Change.childRemovedChange(key, oldChild));\n } else {\n assert(snap.isLeafNode(), 'A child remove without an old child only makes sense on a leaf node');\n }\n } else if (oldChild.isEmpty()) {\n optChangeAccumulator.trackChildChange(Change.childAddedChange(key, newChild));\n } else {\n optChangeAccumulator.trackChildChange(Change.childChangedChange(key, newChild, oldChild));\n }\n }\n if (snap.isLeafNode() && newChild.isEmpty()) {\n return snap;\n } else {\n // Make sure the node is indexed\n return snap.updateImmediateChild(key, newChild).withIndex(this.index_);\n }\n };\n\n /**\n * @inheritDoc\n */\n updateFullNode(oldSnap: Node, newSnap: Node,\n optChangeAccumulator: ChildChangeAccumulator | null): Node {\n if (optChangeAccumulator != null) {\n if (!oldSnap.isLeafNode()) {\n oldSnap.forEachChild(PRIORITY_INDEX, function(key, childNode) {\n if (!newSnap.hasChild(key)) {\n optChangeAccumulator.trackChildChange(Change.childRemovedChange(key, childNode));\n }\n });\n }\n if (!newSnap.isLeafNode()) {\n newSnap.forEachChild(PRIORITY_INDEX, function(key, childNode) {\n if (oldSnap.hasChild(key)) {\n const oldChild = oldSnap.getImmediateChild(key);\n if (!oldChild.equals(childNode)) {\n optChangeAccumulator.trackChildChange(Change.childChangedChange(key, childNode, oldChild));\n }\n } else {\n optChangeAccumulator.trackChildChange(Change.childAddedChange(key, childNode));\n }\n });\n }\n }\n return newSnap.withIndex(this.index_);\n };\n\n /**\n * @inheritDoc\n */\n updatePriority(oldSnap: Node, newPriority: Node): Node {\n if (oldSnap.isEmpty()) {\n return ChildrenNode.EMPTY_NODE;\n } else {\n return oldSnap.updatePriority(newPriority);\n }\n };\n\n /**\n * @inheritDoc\n */\n filtersNodes(): boolean {\n return false;\n };\n\n /**\n * @inheritDoc\n */\n getIndexedFilter(): IndexedFilter {\n return this;\n };\n\n /**\n * @inheritDoc\n */\n getIndex(): Index {\n return this.index_;\n };\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/filter/IndexedFilter.ts","/**\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\nimport { CacheNode } from './view/CacheNode';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { assert } from '../../utils/assert';\nimport { isEmpty, forEach, findValue, safeGet } from '../../utils/obj';\nimport { ViewCache } from './view/ViewCache';\nimport { View } from './view/View';\nimport { Operation } from './operation/Operation';\nimport { WriteTreeRef } from './WriteTree';\nimport { Query } from '../api/Query';\nimport { EventRegistration } from './view/EventRegistration';\nimport { Node } from './snap/Node';\nimport { Path } from './util/Path';\nimport { Event } from './view/Event';\nimport { Reference, ReferenceConstructor } from '../api/Reference';\n\nlet __referenceConstructor: ReferenceConstructor;\n\n/**\n * SyncPoint represents a single location in a SyncTree with 1 or more event registrations, meaning we need to\n * maintain 1 or more Views at this location to cache server data and raise appropriate events for server changes\n * and user writes (set, transaction, update).\n *\n * It's responsible for:\n * - Maintaining the set of 1 or more views necessary at this location (a SyncPoint with 0 views should be removed).\n * - Proxying user / server operations to the views as appropriate (i.e. applyServerOverwrite,\n * applyUserOverwrite, etc.)\n */\nexport class SyncPoint {\n static set __referenceConstructor(val: ReferenceConstructor) {\n assert(!__referenceConstructor, '__referenceConstructor has already been defined');\n __referenceConstructor = val;\n }\n\n static get __referenceConstructor() {\n assert(__referenceConstructor, 'Reference.ts has not been loaded');\n return __referenceConstructor;\n }\n\n /**\n * The Views being tracked at this location in the tree, stored as a map where the key is a\n * queryId and the value is the View for that query.\n *\n * NOTE: This list will be quite small (usually 1, but perhaps 2 or 3; any more is an odd use case).\n *\n * @type {!Object.}\n * @private\n */\n private views_: { [k: string]: View } = {};\n\n /**\n * @return {boolean}\n */\n isEmpty(): boolean {\n return isEmpty(this.views_);\n }\n\n /**\n *\n * @param {!Operation} operation\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} optCompleteServerCache\n * @return {!Array.}\n */\n applyOperation(operation: Operation, writesCache: WriteTreeRef,\n optCompleteServerCache: Node | null): Event[] {\n const queryId = operation.source.queryId;\n if (queryId !== null) {\n const view = safeGet(this.views_, queryId);\n assert(view != null, 'SyncTree gave us an op for an invalid query.');\n return view.applyOperation(operation, writesCache, optCompleteServerCache);\n } else {\n let events: Event[] = [];\n\n forEach(this.views_, function (key: string, view: View) {\n events = events.concat(view.applyOperation(operation, writesCache, optCompleteServerCache));\n });\n\n return events;\n }\n }\n\n /**\n * Add an event callback for the specified query.\n *\n * @param {!Query} query\n * @param {!EventRegistration} eventRegistration\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} serverCache Complete server cache, if we have it.\n * @param {boolean} serverCacheComplete\n * @return {!Array.} Events to raise.\n */\n addEventRegistration(query: Query, eventRegistration: EventRegistration, writesCache: WriteTreeRef,\n serverCache: Node | null, serverCacheComplete: boolean): Event[] {\n const queryId = query.queryIdentifier();\n let view = safeGet(this.views_, queryId);\n if (!view) {\n // TODO: make writesCache take flag for complete server node\n let eventCache = writesCache.calcCompleteEventCache(serverCacheComplete ? serverCache : null);\n let eventCacheComplete = false;\n if (eventCache) {\n eventCacheComplete = true;\n } else if (serverCache instanceof ChildrenNode) {\n eventCache = writesCache.calcCompleteEventChildren(serverCache);\n eventCacheComplete = false;\n } else {\n eventCache = ChildrenNode.EMPTY_NODE;\n eventCacheComplete = false;\n }\n const viewCache = new ViewCache(\n new CacheNode(/** @type {!Node} */ (eventCache), eventCacheComplete, false),\n new CacheNode(/** @type {!Node} */ (serverCache), serverCacheComplete, false)\n );\n view = new View(query, viewCache);\n this.views_[queryId] = view;\n }\n\n // This is guaranteed to exist now, we just created anything that was missing\n view.addEventRegistration(eventRegistration);\n return view.getInitialEvents(eventRegistration);\n }\n\n /**\n * Remove event callback(s). Return cancelEvents if a cancelError is specified.\n *\n * If query is the default query, we'll check all views for the specified eventRegistration.\n * If eventRegistration is null, we'll remove all callbacks for the specified view(s).\n *\n * @param {!Query} query\n * @param {?EventRegistration} eventRegistration If null, remove all callbacks.\n * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\n * @return {{removed:!Array., events:!Array.}} removed queries and any cancel events\n */\n removeEventRegistration(query: Query, eventRegistration: EventRegistration | null,\n cancelError?: Error): { removed: Query[], events: Event[] } {\n const queryId = query.queryIdentifier();\n const removed: Query[] = [];\n let cancelEvents: Event[] = [];\n const hadCompleteView = this.hasCompleteView();\n if (queryId === 'default') {\n // When you do ref.off(...), we search all views for the registration to remove.\n const self = this;\n forEach(this.views_, function (viewQueryId: string, view: View) {\n cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));\n if (view.isEmpty()) {\n delete self.views_[viewQueryId];\n\n // We'll deal with complete views later.\n if (!view.getQuery().getQueryParams().loadsAllData()) {\n removed.push(view.getQuery());\n }\n }\n });\n } else {\n // remove the callback from the specific view.\n const view = safeGet(this.views_, queryId);\n if (view) {\n cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));\n if (view.isEmpty()) {\n delete this.views_[queryId];\n\n // We'll deal with complete views later.\n if (!view.getQuery().getQueryParams().loadsAllData()) {\n removed.push(view.getQuery());\n }\n }\n }\n }\n\n if (hadCompleteView && !this.hasCompleteView()) {\n // We removed our last complete view.\n removed.push(new SyncPoint.__referenceConstructor(query.repo, query.path));\n }\n\n return {removed: removed, events: cancelEvents};\n }\n\n /**\n * @return {!Array.}\n */\n getQueryViews(): View[] {\n const values = Object.keys(this.views_)\n .map(key => this.views_[key]);\n return values.filter(function (view) {\n return !view.getQuery().getQueryParams().loadsAllData();\n });\n }\n\n /**\n *\n * @param {!Path} path The path to the desired complete snapshot\n * @return {?Node} A complete cache, if it exists\n */\n getCompleteServerCache(path: Path): Node | null {\n let serverCache: Node | null = null;\n forEach(this.views_, (key: string, view: View) => {\n serverCache = serverCache || view.getCompleteServerCache(path);\n });\n return serverCache;\n }\n\n /**\n * @param {!Query} query\n * @return {?View}\n */\n viewForQuery(query: Query): View | null {\n const params = query.getQueryParams();\n if (params.loadsAllData()) {\n return this.getCompleteView();\n } else {\n const queryId = query.queryIdentifier();\n return safeGet(this.views_, queryId);\n }\n }\n\n /**\n * @param {!Query} query\n * @return {boolean}\n */\n viewExistsForQuery(query: Query): boolean {\n return this.viewForQuery(query) != null;\n }\n\n /**\n * @return {boolean}\n */\n hasCompleteView(): boolean {\n return this.getCompleteView() != null;\n }\n\n /**\n * @return {?View}\n */\n getCompleteView(): View | null {\n const completeView = findValue(this.views_, (view: View) => view.getQuery().getQueryParams().loadsAllData());\n return completeView || null;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/SyncPoint.ts","/**\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\nimport { getValues, safeGet } from '../../../utils/obj';\nimport { Change } from './Change';\nimport { assert, assertionError } from '../../../utils/assert';\n\n/**\n * @constructor\n */\nexport class ChildChangeAccumulator {\n private changeMap_: { [k: string]: Change } = {};\n\n /**\n * @param {!Change} change\n */\n trackChildChange(change: Change) {\n const type = change.type;\n const childKey = /** @type {!string} */ (change.childName);\n assert(type == Change.CHILD_ADDED ||\n type == Change.CHILD_CHANGED ||\n type == Change.CHILD_REMOVED, 'Only child changes supported for tracking');\n assert(childKey !== '.priority', 'Only non-priority child changes can be tracked.');\n const oldChange = safeGet(this.changeMap_, childKey) as Change;\n if (oldChange) {\n const oldType = oldChange.type;\n if (type == Change.CHILD_ADDED && oldType == Change.CHILD_REMOVED) {\n this.changeMap_[childKey] = Change.childChangedChange(childKey, change.snapshotNode, oldChange.snapshotNode);\n } else if (type == Change.CHILD_REMOVED && oldType == Change.CHILD_ADDED) {\n delete this.changeMap_[childKey];\n } else if (type == Change.CHILD_REMOVED && oldType == Change.CHILD_CHANGED) {\n this.changeMap_[childKey] = Change.childRemovedChange(childKey, oldChange.oldSnap);\n } else if (type == Change.CHILD_CHANGED && oldType == Change.CHILD_ADDED) {\n this.changeMap_[childKey] = Change.childAddedChange(childKey, change.snapshotNode);\n } else if (type == Change.CHILD_CHANGED && oldType == Change.CHILD_CHANGED) {\n this.changeMap_[childKey] = Change.childChangedChange(childKey, change.snapshotNode, oldChange.oldSnap);\n } else {\n throw assertionError('Illegal combination of changes: ' + change + ' occurred after ' + oldChange);\n }\n } else {\n this.changeMap_[childKey] = change;\n }\n }\n\n\n /**\n * @return {!Array.}\n */\n getChanges(): Change[] {\n return getValues(this.changeMap_);\n }\n}\n\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/ChildChangeAccumulator.ts","/**\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\nimport { CacheNode } from './CacheNode';\nimport { NamedNode, Node } from '../snap/Node';\nimport { Index } from '../snap/indexes/Index';\nimport { WriteTreeRef } from '../WriteTree';\nimport { ViewCache } from './ViewCache';\n\n/**\n * Since updates to filtered nodes might require nodes to be pulled in from \"outside\" the node, this interface\n * can help to get complete children that can be pulled in.\n * A class implementing this interface takes potentially multiple sources (e.g. user writes, server data from\n * other views etc.) to try it's best to get a complete child that might be useful in pulling into the view.\n *\n * @interface\n */\nexport interface CompleteChildSource {\n /**\n * @param {!string} childKey\n * @return {?Node}\n */\n getCompleteChild(childKey: string): Node | null;\n\n /**\n * @param {!Index} index\n * @param {!NamedNode} child\n * @param {boolean} reverse\n * @return {?NamedNode}\n */\n getChildAfterChild(index: Index, child: NamedNode, reverse: boolean): NamedNode | null;\n}\n\n\n/**\n * An implementation of CompleteChildSource that never returns any additional children\n *\n * @private\n * @constructor\n * @implements CompleteChildSource\n */\nexport class NoCompleteChildSource_ implements CompleteChildSource {\n\n /**\n * @inheritDoc\n */\n getCompleteChild(childKey?: string): Node | null {\n return null;\n }\n\n /**\n * @inheritDoc\n */\n getChildAfterChild(index?: Index, child?: NamedNode, reverse?: boolean): NamedNode | null {\n return null;\n }\n}\n\n\n/**\n * Singleton instance.\n * @const\n * @type {!CompleteChildSource}\n */\nexport const NO_COMPLETE_CHILD_SOURCE = new NoCompleteChildSource_();\n\n\n/**\n * An implementation of CompleteChildSource that uses a WriteTree in addition to any other server data or\n * old event caches available to calculate complete children.\n *\n *\n * @implements CompleteChildSource\n */\nexport class WriteTreeCompleteChildSource implements CompleteChildSource {\n /**\n * @param {!WriteTreeRef} writes_\n * @param {!ViewCache} viewCache_\n * @param {?Node} optCompleteServerCache_\n */\n constructor(private writes_: WriteTreeRef,\n private viewCache_: ViewCache,\n private optCompleteServerCache_: Node | null = null) {\n }\n\n /**\n * @inheritDoc\n */\n getCompleteChild(childKey: string): Node | null {\n const node = this.viewCache_.getEventCache();\n if (node.isCompleteForChild(childKey)) {\n return node.getNode().getImmediateChild(childKey);\n } else {\n const serverNode = this.optCompleteServerCache_ != null ?\n new CacheNode(this.optCompleteServerCache_, true, false) : this.viewCache_.getServerCache();\n return this.writes_.calcCompleteChild(childKey, serverNode);\n }\n }\n\n /**\n * @inheritDoc\n */\n getChildAfterChild(index: Index, child: NamedNode, reverse: boolean): NamedNode | null {\n const completeServerData = this.optCompleteServerCache_ != null ? this.optCompleteServerCache_ :\n this.viewCache_.getCompleteServerSnap();\n const nodes = this.writes_.calcIndexedSlice(completeServerData, child, 1, reverse, index);\n if (nodes.length === 0) {\n return null;\n } else {\n return nodes[0];\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/CompleteChildSource.ts","/**\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\nimport { Operation, OperationType } from '../operation/Operation';\nimport { assert, assertionError } from '../../../utils/assert';\nimport { ChildChangeAccumulator } from './ChildChangeAccumulator';\nimport { Change } from './Change';\nimport { ChildrenNode } from '../snap/ChildrenNode';\nimport { KEY_INDEX } from '../snap/indexes/KeyIndex';\nimport { ImmutableTree } from '../util/ImmutableTree';\nimport { Path } from '../util/Path';\nimport { WriteTreeCompleteChildSource, NO_COMPLETE_CHILD_SOURCE, CompleteChildSource } from './CompleteChildSource';\nimport { ViewCache } from './ViewCache';\nimport { NodeFilter } from './filter/NodeFilter';\nimport { WriteTreeRef } from '../WriteTree';\nimport { Overwrite } from '../operation/Overwrite';\nimport { Merge } from '../operation/Merge';\nimport { AckUserWrite } from '../operation/AckUserWrite';\nimport { Node } from '../snap/Node';\n\n/**\n * @constructor\n * @struct\n */\nexport class ProcessorResult {\n /**\n * @param {!ViewCache} viewCache\n * @param {!Array.} changes\n */\n constructor(public readonly viewCache: ViewCache,\n public readonly changes: Change[]) {\n }\n}\n\n/**\n * @constructor\n */\nexport class ViewProcessor {\n /**\n * @param {!NodeFilter} filter_\n */\n constructor(private readonly filter_: NodeFilter) {\n }\n\n /**\n * @param {!ViewCache} viewCache\n */\n assertIndexed(viewCache: ViewCache) {\n assert(viewCache.getEventCache().getNode().isIndexed(this.filter_.getIndex()), 'Event snap not indexed');\n assert(viewCache.getServerCache().getNode().isIndexed(this.filter_.getIndex()),\n 'Server snap not indexed');\n }\n\n /**\n * @param {!ViewCache} oldViewCache\n * @param {!Operation} operation\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} completeCache\n * @return {!ProcessorResult}\n */\n applyOperation(oldViewCache: ViewCache, operation: Operation,\n writesCache: WriteTreeRef, completeCache: Node | null): ProcessorResult {\n const accumulator = new ChildChangeAccumulator();\n let newViewCache, filterServerNode;\n if (operation.type === OperationType.OVERWRITE) {\n const overwrite = operation as Overwrite;\n if (overwrite.source.fromUser) {\n newViewCache = this.applyUserOverwrite_(oldViewCache, overwrite.path, overwrite.snap,\n writesCache, completeCache, accumulator);\n } else {\n assert(overwrite.source.fromServer, 'Unknown source.');\n // We filter the node if it's a tagged update or the node has been previously filtered and the\n // update is not at the root in which case it is ok (and necessary) to mark the node unfiltered\n // again\n filterServerNode = overwrite.source.tagged ||\n (oldViewCache.getServerCache().isFiltered() && !overwrite.path.isEmpty());\n newViewCache = this.applyServerOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache,\n completeCache, filterServerNode, accumulator);\n }\n } else if (operation.type === OperationType.MERGE) {\n const merge = operation as Merge;\n if (merge.source.fromUser) {\n newViewCache = this.applyUserMerge_(oldViewCache, merge.path, merge.children, writesCache,\n completeCache, accumulator);\n } else {\n assert(merge.source.fromServer, 'Unknown source.');\n // We filter the node if it's a tagged update or the node has been previously filtered\n filterServerNode = merge.source.tagged || oldViewCache.getServerCache().isFiltered();\n newViewCache = this.applyServerMerge_(oldViewCache, merge.path, merge.children, writesCache, completeCache,\n filterServerNode, accumulator);\n }\n } else if (operation.type === OperationType.ACK_USER_WRITE) {\n const ackUserWrite = operation as AckUserWrite;\n if (!ackUserWrite.revert) {\n newViewCache = this.ackUserWrite_(oldViewCache, ackUserWrite.path, ackUserWrite.affectedTree, writesCache,\n completeCache, accumulator);\n } else {\n newViewCache = this.revertUserWrite_(oldViewCache, ackUserWrite.path, writesCache, completeCache, accumulator);\n }\n } else if (operation.type === OperationType.LISTEN_COMPLETE) {\n newViewCache = this.listenComplete_(oldViewCache, operation.path, writesCache, accumulator);\n } else {\n throw assertionError('Unknown operation type: ' + operation.type);\n }\n const changes = accumulator.getChanges();\n ViewProcessor.maybeAddValueEvent_(oldViewCache, newViewCache, changes);\n return new ProcessorResult(newViewCache, changes);\n }\n\n /**\n * @param {!ViewCache} oldViewCache\n * @param {!ViewCache} newViewCache\n * @param {!Array.} accumulator\n * @private\n */\n private static maybeAddValueEvent_(oldViewCache: ViewCache, newViewCache: ViewCache, accumulator: Change[]) {\n const eventSnap = newViewCache.getEventCache();\n if (eventSnap.isFullyInitialized()) {\n const isLeafOrEmpty = eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty();\n const oldCompleteSnap = oldViewCache.getCompleteEventSnap();\n if (accumulator.length > 0 ||\n !oldViewCache.getEventCache().isFullyInitialized() ||\n (isLeafOrEmpty && !eventSnap.getNode().equals(/** @type {!Node} */ (oldCompleteSnap))) ||\n !eventSnap.getNode().getPriority().equals(oldCompleteSnap.getPriority())) {\n accumulator.push(Change.valueChange(\n /** @type {!Node} */ (newViewCache.getCompleteEventSnap())));\n }\n }\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {!Path} changePath\n * @param {!WriteTreeRef} writesCache\n * @param {!CompleteChildSource} source\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n private generateEventCacheAfterServerEvent_(viewCache: ViewCache, changePath: Path,\n writesCache: WriteTreeRef, source: CompleteChildSource,\n accumulator: ChildChangeAccumulator): ViewCache {\n const oldEventSnap = viewCache.getEventCache();\n if (writesCache.shadowingWrite(changePath) != null) {\n // we have a shadowing write, ignore changes\n return viewCache;\n } else {\n let newEventCache, serverNode;\n if (changePath.isEmpty()) {\n // TODO: figure out how this plays with \"sliding ack windows\"\n assert(viewCache.getServerCache().isFullyInitialized(),\n 'If change path is empty, we must have complete server data');\n if (viewCache.getServerCache().isFiltered()) {\n // We need to special case this, because we need to only apply writes to complete children, or\n // we might end up raising events for incomplete children. If the server data is filtered deep\n // writes cannot be guaranteed to be complete\n const serverCache = viewCache.getCompleteServerSnap();\n const completeChildren = (serverCache instanceof ChildrenNode) ? serverCache :\n ChildrenNode.EMPTY_NODE;\n const completeEventChildren = writesCache.calcCompleteEventChildren(completeChildren);\n newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeEventChildren,\n accumulator);\n } else {\n const completeNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\n newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeNode, accumulator);\n }\n } else {\n const childKey = changePath.getFront();\n if (childKey == '.priority') {\n assert(changePath.getLength() == 1, 'Can\\'t have a priority with additional path components');\n const oldEventNode = oldEventSnap.getNode();\n serverNode = viewCache.getServerCache().getNode();\n // we might have overwrites for this priority\n const updatedPriority = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventNode, serverNode);\n if (updatedPriority != null) {\n newEventCache = this.filter_.updatePriority(oldEventNode, updatedPriority);\n } else {\n // priority didn't change, keep old node\n newEventCache = oldEventSnap.getNode();\n }\n } else {\n const childChangePath = changePath.popFront();\n // update child\n let newEventChild;\n if (oldEventSnap.isCompleteForChild(childKey)) {\n serverNode = viewCache.getServerCache().getNode();\n const eventChildUpdate = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventSnap.getNode(),\n serverNode);\n if (eventChildUpdate != null) {\n newEventChild = oldEventSnap.getNode().getImmediateChild(childKey).updateChild(childChangePath,\n eventChildUpdate);\n } else {\n // Nothing changed, just keep the old child\n newEventChild = oldEventSnap.getNode().getImmediateChild(childKey);\n }\n } else {\n newEventChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());\n }\n if (newEventChild != null) {\n newEventCache = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newEventChild, childChangePath,\n source, accumulator);\n } else {\n // no complete child available or no change\n newEventCache = oldEventSnap.getNode();\n }\n }\n }\n return viewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized() || changePath.isEmpty(),\n this.filter_.filtersNodes());\n }\n }\n\n /**\n * @param {!ViewCache} oldViewCache\n * @param {!Path} changePath\n * @param {!Node} changedSnap\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} completeCache\n * @param {boolean} filterServerNode\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n applyServerOverwrite_(oldViewCache: ViewCache, changePath: Path, changedSnap: Node,\n writesCache: WriteTreeRef, completeCache: Node | null, filterServerNode: boolean,\n accumulator: ChildChangeAccumulator): ViewCache {\n const oldServerSnap = oldViewCache.getServerCache();\n let newServerCache;\n const serverFilter = filterServerNode ? this.filter_ : this.filter_.getIndexedFilter();\n if (changePath.isEmpty()) {\n newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), changedSnap, null);\n } else if (serverFilter.filtersNodes() && !oldServerSnap.isFiltered()) {\n // we want to filter the server node, but we didn't filter the server node yet, so simulate a full update\n const newServerNode = oldServerSnap.getNode().updateChild(changePath, changedSnap);\n newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), newServerNode, null);\n } else {\n const childKey = changePath.getFront();\n if (!oldServerSnap.isCompleteForPath(changePath) && changePath.getLength() > 1) {\n // We don't update incomplete nodes with updates intended for other listeners\n return oldViewCache;\n }\n const childChangePath = changePath.popFront();\n const childNode = oldServerSnap.getNode().getImmediateChild(childKey);\n const newChildNode = childNode.updateChild(childChangePath, changedSnap);\n if (childKey == '.priority') {\n newServerCache = serverFilter.updatePriority(oldServerSnap.getNode(), newChildNode);\n } else {\n newServerCache = serverFilter.updateChild(oldServerSnap.getNode(), childKey, newChildNode, childChangePath,\n NO_COMPLETE_CHILD_SOURCE, null);\n }\n }\n const newViewCache = oldViewCache.updateServerSnap(newServerCache,\n oldServerSnap.isFullyInitialized() || changePath.isEmpty(), serverFilter.filtersNodes());\n const source = new WriteTreeCompleteChildSource(writesCache, newViewCache, completeCache);\n return this.generateEventCacheAfterServerEvent_(newViewCache, changePath, writesCache, source, accumulator);\n }\n\n /**\n * @param {!ViewCache} oldViewCache\n * @param {!Path} changePath\n * @param {!Node} changedSnap\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} completeCache\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n applyUserOverwrite_(oldViewCache: ViewCache, changePath: Path, changedSnap: Node, writesCache: WriteTreeRef,\n completeCache: Node | null, accumulator: ChildChangeAccumulator): ViewCache {\n const oldEventSnap = oldViewCache.getEventCache();\n let newViewCache, newEventCache;\n const source = new WriteTreeCompleteChildSource(writesCache, oldViewCache, completeCache);\n if (changePath.isEmpty()) {\n newEventCache = this.filter_.updateFullNode(oldViewCache.getEventCache().getNode(), changedSnap, accumulator);\n newViewCache = oldViewCache.updateEventSnap(newEventCache, true, this.filter_.filtersNodes());\n } else {\n const childKey = changePath.getFront();\n if (childKey === '.priority') {\n newEventCache = this.filter_.updatePriority(oldViewCache.getEventCache().getNode(), changedSnap);\n newViewCache = oldViewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized(),\n oldEventSnap.isFiltered());\n } else {\n const childChangePath = changePath.popFront();\n const oldChild = oldEventSnap.getNode().getImmediateChild(childKey);\n let newChild;\n if (childChangePath.isEmpty()) {\n // Child overwrite, we can replace the child\n newChild = changedSnap;\n } else {\n const childNode = source.getCompleteChild(childKey);\n if (childNode != null) {\n if (childChangePath.getBack() === '.priority' &&\n childNode.getChild(childChangePath.parent()).isEmpty()) {\n // This is a priority update on an empty node. If this node exists on the server, the\n // server will send down the priority in the update, so ignore for now\n newChild = childNode;\n } else {\n newChild = childNode.updateChild(childChangePath, changedSnap);\n }\n } else {\n // There is no complete child node available\n newChild = ChildrenNode.EMPTY_NODE;\n }\n }\n if (!oldChild.equals(newChild)) {\n const newEventSnap = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newChild, childChangePath,\n source, accumulator);\n newViewCache = oldViewCache.updateEventSnap(newEventSnap, oldEventSnap.isFullyInitialized(),\n this.filter_.filtersNodes());\n } else {\n newViewCache = oldViewCache;\n }\n }\n }\n return newViewCache;\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {string} childKey\n * @return {boolean}\n * @private\n */\n private static cacheHasChild_(viewCache: ViewCache, childKey: string): boolean {\n return viewCache.getEventCache().isCompleteForChild(childKey);\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {!Path} path\n * @param {ImmutableTree.} changedChildren\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} serverCache\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n private applyUserMerge_(viewCache: ViewCache, path: Path, changedChildren: ImmutableTree, writesCache: WriteTreeRef,\n serverCache: Node | null, accumulator: ChildChangeAccumulator): ViewCache {\n // HACK: In the case of a limit query, there may be some changes that bump things out of the\n // window leaving room for new items. It's important we process these changes first, so we\n // iterate the changes twice, first processing any that affect items currently in view.\n // TODO: I consider an item \"in view\" if cacheHasChild is true, which checks both the server\n // and event snap. I'm not sure if this will result in edge cases when a child is in one but\n // not the other.\n let curViewCache = viewCache;\n changedChildren.foreach((relativePath, childNode) => {\n const writePath = path.child(relativePath);\n if (ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\n curViewCache = this.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache,\n serverCache, accumulator);\n }\n });\n\n changedChildren.foreach((relativePath, childNode) => {\n const writePath = path.child(relativePath);\n if (!ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\n curViewCache = this.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache,\n serverCache, accumulator);\n }\n });\n\n return curViewCache;\n }\n\n /**\n * @param {!Node} node\n * @param {ImmutableTree.} merge\n * @return {!Node}\n * @private\n */\n private applyMerge_(node: Node, merge: ImmutableTree): Node {\n merge.foreach(function (relativePath, childNode) {\n node = node.updateChild(relativePath, childNode);\n });\n return node;\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {!Path} path\n * @param {!ImmutableTree.} changedChildren\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} serverCache\n * @param {boolean} filterServerNode\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n private applyServerMerge_(viewCache: ViewCache, path: Path, changedChildren: ImmutableTree,\n writesCache: WriteTreeRef, serverCache: Node | null, filterServerNode: boolean,\n accumulator: ChildChangeAccumulator): ViewCache {\n // If we don't have a cache yet, this merge was intended for a previously listen in the same location. Ignore it and\n // wait for the complete data update coming soon.\n if (viewCache.getServerCache().getNode().isEmpty() && !viewCache.getServerCache().isFullyInitialized()) {\n return viewCache;\n }\n\n // HACK: In the case of a limit query, there may be some changes that bump things out of the\n // window leaving room for new items. It's important we process these changes first, so we\n // iterate the changes twice, first processing any that affect items currently in view.\n // TODO: I consider an item \"in view\" if cacheHasChild is true, which checks both the server\n // and event snap. I'm not sure if this will result in edge cases when a child is in one but\n // not the other.\n let curViewCache = viewCache;\n let viewMergeTree;\n if (path.isEmpty()) {\n viewMergeTree = changedChildren;\n } else {\n viewMergeTree = ImmutableTree.Empty.setTree(path, changedChildren);\n }\n const serverNode = viewCache.getServerCache().getNode();\n viewMergeTree.children.inorderTraversal((childKey, childTree) => {\n if (serverNode.hasChild(childKey)) {\n const serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);\n const newChild = this.applyMerge_(serverChild, childTree);\n curViewCache = this.applyServerOverwrite_(curViewCache, new Path(childKey), newChild,\n writesCache, serverCache, filterServerNode, accumulator);\n }\n });\n viewMergeTree.children.inorderTraversal((childKey, childMergeTree) => {\n const isUnknownDeepMerge = !viewCache.getServerCache().isCompleteForChild(childKey)\n && (childMergeTree.value == null);\n if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {\n const serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);\n const newChild = this.applyMerge_(serverChild, childMergeTree);\n curViewCache = this.applyServerOverwrite_(curViewCache, new Path(childKey), newChild, writesCache,\n serverCache, filterServerNode, accumulator);\n }\n });\n\n return curViewCache;\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {!Path} ackPath\n * @param {!ImmutableTree} affectedTree\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} completeCache\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n private ackUserWrite_(viewCache: ViewCache, ackPath: Path, affectedTree: ImmutableTree, writesCache: WriteTreeRef,\n completeCache: Node | null, accumulator: ChildChangeAccumulator): ViewCache {\n if (writesCache.shadowingWrite(ackPath) != null) {\n return viewCache;\n }\n\n // Only filter server node if it is currently filtered\n const filterServerNode = viewCache.getServerCache().isFiltered();\n\n // Essentially we'll just get our existing server cache for the affected paths and re-apply it as a server update\n // now that it won't be shadowed.\n const serverCache = viewCache.getServerCache();\n if (affectedTree.value != null) {\n // This is an overwrite.\n if ((ackPath.isEmpty() && serverCache.isFullyInitialized()) || serverCache.isCompleteForPath(ackPath)) {\n return this.applyServerOverwrite_(viewCache, ackPath, serverCache.getNode().getChild(ackPath),\n writesCache, completeCache, filterServerNode, accumulator);\n } else if (ackPath.isEmpty()) {\n // This is a goofy edge case where we are acking data at this location but don't have full data. We\n // should just re-apply whatever we have in our cache as a merge.\n let changedChildren = ImmutableTree.Empty;\n serverCache.getNode().forEachChild(KEY_INDEX, function (name, node) {\n changedChildren = changedChildren.set(new Path(name), node);\n });\n return this.applyServerMerge_(viewCache, ackPath, changedChildren, writesCache, completeCache,\n filterServerNode, accumulator);\n } else {\n return viewCache;\n }\n } else {\n // This is a merge.\n let changedChildren = ImmutableTree.Empty;\n affectedTree.foreach(function (mergePath, value) {\n const serverCachePath = ackPath.child(mergePath);\n if (serverCache.isCompleteForPath(serverCachePath)) {\n changedChildren = changedChildren.set(mergePath, serverCache.getNode().getChild(serverCachePath));\n }\n });\n return this.applyServerMerge_(viewCache, ackPath, changedChildren, writesCache, completeCache,\n filterServerNode, accumulator);\n }\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {!Path} path\n * @param {!WriteTreeRef} writesCache\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n private listenComplete_(viewCache: ViewCache, path: Path, writesCache: WriteTreeRef,\n accumulator: ChildChangeAccumulator): ViewCache {\n const oldServerNode = viewCache.getServerCache();\n const newViewCache = viewCache.updateServerSnap(oldServerNode.getNode(),\n oldServerNode.isFullyInitialized() || path.isEmpty(), oldServerNode.isFiltered());\n return this.generateEventCacheAfterServerEvent_(newViewCache, path, writesCache,\n NO_COMPLETE_CHILD_SOURCE, accumulator);\n }\n\n /**\n * @param {!ViewCache} viewCache\n * @param {!Path} path\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} completeServerCache\n * @param {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n private revertUserWrite_(viewCache: ViewCache, path: Path, writesCache: WriteTreeRef, completeServerCache: Node | null,\n accumulator: ChildChangeAccumulator): ViewCache {\n let complete;\n if (writesCache.shadowingWrite(path) != null) {\n return viewCache;\n } else {\n const source = new WriteTreeCompleteChildSource(writesCache, viewCache, completeServerCache);\n const oldEventCache = viewCache.getEventCache().getNode();\n let newEventCache;\n if (path.isEmpty() || path.getFront() === '.priority') {\n let newNode;\n if (viewCache.getServerCache().isFullyInitialized()) {\n newNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\n } else {\n const serverChildren = viewCache.getServerCache().getNode();\n assert(serverChildren instanceof ChildrenNode,\n 'serverChildren would be complete if leaf node');\n newNode = writesCache.calcCompleteEventChildren(serverChildren as ChildrenNode);\n }\n newNode = newNode as Node;\n newEventCache = this.filter_.updateFullNode(oldEventCache, newNode, accumulator);\n } else {\n const childKey = path.getFront();\n let newChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());\n if (newChild == null && viewCache.getServerCache().isCompleteForChild(childKey)) {\n newChild = oldEventCache.getImmediateChild(childKey);\n }\n if (newChild != null) {\n newEventCache = this.filter_.updateChild(oldEventCache, childKey, newChild, path.popFront(), source,\n accumulator);\n } else if (viewCache.getEventCache().getNode().hasChild(childKey)) {\n // No complete child available, delete the existing one, if any\n newEventCache = this.filter_.updateChild(oldEventCache, childKey, ChildrenNode.EMPTY_NODE, path.popFront(),\n source, accumulator);\n } else {\n newEventCache = oldEventCache;\n }\n if (newEventCache.isEmpty() && viewCache.getServerCache().isFullyInitialized()) {\n // We might have reverted all child writes. Maybe the old event was a leaf node\n complete = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\n if (complete.isLeafNode()) {\n newEventCache = this.filter_.updateFullNode(newEventCache, complete, accumulator);\n }\n }\n }\n complete = viewCache.getServerCache().isFullyInitialized() ||\n writesCache.shadowingWrite(Path.Empty) != null;\n return viewCache.updateEventSnap(newEventCache, complete, this.filter_.filtersNodes());\n }\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/ViewProcessor.ts","/**\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\nimport { NamedNode, Node } from '../snap/Node';\nimport { Change } from './Change';\nimport { assertionError } from '../../../utils/assert';\nimport { Query } from '../../api/Query';\nimport { Index } from '../snap/indexes/Index';\nimport { EventRegistration } from './EventRegistration';\nimport { Event } from './Event';\n\n/**\n * An EventGenerator is used to convert \"raw\" changes (Change) as computed by the\n * CacheDiffer into actual events (Event) that can be raised. See generateEventsForChanges()\n * for details.\n *\n * @constructor\n */\nexport class EventGenerator {\n private index_: Index;\n\n /**\n *\n * @param {!Query} query_\n */\n constructor(private query_: Query) {\n /**\n * @private\n * @type {!Index}\n */\n this.index_ = this.query_.getQueryParams().getIndex();\n }\n\n /**\n * Given a set of raw changes (no moved events and prevName not specified yet), and a set of\n * EventRegistrations that should be notified of these changes, generate the actual events to be raised.\n *\n * Notes:\n * - child_moved events will be synthesized at this time for any child_changed events that affect\n * our index.\n * - prevName will be calculated based on the index ordering.\n *\n * @param {!Array.} changes\n * @param {!Node} eventCache\n * @param {!Array.} eventRegistrations\n * @return {!Array.}\n */\n generateEventsForChanges(changes: Change[], eventCache: Node, eventRegistrations: EventRegistration[]): Event[] {\n const events: Event[] = [];\n const moves: Change[] = [];\n\n changes.forEach((change) => {\n if (change.type === Change.CHILD_CHANGED &&\n this.index_.indexedValueChanged(change.oldSnap as Node, change.snapshotNode)) {\n moves.push(Change.childMovedChange(change.childName as string, change.snapshotNode));\n }\n });\n\n this.generateEventsForType_(events, Change.CHILD_REMOVED, changes, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change.CHILD_ADDED, changes, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change.CHILD_MOVED, moves, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change.CHILD_CHANGED, changes, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change.VALUE, changes, eventRegistrations, eventCache);\n\n return events;\n }\n\n /**\n * Given changes of a single change type, generate the corresponding events.\n *\n * @param {!Array.} events\n * @param {!string} eventType\n * @param {!Array.} changes\n * @param {!Array.} registrations\n * @param {!Node} eventCache\n * @private\n */\n private generateEventsForType_(events: Event[], eventType: string, changes: Change[],\n registrations: EventRegistration[], eventCache: Node) {\n const filteredChanges = changes.filter((change) => change.type === eventType);\n\n filteredChanges.sort(this.compareChanges_.bind(this));\n filteredChanges.forEach((change) => {\n const materializedChange = this.materializeSingleChange_(change, eventCache);\n registrations.forEach((registration) => {\n if (registration.respondsTo(change.type)) {\n events.push(registration.createEvent(materializedChange, this.query_));\n }\n });\n });\n }\n\n /**\n * @param {!Change} change\n * @param {!Node} eventCache\n * @return {!Change}\n * @private\n */\n private materializeSingleChange_(change: Change, eventCache: Node): Change {\n if (change.type === 'value' || change.type === 'child_removed') {\n return change;\n } else {\n change.prevName = eventCache.getPredecessorChildName(/** @type {!string} */ (change.childName), change.snapshotNode,\n this.index_);\n return change;\n }\n }\n\n /**\n * @param {!Change} a\n * @param {!Change} b\n * @return {number}\n * @private\n */\n private compareChanges_(a: Change, b: Change) {\n if (a.childName == null || b.childName == null) {\n throw assertionError('Should only compare child_ events.');\n }\n const aWrapped = new NamedNode(a.childName, a.snapshotNode);\n const bWrapped = new NamedNode(b.childName, b.snapshotNode);\n return this.index_.compare(aWrapped, bWrapped);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/EventGenerator.ts","/**\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\nimport { IndexedFilter } from './filter/IndexedFilter';\nimport { ViewProcessor } from './ViewProcessor';\nimport { ChildrenNode } from '../snap/ChildrenNode';\nimport { CacheNode } from './CacheNode';\nimport { ViewCache } from './ViewCache';\nimport { EventGenerator } from './EventGenerator';\nimport { assert } from '../../../utils/assert';\nimport { Operation, OperationType } from '../operation/Operation';\nimport { Change } from './Change';\nimport { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';\nimport { Query } from '../../api/Query';\nimport { EventRegistration } from './EventRegistration';\nimport { Node } from '../snap/Node';\nimport { Path } from '../util/Path';\nimport { WriteTreeRef } from '../WriteTree';\nimport { CancelEvent, Event } from './Event';\n\n/**\n * A view represents a specific location and query that has 1 or more event registrations.\n *\n * It does several things:\n * - Maintains the list of event registrations for this location/query.\n * - Maintains a cache of the data visible for this location/query.\n * - Applies new operations (via applyOperation), updates the cache, and based on the event\n * registrations returns the set of events to be raised.\n * @constructor\n */\nexport class View {\n private processor_: ViewProcessor;\n private viewCache_: ViewCache;\n private eventRegistrations_: EventRegistration[] = [];\n private eventGenerator_: EventGenerator;\n\n /**\n *\n * @param {!Query} query_\n * @param {!ViewCache} initialViewCache\n */\n constructor(private query_: Query, initialViewCache: ViewCache) {\n const params = this.query_.getQueryParams();\n\n const indexFilter = new IndexedFilter(params.getIndex());\n const filter = params.getNodeFilter();\n\n /**\n * @type {ViewProcessor}\n * @private\n */\n this.processor_ = new ViewProcessor(filter);\n\n const initialServerCache = initialViewCache.getServerCache();\n const initialEventCache = initialViewCache.getEventCache();\n\n // Don't filter server node with other filter than index, wait for tagged listen\n const serverSnap = indexFilter.updateFullNode(ChildrenNode.EMPTY_NODE, initialServerCache.getNode(), null);\n const eventSnap = filter.updateFullNode(ChildrenNode.EMPTY_NODE, initialEventCache.getNode(), null);\n const newServerCache = new CacheNode(serverSnap, initialServerCache.isFullyInitialized(),\n indexFilter.filtersNodes());\n const newEventCache = new CacheNode(eventSnap, initialEventCache.isFullyInitialized(),\n filter.filtersNodes());\n\n /**\n * @type {!ViewCache}\n * @private\n */\n this.viewCache_ = new ViewCache(newEventCache, newServerCache);\n\n /**\n * @type {!EventGenerator}\n * @private\n */\n this.eventGenerator_ = new EventGenerator(this.query_);\n };\n\n /**\n * @return {!Query}\n */\n getQuery(): Query {\n return this.query_;\n };\n\n /**\n * @return {?Node}\n */\n getServerCache(): Node | null {\n return this.viewCache_.getServerCache().getNode();\n };\n\n /**\n * @param {!Path} path\n * @return {?Node}\n */\n getCompleteServerCache(path: Path): Node | null {\n const cache = this.viewCache_.getCompleteServerSnap();\n if (cache) {\n // If this isn't a \"loadsAllData\" view, then cache isn't actually a complete cache and\n // we need to see if it contains the child we're interested in.\n if (this.query_.getQueryParams().loadsAllData() ||\n (!path.isEmpty() && !cache.getImmediateChild(path.getFront()).isEmpty())) {\n return cache.getChild(path);\n }\n }\n return null;\n };\n\n /**\n * @return {boolean}\n */\n isEmpty(): boolean {\n return this.eventRegistrations_.length === 0;\n };\n\n /**\n * @param {!EventRegistration} eventRegistration\n */\n addEventRegistration(eventRegistration: EventRegistration) {\n this.eventRegistrations_.push(eventRegistration);\n };\n\n /**\n * @param {?EventRegistration} eventRegistration If null, remove all callbacks.\n * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\n * @return {!Array.} Cancel events, if cancelError was provided.\n */\n removeEventRegistration(eventRegistration: EventRegistration | null, cancelError?: Error): Event[] {\n const cancelEvents: CancelEvent[] = [];\n if (cancelError) {\n assert(eventRegistration == null, 'A cancel should cancel all event registrations.');\n const path = this.query_.path;\n this.eventRegistrations_.forEach(function (registration) {\n cancelError = /** @type {!Error} */ (cancelError);\n const maybeEvent = registration.createCancelEvent(cancelError, path);\n if (maybeEvent) {\n cancelEvents.push(maybeEvent);\n }\n });\n }\n\n if (eventRegistration) {\n let remaining = [];\n for (let i = 0; i < this.eventRegistrations_.length; ++i) {\n const existing = this.eventRegistrations_[i];\n if (!existing.matches(eventRegistration)) {\n remaining.push(existing);\n } else if (eventRegistration.hasAnyCallback()) {\n // We're removing just this one\n remaining = remaining.concat(this.eventRegistrations_.slice(i + 1));\n break;\n }\n }\n this.eventRegistrations_ = remaining;\n } else {\n this.eventRegistrations_ = [];\n }\n return cancelEvents;\n };\n\n /**\n * Applies the given Operation, updates our cache, and returns the appropriate events.\n *\n * @param {!Operation} operation\n * @param {!WriteTreeRef} writesCache\n * @param {?Node} completeServerCache\n * @return {!Array.}\n */\n applyOperation(operation: Operation, writesCache: WriteTreeRef, completeServerCache: Node | null): Event[] {\n if (operation.type === OperationType.MERGE &&\n operation.source.queryId !== null) {\n\n assert(this.viewCache_.getCompleteServerSnap(),\n 'We should always have a full cache before handling merges');\n assert(this.viewCache_.getCompleteEventSnap(),\n 'Missing event cache, even though we have a server cache');\n }\n\n const oldViewCache = this.viewCache_;\n const result = this.processor_.applyOperation(oldViewCache, operation, writesCache, completeServerCache);\n this.processor_.assertIndexed(result.viewCache);\n\n assert(result.viewCache.getServerCache().isFullyInitialized() ||\n !oldViewCache.getServerCache().isFullyInitialized(),\n 'Once a server snap is complete, it should never go back');\n\n this.viewCache_ = result.viewCache;\n\n return this.generateEventsForChanges_(result.changes, result.viewCache.getEventCache().getNode(), null);\n };\n\n /**\n * @param {!EventRegistration} registration\n * @return {!Array.}\n */\n getInitialEvents(registration: EventRegistration): Event[] {\n const eventSnap = this.viewCache_.getEventCache();\n const initialChanges: Change[] = [];\n if (!eventSnap.getNode().isLeafNode()) {\n const eventNode = eventSnap.getNode() as ChildrenNode;\n eventNode.forEachChild(PRIORITY_INDEX, function (key, childNode) {\n initialChanges.push(Change.childAddedChange(key, childNode));\n });\n }\n if (eventSnap.isFullyInitialized()) {\n initialChanges.push(Change.valueChange(eventSnap.getNode()));\n }\n return this.generateEventsForChanges_(initialChanges, eventSnap.getNode(), registration);\n };\n\n /**\n * @private\n * @param {!Array.} changes\n * @param {!Node} eventCache\n * @param {EventRegistration=} eventRegistration\n * @return {!Array.}\n */\n generateEventsForChanges_(changes: Change[], eventCache: Node, eventRegistration?: EventRegistration): Event[] {\n const registrations = eventRegistration ? [eventRegistration] : this.eventRegistrations_;\n return this.eventGenerator_.generateEventsForChanges(changes, eventCache, registrations);\n };\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/View.ts","/**\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\nimport { ImmutableTree } from \"./util/ImmutableTree\";\nimport { Path } from \"./util/Path\";\nimport { forEach } from \"../../utils/obj\";\nimport { Node, NamedNode } from \"./snap/Node\";\nimport { PRIORITY_INDEX } from \"./snap/indexes/PriorityIndex\";\nimport { assert } from \"../../utils/assert\";\nimport { ChildrenNode } from './snap/ChildrenNode';\n\n/**\n * This class holds a collection of writes that can be applied to nodes in unison. It abstracts away the logic with\n * dealing with priority writes and multiple nested writes. At any given path there is only allowed to be one write\n * modifying that path. Any write to an existing path or shadowing an existing path will modify that existing write\n * to reflect the write added.\n *\n * @constructor\n * @param {!ImmutableTree.} writeTree\n */\nexport class CompoundWrite {\n constructor(private writeTree_: ImmutableTree) {};\n /**\n * @type {!CompoundWrite}\n */\n static Empty = new CompoundWrite(new ImmutableTree(null));\n\n /**\n * @param {!Path} path\n * @param {!Node} node\n * @return {!CompoundWrite}\n */\n addWrite(path: Path, node: Node): CompoundWrite {\n if (path.isEmpty()) {\n return new CompoundWrite(new ImmutableTree(node));\n } else {\n const rootmost = this.writeTree_.findRootMostValueAndPath(path);\n if (rootmost != null) {\n const rootMostPath = rootmost.path;\n let value = rootmost.value;\n const relativePath = Path.relativePath(rootMostPath, path);\n value = value.updateChild(relativePath, node);\n return new CompoundWrite(this.writeTree_.set(rootMostPath, value));\n } else {\n const subtree = new ImmutableTree(node);\n const newWriteTree = this.writeTree_.setTree(path, subtree);\n return new CompoundWrite(newWriteTree);\n }\n }\n }\n\n /**\n * @param {!Path} path\n * @param {!Object.} updates\n * @return {!CompoundWrite}\n */\n addWrites(path: Path, updates: { [name: string]: Node }): CompoundWrite {\n let newWrite = this as CompoundWrite;\n forEach(updates, function(childKey: string, node: Node) {\n newWrite = newWrite.addWrite(path.child(childKey), node);\n });\n return newWrite;\n }\n\n /**\n * Will remove a write at the given path and deeper paths. This will not modify a write at a higher\n * location, which must be removed by calling this method with that path.\n *\n * @param {!Path} path The path at which a write and all deeper writes should be removed\n * @return {!CompoundWrite} The new CompoundWrite with the removed path\n */\n removeWrite(path: Path): CompoundWrite {\n if (path.isEmpty()) {\n return CompoundWrite.Empty;\n } else {\n const newWriteTree = this.writeTree_.setTree(path, ImmutableTree.Empty);\n return new CompoundWrite(newWriteTree);\n }\n }\n\n /**\n * Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be\n * considered \"complete\".\n *\n * @param {!Path} path The path to check for\n * @return {boolean} Whether there is a complete write at that path\n */\n hasCompleteWrite(path: Path): boolean {\n return this.getCompleteNode(path) != null;\n }\n\n /**\n * Returns a node for a path if and only if the node is a \"complete\" overwrite at that path. This will not aggregate\n * writes from deeper paths, but will return child nodes from a more shallow path.\n *\n * @param {!Path} path The path to get a complete write\n * @return {?Node} The node if complete at that path, or null otherwise.\n */\n getCompleteNode(path: Path): Node | null {\n const rootmost = this.writeTree_.findRootMostValueAndPath(path);\n if (rootmost != null) {\n return this.writeTree_.get(rootmost.path).getChild(Path.relativePath(rootmost.path, path));\n } else {\n return null;\n }\n }\n\n /**\n * Returns all children that are guaranteed to be a complete overwrite.\n *\n * @return {!Array.} A list of all complete children.\n */\n getCompleteChildren(): Array {\n const children: NamedNode[] = [];\n let node = this.writeTree_.value;\n if (node != null) {\n // If it's a leaf node, it has no children; so nothing to do.\n if (!node.isLeafNode()) {\n (node as ChildrenNode).forEachChild(PRIORITY_INDEX, function(childName, childNode) {\n children.push(new NamedNode(childName, childNode));\n });\n }\n } else {\n this.writeTree_.children.inorderTraversal(function(childName, childTree) {\n if (childTree.value != null) {\n children.push(new NamedNode(childName, childTree.value));\n }\n });\n }\n return children;\n }\n\n /**\n * @param {!Path} path\n * @return {!CompoundWrite}\n */\n childCompoundWrite(path: Path): CompoundWrite {\n if (path.isEmpty()) {\n return this;\n } else {\n const shadowingNode = this.getCompleteNode(path);\n if (shadowingNode != null) {\n return new CompoundWrite(new ImmutableTree(shadowingNode));\n } else {\n return new CompoundWrite(this.writeTree_.subtree(path));\n }\n }\n }\n\n /**\n * Returns true if this CompoundWrite is empty and therefore does not modify any nodes.\n * @return {boolean} Whether this CompoundWrite is empty\n */\n isEmpty(): boolean {\n return this.writeTree_.isEmpty();\n }\n\n /**\n * Applies this CompoundWrite to a node. The node is returned with all writes from this CompoundWrite applied to the\n * node\n * @param {!Node} node The node to apply this CompoundWrite to\n * @return {!Node} The node with all writes applied\n */\n apply(node: Node): Node {\n return CompoundWrite.applySubtreeWrite_(Path.Empty, this.writeTree_, node);\n }\n\n /**\n * @param {!Path} relativePath\n * @param {!ImmutableTree.} writeTree\n * @param {!Node} node\n * @return {!Node}\n * @private\n */\n private static applySubtreeWrite_ = function(relativePath: Path, writeTree: ImmutableTree, node: Node): Node {\n if (writeTree.value != null) {\n // Since there a write is always a leaf, we're done here\n return node.updateChild(relativePath, writeTree.value);\n } else {\n let priorityWrite = null;\n writeTree.children.inorderTraversal(function(childKey, childTree) {\n if (childKey === '.priority') {\n // Apply priorities at the end so we don't update priorities for either empty nodes or forget\n // to apply priorities to empty nodes that are later filled\n assert(childTree.value !== null, 'Priority writes must always be leaf nodes');\n priorityWrite = childTree.value;\n } else {\n node = CompoundWrite.applySubtreeWrite_(relativePath.child(childKey), childTree, node);\n }\n });\n // If there was a priority write, we only apply it if the node is not empty\n if (!node.getChild(relativePath).isEmpty() && priorityWrite !== null) {\n node = node.updateChild(relativePath.child('.priority'), priorityWrite);\n }\n return node;\n }\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/CompoundWrite.ts","/**\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\nimport { findKey, forEach, safeGet } from '../../utils/obj';\nimport { assert, assertionError } from '../../utils/assert';\nimport { Path } from './util/Path';\nimport { CompoundWrite } from './CompoundWrite';\nimport { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { NamedNode, Node } from './snap/Node';\nimport { CacheNode } from './view/CacheNode';\nimport { Index } from './snap/indexes/Index';\n\n/**\n * Defines a single user-initiated write operation. May be the result of a set(), transaction(), or update() call. In\n * the case of a set() or transaction, snap wil be non-null. In the case of an update(), children will be non-null.\n */\nexport interface WriteRecord {\n writeId: number;\n path: Path;\n snap?: Node | null;\n children?: { [k: string]: Node } | null;\n visible: boolean\n}\n\n/**\n * WriteTree tracks all pending user-initiated writes and has methods to calculate the result of merging them\n * with underlying server data (to create \"event cache\" data). Pending writes are added with addOverwrite()\n * and addMerge(), and removed with removeWrite().\n *\n * @constructor\n */\nexport class WriteTree {\n /**\n * A tree tracking the result of applying all visible writes. This does not include transactions with\n * applyLocally=false or writes that are completely shadowed by other writes.\n *\n * @type {!CompoundWrite}\n * @private\n */\n private visibleWrites_: CompoundWrite = CompoundWrite.Empty;\n\n /**\n * A list of all pending writes, regardless of visibility and shadowed-ness. Used to calculate arbitrary\n * sets of the changed data, such as hidden writes (from transactions) or changes with certain writes excluded (also\n * used by transactions).\n *\n * @type {!Array.}\n * @private\n */\n private allWrites_: WriteRecord[] = [];\n\n private lastWriteId_ = -1;\n\n /**\n * Create a new WriteTreeRef for the given path. For use with a new sync point at the given path.\n *\n * @param {!Path} path\n * @return {!WriteTreeRef}\n */\n childWrites(path: Path): WriteTreeRef {\n return new WriteTreeRef(path, this);\n }\n\n /**\n * Record a new overwrite from user code.\n *\n * @param {!Path} path\n * @param {!Node} snap\n * @param {!number} writeId\n * @param {boolean=} visible This is set to false by some transactions. It should be excluded from event caches\n */\n addOverwrite(path: Path, snap: Node, writeId: number, visible?: boolean) {\n assert(writeId > this.lastWriteId_, 'Stacking an older write on top of newer ones');\n if (visible === undefined) {\n visible = true;\n }\n this.allWrites_.push({path: path, snap: snap, writeId: writeId, visible: visible});\n\n if (visible) {\n this.visibleWrites_ = this.visibleWrites_.addWrite(path, snap);\n }\n this.lastWriteId_ = writeId;\n }\n\n /**\n * Record a new merge from user code.\n *\n * @param {!Path} path\n * @param {!Object.} changedChildren\n * @param {!number} writeId\n */\n addMerge(path: Path, changedChildren: { [k: string]: Node }, writeId: number) {\n assert(writeId > this.lastWriteId_, 'Stacking an older merge on top of newer ones');\n this.allWrites_.push({path: path, children: changedChildren, writeId: writeId, visible: true});\n\n this.visibleWrites_ = this.visibleWrites_.addWrites(path, changedChildren);\n this.lastWriteId_ = writeId;\n }\n\n\n /**\n * @param {!number} writeId\n * @return {?WriteRecord}\n */\n getWrite(writeId: number): WriteRecord | null {\n for (let i = 0; i < this.allWrites_.length; i++) {\n const record = this.allWrites_[i];\n if (record.writeId === writeId) {\n return record;\n }\n }\n return null;\n }\n\n\n /**\n * Remove a write (either an overwrite or merge) that has been successfully acknowledge by the server. Recalculates\n * the tree if necessary. We return true if it may have been visible, meaning views need to reevaluate.\n *\n * @param {!number} writeId\n * @return {boolean} true if the write may have been visible (meaning we'll need to reevaluate / raise\n * events as a result).\n */\n removeWrite(writeId: number): boolean {\n // Note: disabling this check. It could be a transaction that preempted another transaction, and thus was applied\n // out of order.\n //const validClear = revert || this.allWrites_.length === 0 || writeId <= this.allWrites_[0].writeId;\n //assert(validClear, \"Either we don't have this write, or it's the first one in the queue\");\n\n const idx = this.allWrites_.findIndex(function (s) { return s.writeId === writeId; });\n assert(idx >= 0, 'removeWrite called with nonexistent writeId.');\n const writeToRemove = this.allWrites_[idx];\n this.allWrites_.splice(idx, 1);\n\n let removedWriteWasVisible = writeToRemove.visible;\n let removedWriteOverlapsWithOtherWrites = false;\n\n let i = this.allWrites_.length - 1;\n\n while (removedWriteWasVisible && i >= 0) {\n const currentWrite = this.allWrites_[i];\n if (currentWrite.visible) {\n if (i >= idx && this.recordContainsPath_(currentWrite, writeToRemove.path)) {\n // The removed write was completely shadowed by a subsequent write.\n removedWriteWasVisible = false;\n } else if (writeToRemove.path.contains(currentWrite.path)) {\n // Either we're covering some writes or they're covering part of us (depending on which came first).\n removedWriteOverlapsWithOtherWrites = true;\n }\n }\n i--;\n }\n\n if (!removedWriteWasVisible) {\n return false;\n } else if (removedWriteOverlapsWithOtherWrites) {\n // There's some shadowing going on. Just rebuild the visible writes from scratch.\n this.resetTree_();\n return true;\n } else {\n // There's no shadowing. We can safely just remove the write(s) from visibleWrites.\n if (writeToRemove.snap) {\n this.visibleWrites_ = this.visibleWrites_.removeWrite(writeToRemove.path);\n } else {\n const children = writeToRemove.children;\n forEach(children, (childName: string) => {\n this.visibleWrites_ = this.visibleWrites_.removeWrite(writeToRemove.path.child(childName));\n });\n }\n return true;\n }\n }\n\n /**\n * Return a complete snapshot for the given path if there's visible write data at that path, else null.\n * No server data is considered.\n *\n * @param {!Path} path\n * @return {?Node}\n */\n getCompleteWriteData(path: Path): Node | null {\n return this.visibleWrites_.getCompleteNode(path);\n }\n\n /**\n * Given optional, underlying server data, and an optional set of constraints (exclude some sets, include hidden\n * writes), attempt to calculate a complete snapshot for the given path\n *\n * @param {!Path} treePath\n * @param {?Node} completeServerCache\n * @param {Array.=} writeIdsToExclude An optional set to be excluded\n * @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false\n * @return {?Node}\n */\n calcCompleteEventCache(treePath: Path, completeServerCache: Node | null, writeIdsToExclude?: number[],\n includeHiddenWrites?: boolean): Node | null {\n if (!writeIdsToExclude && !includeHiddenWrites) {\n const shadowingNode = this.visibleWrites_.getCompleteNode(treePath);\n if (shadowingNode != null) {\n return shadowingNode;\n } else {\n const subMerge = this.visibleWrites_.childCompoundWrite(treePath);\n if (subMerge.isEmpty()) {\n return completeServerCache;\n } else if (completeServerCache == null && !subMerge.hasCompleteWrite(Path.Empty)) {\n // We wouldn't have a complete snapshot, since there's no underlying data and no complete shadow\n return null;\n } else {\n const layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE;\n return subMerge.apply(layeredCache);\n }\n }\n } else {\n const merge = this.visibleWrites_.childCompoundWrite(treePath);\n if (!includeHiddenWrites && merge.isEmpty()) {\n return completeServerCache;\n } else {\n // If the server cache is null, and we don't have a complete cache, we need to return null\n if (!includeHiddenWrites && completeServerCache == null && !merge.hasCompleteWrite(Path.Empty)) {\n return null;\n } else {\n const filter = function (write: WriteRecord) {\n return (write.visible || includeHiddenWrites) &&\n (!writeIdsToExclude || !~writeIdsToExclude.indexOf(write.writeId)) &&\n (write.path.contains(treePath) || treePath.contains(write.path));\n };\n const mergeAtPath = WriteTree.layerTree_(this.allWrites_, filter, treePath);\n const layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE;\n return mergeAtPath.apply(layeredCache);\n }\n }\n }\n }\n\n /**\n * With optional, underlying server data, attempt to return a children node of children that we have complete data for.\n * Used when creating new views, to pre-fill their complete event children snapshot.\n *\n * @param {!Path} treePath\n * @param {?ChildrenNode} completeServerChildren\n * @return {!ChildrenNode}\n */\n calcCompleteEventChildren(treePath: Path, completeServerChildren: ChildrenNode | null) {\n let completeChildren = ChildrenNode.EMPTY_NODE as Node;\n const topLevelSet = this.visibleWrites_.getCompleteNode(treePath);\n if (topLevelSet) {\n if (!topLevelSet.isLeafNode()) {\n // we're shadowing everything. Return the children.\n topLevelSet.forEachChild(PRIORITY_INDEX, function (childName, childSnap) {\n completeChildren = completeChildren.updateImmediateChild(childName, childSnap);\n });\n }\n return completeChildren;\n } else if (completeServerChildren) {\n // Layer any children we have on top of this\n // We know we don't have a top-level set, so just enumerate existing children\n const merge = this.visibleWrites_.childCompoundWrite(treePath);\n completeServerChildren.forEachChild(PRIORITY_INDEX, function (childName, childNode) {\n const node = merge.childCompoundWrite(new Path(childName)).apply(childNode);\n completeChildren = completeChildren.updateImmediateChild(childName, node);\n });\n // Add any complete children we have from the set\n merge.getCompleteChildren().forEach(function (namedNode) {\n completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node);\n });\n return completeChildren;\n } else {\n // We don't have anything to layer on top of. Layer on any children we have\n // Note that we can return an empty snap if we have a defined delete\n const merge = this.visibleWrites_.childCompoundWrite(treePath);\n merge.getCompleteChildren().forEach(function (namedNode) {\n completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node);\n });\n return completeChildren;\n }\n }\n\n /**\n * Given that the underlying server data has updated, determine what, if anything, needs to be\n * applied to the event cache.\n *\n * Possibilities:\n *\n * 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data\n *\n * 2. Some write is completely shadowing. No events to be raised\n *\n * 3. Is partially shadowed. Events\n *\n * Either existingEventSnap or existingServerSnap must exist\n *\n * @param {!Path} treePath\n * @param {!Path} childPath\n * @param {?Node} existingEventSnap\n * @param {?Node} existingServerSnap\n * @return {?Node}\n */\n calcEventCacheAfterServerOverwrite(treePath: Path, childPath: Path, existingEventSnap: Node | null,\n existingServerSnap: Node | null): Node | null {\n assert(existingEventSnap || existingServerSnap,\n 'Either existingEventSnap or existingServerSnap must exist');\n const path = treePath.child(childPath);\n if (this.visibleWrites_.hasCompleteWrite(path)) {\n // At this point we can probably guarantee that we're in case 2, meaning no events\n // May need to check visibility while doing the findRootMostValueAndPath call\n return null;\n } else {\n // No complete shadowing. We're either partially shadowing or not shadowing at all.\n const childMerge = this.visibleWrites_.childCompoundWrite(path);\n if (childMerge.isEmpty()) {\n // We're not shadowing at all. Case 1\n return existingServerSnap.getChild(childPath);\n } else {\n // This could be more efficient if the serverNode + updates doesn't change the eventSnap\n // However this is tricky to find out, since user updates don't necessary change the server\n // snap, e.g. priority updates on empty nodes, or deep deletes. Another special case is if the server\n // adds nodes, but doesn't change any existing writes. It is therefore not enough to\n // only check if the updates change the serverNode.\n // Maybe check if the merge tree contains these special cases and only do a full overwrite in that case?\n return childMerge.apply(existingServerSnap.getChild(childPath));\n }\n }\n }\n\n /**\n * Returns a complete child for a given server snap after applying all user writes or null if there is no\n * complete child for this ChildKey.\n *\n * @param {!Path} treePath\n * @param {!string} childKey\n * @param {!CacheNode} existingServerSnap\n * @return {?Node}\n */\n calcCompleteChild(treePath: Path, childKey: string, existingServerSnap: CacheNode): Node | null {\n const path = treePath.child(childKey);\n const shadowingNode = this.visibleWrites_.getCompleteNode(path);\n if (shadowingNode != null) {\n return shadowingNode;\n } else {\n if (existingServerSnap.isCompleteForChild(childKey)) {\n const childMerge = this.visibleWrites_.childCompoundWrite(path);\n return childMerge.apply(existingServerSnap.getNode().getImmediateChild(childKey));\n } else {\n return null;\n }\n }\n }\n\n /**\n * Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at\n * a higher path, this will return the child of that write relative to the write and this path.\n * Returns null if there is no write at this path.\n *\n * @param {!Path} path\n * @return {?Node}\n */\n shadowingWrite(path: Path): Node | null {\n return this.visibleWrites_.getCompleteNode(path);\n }\n\n /**\n * This method is used when processing child remove events on a query. If we can, we pull in children that were outside\n * the window, but may now be in the window.\n *\n * @param {!Path} treePath\n * @param {?Node} completeServerData\n * @param {!NamedNode} startPost\n * @param {!number} count\n * @param {boolean} reverse\n * @param {!Index} index\n * @return {!Array.}\n */\n calcIndexedSlice(treePath: Path, completeServerData: Node | null, startPost: NamedNode, count: number,\n reverse: boolean, index: Index): NamedNode[] {\n let toIterate: Node;\n const merge = this.visibleWrites_.childCompoundWrite(treePath);\n const shadowingNode = merge.getCompleteNode(Path.Empty);\n if (shadowingNode != null) {\n toIterate = shadowingNode;\n } else if (completeServerData != null) {\n toIterate = merge.apply(completeServerData);\n } else {\n // no children to iterate on\n return [];\n }\n toIterate = toIterate.withIndex(index);\n if (!toIterate.isEmpty() && !toIterate.isLeafNode()) {\n const nodes = [];\n const cmp = index.getCompare();\n const iter = reverse ? (toIterate as ChildrenNode).getReverseIteratorFrom(startPost, index) :\n (toIterate as ChildrenNode).getIteratorFrom(startPost, index);\n let next = iter.getNext();\n while (next && nodes.length < count) {\n if (cmp(next, startPost) !== 0) {\n nodes.push(next);\n }\n next = iter.getNext();\n }\n return nodes;\n } else {\n return [];\n }\n }\n\n /**\n * @param {!WriteRecord} writeRecord\n * @param {!Path} path\n * @return {boolean}\n * @private\n */\n private recordContainsPath_(writeRecord: WriteRecord, path: Path): boolean {\n if (writeRecord.snap) {\n return writeRecord.path.contains(path);\n } else {\n // findKey can return undefined, so use !! to coerce to boolean\n return !!findKey(writeRecord.children, function (childSnap: Node, childName: string) {\n return writeRecord.path.child(childName).contains(path);\n });\n }\n }\n\n /**\n * Re-layer the writes and merges into a tree so we can efficiently calculate event snapshots\n * @private\n */\n private resetTree_() {\n this.visibleWrites_ = WriteTree.layerTree_(this.allWrites_, WriteTree.DefaultFilter_,\n Path.Empty);\n if (this.allWrites_.length > 0) {\n this.lastWriteId_ = this.allWrites_[this.allWrites_.length - 1].writeId;\n } else {\n this.lastWriteId_ = -1;\n }\n }\n\n /**\n * The default filter used when constructing the tree. Keep everything that's visible.\n *\n * @param {!WriteRecord} write\n * @return {boolean}\n * @private\n */\n private static DefaultFilter_(write: WriteRecord) {\n return write.visible;\n }\n\n /**\n * Static method. Given an array of WriteRecords, a filter for which ones to include, and a path, construct the tree of\n * event data at that path.\n *\n * @param {!Array.} writes\n * @param {!function(!WriteRecord):boolean} filter\n * @param {!Path} treeRoot\n * @return {!CompoundWrite}\n * @private\n */\n private static layerTree_(writes: WriteRecord[], filter: (w: WriteRecord) => boolean, treeRoot: Path): CompoundWrite {\n let compoundWrite = CompoundWrite.Empty;\n for (let i = 0; i < writes.length; ++i) {\n const write = writes[i];\n // Theory, a later set will either:\n // a) abort a relevant transaction, so no need to worry about excluding it from calculating that transaction\n // b) not be relevant to a transaction (separate branch), so again will not affect the data for that transaction\n if (filter(write)) {\n const writePath = write.path;\n let relativePath;\n if (write.snap) {\n if (treeRoot.contains(writePath)) {\n relativePath = Path.relativePath(treeRoot, writePath);\n compoundWrite = compoundWrite.addWrite(relativePath, write.snap);\n } else if (writePath.contains(treeRoot)) {\n relativePath = Path.relativePath(writePath, treeRoot);\n compoundWrite = compoundWrite.addWrite(Path.Empty, write.snap.getChild(relativePath));\n } else {\n // There is no overlap between root path and write path, ignore write\n }\n } else if (write.children) {\n if (treeRoot.contains(writePath)) {\n relativePath = Path.relativePath(treeRoot, writePath);\n compoundWrite = compoundWrite.addWrites(relativePath, write.children);\n } else if (writePath.contains(treeRoot)) {\n relativePath = Path.relativePath(writePath, treeRoot);\n if (relativePath.isEmpty()) {\n compoundWrite = compoundWrite.addWrites(Path.Empty, write.children);\n } else {\n const child = safeGet(write.children, relativePath.getFront());\n if (child) {\n // There exists a child in this node that matches the root path\n const deepNode = child.getChild(relativePath.popFront());\n compoundWrite = compoundWrite.addWrite(Path.Empty, deepNode);\n }\n }\n } else {\n // There is no overlap between root path and write path, ignore write\n }\n } else {\n throw assertionError('WriteRecord should have .snap or .children');\n }\n }\n }\n return compoundWrite;\n }\n}\n\n/**\n * A WriteTreeRef wraps a WriteTree and a path, for convenient access to a particular subtree. All of the methods\n * just proxy to the underlying WriteTree.\n *\n * @constructor\n */\nexport class WriteTreeRef {\n /**\n * The path to this particular write tree ref. Used for calling methods on writeTree_ while exposing a simpler\n * interface to callers.\n *\n * @type {!Path}\n * @private\n * @const\n */\n private readonly treePath_: Path;\n\n /**\n * * A reference to the actual tree of write data. All methods are pass-through to the tree, but with the appropriate\n * path prefixed.\n *\n * This lets us make cheap references to points in the tree for sync points without having to copy and maintain all of\n * the data.\n *\n * @type {!WriteTree}\n * @private\n * @const\n */\n private readonly writeTree_: WriteTree;\n\n /**\n * @param {!Path} path\n * @param {!WriteTree} writeTree\n */\n constructor(path: Path, writeTree: WriteTree) {\n this.treePath_ = path;\n this.writeTree_ = writeTree;\n }\n\n /**\n * If possible, returns a complete event cache, using the underlying server data if possible. In addition, can be used\n * to get a cache that includes hidden writes, and excludes arbitrary writes. Note that customizing the returned node\n * can lead to a more expensive calculation.\n *\n * @param {?Node} completeServerCache\n * @param {Array.=} writeIdsToExclude Optional writes to exclude.\n * @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false\n * @return {?Node}\n */\n calcCompleteEventCache(completeServerCache: Node | null, writeIdsToExclude?: number[],\n includeHiddenWrites?: boolean): Node | null {\n return this.writeTree_.calcCompleteEventCache(this.treePath_, completeServerCache, writeIdsToExclude,\n includeHiddenWrites);\n }\n\n /**\n * If possible, returns a children node containing all of the complete children we have data for. The returned data is a\n * mix of the given server data and write data.\n *\n * @param {?ChildrenNode} completeServerChildren\n * @return {!ChildrenNode}\n */\n calcCompleteEventChildren(completeServerChildren: ChildrenNode | null): ChildrenNode {\n return this.writeTree_.calcCompleteEventChildren(this.treePath_, completeServerChildren) as ChildrenNode;\n }\n\n /**\n * Given that either the underlying server data has updated or the outstanding writes have updated, determine what,\n * if anything, needs to be applied to the event cache.\n *\n * Possibilities:\n *\n * 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data\n *\n * 2. Some write is completely shadowing. No events to be raised\n *\n * 3. Is partially shadowed. Events should be raised\n *\n * Either existingEventSnap or existingServerSnap must exist, this is validated via an assert\n *\n * @param {!Path} path\n * @param {?Node} existingEventSnap\n * @param {?Node} existingServerSnap\n * @return {?Node}\n */\n calcEventCacheAfterServerOverwrite(path: Path, existingEventSnap: Node | null,\n existingServerSnap: Node | null): Node | null {\n return this.writeTree_.calcEventCacheAfterServerOverwrite(this.treePath_, path, existingEventSnap, existingServerSnap);\n }\n\n /**\n * Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at\n * a higher path, this will return the child of that write relative to the write and this path.\n * Returns null if there is no write at this path.\n *\n * @param {!Path} path\n * @return {?Node}\n */\n shadowingWrite(path: Path): Node | null {\n return this.writeTree_.shadowingWrite(this.treePath_.child(path));\n }\n\n /**\n * This method is used when processing child remove events on a query. If we can, we pull in children that were outside\n * the window, but may now be in the window\n *\n * @param {?Node} completeServerData\n * @param {!NamedNode} startPost\n * @param {!number} count\n * @param {boolean} reverse\n * @param {!Index} index\n * @return {!Array.}\n */\n calcIndexedSlice(completeServerData: Node | null, startPost: NamedNode, count: number,\n reverse: boolean, index: Index): NamedNode[] {\n return this.writeTree_.calcIndexedSlice(this.treePath_, completeServerData, startPost, count, reverse, index);\n }\n\n /**\n * Returns a complete child for a given server snap after applying all user writes or null if there is no\n * complete child for this ChildKey.\n *\n * @param {!string} childKey\n * @param {!CacheNode} existingServerCache\n * @return {?Node}\n */\n calcCompleteChild(childKey: string, existingServerCache: CacheNode): Node | null {\n return this.writeTree_.calcCompleteChild(this.treePath_, childKey, existingServerCache);\n }\n\n /**\n * Return a WriteTreeRef for a child.\n *\n * @param {string} childName\n * @return {!WriteTreeRef}\n */\n child(childName: string): WriteTreeRef {\n return new WriteTreeRef(this.treePath_.child(childName), this.writeTree_);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/WriteTree.ts","/**\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\nimport { assert } from '../../utils/assert';\nimport { errorForServerCode } from './util/util';\nimport { AckUserWrite } from './operation/AckUserWrite';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { forEach, safeGet } from '../../utils/obj';\nimport { ImmutableTree } from './util/ImmutableTree';\nimport { ListenComplete } from './operation/ListenComplete';\nimport { Merge } from './operation/Merge';\nimport { Operation, OperationSource } from './operation/Operation';\nimport { Overwrite } from './operation/Overwrite';\nimport { Path } from './util/Path';\nimport { SyncPoint } from './SyncPoint';\nimport { WriteTree, WriteTreeRef } from './WriteTree';\nimport { Query } from '../api/Query';\nimport { Node } from './snap/Node';\nimport { Event } from './view/Event';\nimport { EventRegistration } from './view/EventRegistration';\nimport { View } from './view/View';\n\n/**\n * @typedef {{\n * startListening: function(\n * !Query,\n * ?number,\n * function():string,\n * function(!string, *):!Array.\n * ):!Array.,\n *\n * stopListening: function(!Query, ?number)\n * }}\n */\nexport interface ListenProvider {\n startListening(query: Query,\n tag: number | null,\n hashFn: () => string,\n onComplete: (a: string, b?: any) => Event[]): Event[];\n\n stopListening(a: Query, b: number | null): void;\n}\n\n/**\n * SyncTree is the central class for managing event callback registration, data caching, views\n * (query processing), and event generation. There are typically two SyncTree instances for\n * each Repo, one for the normal Firebase data, and one for the .info data.\n *\n * It has a number of responsibilities, including:\n * - Tracking all user event callbacks (registered via addEventRegistration() and removeEventRegistration()).\n * - Applying and caching data changes for user set(), transaction(), and update() calls\n * (applyUserOverwrite(), applyUserMerge()).\n * - Applying and caching data changes for server data changes (applyServerOverwrite(),\n * applyServerMerge()).\n * - Generating user-facing events for server and user changes (all of the apply* methods\n * return the set of events that need to be raised as a result).\n * - Maintaining the appropriate set of server listens to ensure we are always subscribed\n * to the correct set of paths and queries to satisfy the current set of user event\n * callbacks (listens are started/stopped using the provided listenProvider).\n *\n * NOTE: Although SyncTree tracks event callbacks and calculates events to raise, the actual\n * events are returned to the caller rather than raised synchronously.\n *\n * @constructor\n */\nexport class SyncTree {\n /**\n * Tree of SyncPoints. There's a SyncPoint at any location that has 1 or more views.\n * @type {!ImmutableTree.}\n * @private\n */\n private syncPointTree_: ImmutableTree = ImmutableTree.Empty;\n\n /**\n * A tree of all pending user writes (user-initiated set()'s, transaction()'s, update()'s, etc.).\n * @type {!WriteTree}\n * @private\n */\n private pendingWriteTree_ = new WriteTree();\n\n private tagToQueryMap_: { [k: string]: string } = {};\n private queryToTagMap_: { [k: string]: number } = {};\n\n /**\n * @param {!ListenProvider} listenProvider_ Used by SyncTree to start / stop listening\n * to server data.\n */\n constructor(private listenProvider_: ListenProvider) {\n }\n\n /**\n * Apply the data changes for a user-generated set() or transaction() call.\n *\n * @param {!Path} path\n * @param {!Node} newData\n * @param {number} writeId\n * @param {boolean=} visible\n * @return {!Array.} Events to raise.\n */\n applyUserOverwrite(path: Path, newData: Node, writeId: number, visible?: boolean): Event[] {\n // Record pending write.\n this.pendingWriteTree_.addOverwrite(path, newData, writeId, visible);\n\n if (!visible) {\n return [];\n } else {\n return this.applyOperationToSyncPoints_(\n new Overwrite(OperationSource.User, path, newData));\n }\n }\n\n /**\n * Apply the data from a user-generated update() call\n *\n * @param {!Path} path\n * @param {!Object.} changedChildren\n * @param {!number} writeId\n * @return {!Array.} Events to raise.\n */\n applyUserMerge(path: Path, changedChildren: { [k: string]: Node }, writeId: number): Event[] {\n // Record pending merge.\n this.pendingWriteTree_.addMerge(path, changedChildren, writeId);\n\n const changeTree = ImmutableTree.fromObject(changedChildren);\n\n return this.applyOperationToSyncPoints_(\n new Merge(OperationSource.User, path, changeTree));\n }\n\n /**\n * Acknowledge a pending user write that was previously registered with applyUserOverwrite() or applyUserMerge().\n *\n * @param {!number} writeId\n * @param {boolean=} revert True if the given write failed and needs to be reverted\n * @return {!Array.} Events to raise.\n */\n ackUserWrite(writeId: number, revert: boolean = false) {\n const write = this.pendingWriteTree_.getWrite(writeId);\n const needToReevaluate = this.pendingWriteTree_.removeWrite(writeId);\n if (!needToReevaluate) {\n return [];\n } else {\n let affectedTree = ImmutableTree.Empty;\n if (write.snap != null) { // overwrite\n affectedTree = affectedTree.set(Path.Empty, true);\n } else {\n forEach(write.children, function (pathString: string, node: Node) {\n affectedTree = affectedTree.set(new Path(pathString), node);\n });\n }\n return this.applyOperationToSyncPoints_(new AckUserWrite(write.path, affectedTree, revert));\n }\n }\n\n /**\n * Apply new server data for the specified path..\n *\n * @param {!Path} path\n * @param {!Node} newData\n * @return {!Array.} Events to raise.\n */\n applyServerOverwrite(path: Path, newData: Node): Event[] {\n return this.applyOperationToSyncPoints_(\n new Overwrite(OperationSource.Server, path, newData));\n }\n\n /**\n * Apply new server data to be merged in at the specified path.\n *\n * @param {!Path} path\n * @param {!Object.} changedChildren\n * @return {!Array.} Events to raise.\n */\n applyServerMerge(path: Path, changedChildren: { [k: string]: Node }): Event[] {\n const changeTree = ImmutableTree.fromObject(changedChildren);\n\n return this.applyOperationToSyncPoints_(\n new Merge(OperationSource.Server, path, changeTree));\n }\n\n /**\n * Apply a listen complete for a query\n *\n * @param {!Path} path\n * @return {!Array.} Events to raise.\n */\n applyListenComplete(path: Path): Event[] {\n return this.applyOperationToSyncPoints_(\n new ListenComplete(OperationSource.Server, path));\n }\n\n /**\n * Apply new server data for the specified tagged query.\n *\n * @param {!Path} path\n * @param {!Node} snap\n * @param {!number} tag\n * @return {!Array.} Events to raise.\n */\n applyTaggedQueryOverwrite(path: Path, snap: Node, tag: number): Event[] {\n const queryKey = this.queryKeyForTag_(tag);\n if (queryKey != null) {\n const r = SyncTree.parseQueryKey_(queryKey);\n const queryPath = r.path, queryId = r.queryId;\n const relativePath = Path.relativePath(queryPath, path);\n const op = new Overwrite(OperationSource.forServerTaggedQuery(queryId),\n relativePath, snap);\n return this.applyTaggedOperation_(queryPath, op);\n } else {\n // Query must have been removed already\n return [];\n }\n }\n\n /**\n * Apply server data to be merged in for the specified tagged query.\n *\n * @param {!Path} path\n * @param {!Object.} changedChildren\n * @param {!number} tag\n * @return {!Array.} Events to raise.\n */\n applyTaggedQueryMerge(path: Path, changedChildren: { [k: string]: Node }, tag: number): Event[] {\n const queryKey = this.queryKeyForTag_(tag);\n if (queryKey) {\n const r = SyncTree.parseQueryKey_(queryKey);\n const queryPath = r.path, queryId = r.queryId;\n const relativePath = Path.relativePath(queryPath, path);\n const changeTree = ImmutableTree.fromObject(changedChildren);\n const op = new Merge(OperationSource.forServerTaggedQuery(queryId),\n relativePath, changeTree);\n return this.applyTaggedOperation_(queryPath, op);\n } else {\n // We've already removed the query. No big deal, ignore the update\n return [];\n }\n }\n\n /**\n * Apply a listen complete for a tagged query\n *\n * @param {!Path} path\n * @param {!number} tag\n * @return {!Array.} Events to raise.\n */\n applyTaggedListenComplete(path: Path, tag: number): Event[] {\n const queryKey = this.queryKeyForTag_(tag);\n if (queryKey) {\n const r = SyncTree.parseQueryKey_(queryKey);\n const queryPath = r.path, queryId = r.queryId;\n const relativePath = Path.relativePath(queryPath, path);\n const op = new ListenComplete(OperationSource.forServerTaggedQuery(queryId),\n relativePath);\n return this.applyTaggedOperation_(queryPath, op);\n } else {\n // We've already removed the query. No big deal, ignore the update\n return [];\n }\n }\n\n /**\n * Add an event callback for the specified query.\n *\n * @param {!Query} query\n * @param {!EventRegistration} eventRegistration\n * @return {!Array.} Events to raise.\n */\n addEventRegistration(query: Query, eventRegistration: EventRegistration): Event[] {\n const path = query.path;\n\n let serverCache: Node | null = null;\n let foundAncestorDefaultView = false;\n // Any covering writes will necessarily be at the root, so really all we need to find is the server cache.\n // Consider optimizing this once there's a better understanding of what actual behavior will be.\n this.syncPointTree_.foreachOnPath(path, function (pathToSyncPoint, sp) {\n const relativePath = Path.relativePath(pathToSyncPoint, path);\n serverCache = serverCache || sp.getCompleteServerCache(relativePath);\n foundAncestorDefaultView = foundAncestorDefaultView || sp.hasCompleteView();\n });\n let syncPoint = this.syncPointTree_.get(path);\n if (!syncPoint) {\n syncPoint = new SyncPoint();\n this.syncPointTree_ = this.syncPointTree_.set(path, syncPoint);\n } else {\n foundAncestorDefaultView = foundAncestorDefaultView || syncPoint.hasCompleteView();\n serverCache = serverCache || syncPoint.getCompleteServerCache(Path.Empty);\n }\n\n let serverCacheComplete;\n if (serverCache != null) {\n serverCacheComplete = true;\n } else {\n serverCacheComplete = false;\n serverCache = ChildrenNode.EMPTY_NODE;\n const subtree = this.syncPointTree_.subtree(path);\n subtree.foreachChild(function (childName, childSyncPoint) {\n const completeCache = childSyncPoint.getCompleteServerCache(Path.Empty);\n if (completeCache) {\n serverCache = serverCache.updateImmediateChild(childName, completeCache);\n }\n });\n }\n\n const viewAlreadyExists = syncPoint.viewExistsForQuery(query);\n if (!viewAlreadyExists && !query.getQueryParams().loadsAllData()) {\n // We need to track a tag for this query\n const queryKey = SyncTree.makeQueryKey_(query);\n assert(!(queryKey in this.queryToTagMap_),\n 'View does not exist, but we have a tag');\n const tag = SyncTree.getNextQueryTag_();\n this.queryToTagMap_[queryKey] = tag;\n // Coerce to string to avoid sparse arrays.\n this.tagToQueryMap_['_' + tag] = queryKey;\n }\n const writesCache = this.pendingWriteTree_.childWrites(path);\n let events = syncPoint.addEventRegistration(query, eventRegistration, writesCache, serverCache, serverCacheComplete);\n if (!viewAlreadyExists && !foundAncestorDefaultView) {\n const view = /** @type !View */ (syncPoint.viewForQuery(query));\n events = events.concat(this.setupListener_(query, view));\n }\n return events;\n }\n\n /**\n * Remove event callback(s).\n *\n * If query is the default query, we'll check all queries for the specified eventRegistration.\n * If eventRegistration is null, we'll remove all callbacks for the specified query/queries.\n *\n * @param {!Query} query\n * @param {?EventRegistration} eventRegistration If null, all callbacks are removed.\n * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\n * @return {!Array.} Cancel events, if cancelError was provided.\n */\n removeEventRegistration(query: Query, eventRegistration: EventRegistration | null,\n cancelError?: Error): Event[] {\n // Find the syncPoint first. Then deal with whether or not it has matching listeners\n const path = query.path;\n const maybeSyncPoint = this.syncPointTree_.get(path);\n let cancelEvents: Event[] = [];\n // A removal on a default query affects all queries at that location. A removal on an indexed query, even one without\n // other query constraints, does *not* affect all queries at that location. So this check must be for 'default', and\n // not loadsAllData().\n if (maybeSyncPoint && (query.queryIdentifier() === 'default' || maybeSyncPoint.viewExistsForQuery(query))) {\n /**\n * @type {{removed: !Array., events: !Array.}}\n */\n const removedAndEvents = maybeSyncPoint.removeEventRegistration(query, eventRegistration, cancelError);\n if (maybeSyncPoint.isEmpty()) {\n this.syncPointTree_ = this.syncPointTree_.remove(path);\n }\n const removed = removedAndEvents.removed;\n cancelEvents = removedAndEvents.events;\n // We may have just removed one of many listeners and can short-circuit this whole process\n // We may also not have removed a default listener, in which case all of the descendant listeners should already be\n // properly set up.\n //\n // Since indexed queries can shadow if they don't have other query constraints, check for loadsAllData(), instead of\n // queryId === 'default'\n const removingDefault = -1 !== removed.findIndex(function (query) {\n return query.getQueryParams().loadsAllData();\n });\n const covered = this.syncPointTree_.findOnPath(path, function (relativePath, parentSyncPoint) {\n return parentSyncPoint.hasCompleteView();\n });\n\n if (removingDefault && !covered) {\n const subtree = this.syncPointTree_.subtree(path);\n // There are potentially child listeners. Determine what if any listens we need to send before executing the\n // removal\n if (!subtree.isEmpty()) {\n // We need to fold over our subtree and collect the listeners to send\n const newViews = this.collectDistinctViewsForSubTree_(subtree);\n\n // Ok, we've collected all the listens we need. Set them up.\n for (let i = 0; i < newViews.length; ++i) {\n const view = newViews[i], newQuery = view.getQuery();\n const listener = this.createListenerForView_(view);\n this.listenProvider_.startListening(SyncTree.queryForListening_(newQuery), this.tagForQuery_(newQuery),\n listener.hashFn, listener.onComplete);\n }\n } else {\n // There's nothing below us, so nothing we need to start listening on\n }\n }\n // If we removed anything and we're not covered by a higher up listen, we need to stop listening on this query\n // The above block has us covered in terms of making sure we're set up on listens lower in the tree.\n // Also, note that if we have a cancelError, it's already been removed at the provider level.\n if (!covered && removed.length > 0 && !cancelError) {\n // If we removed a default, then we weren't listening on any of the other queries here. Just cancel the one\n // default. Otherwise, we need to iterate through and cancel each individual query\n if (removingDefault) {\n // We don't tag default listeners\n const defaultTag: number | null = null;\n this.listenProvider_.stopListening(SyncTree.queryForListening_(query), defaultTag);\n } else {\n removed.forEach((queryToRemove: Query) => {\n const tagToRemove = this.queryToTagMap_[SyncTree.makeQueryKey_(queryToRemove)];\n this.listenProvider_.stopListening(SyncTree.queryForListening_(queryToRemove), tagToRemove);\n });\n }\n }\n // Now, clear all of the tags we're tracking for the removed listens\n this.removeTags_(removed);\n } else {\n // No-op, this listener must've been already removed\n }\n return cancelEvents;\n }\n\n /**\n * Returns a complete cache, if we have one, of the data at a particular path. The location must have a listener above\n * it, but as this is only used by transaction code, that should always be the case anyways.\n *\n * Note: this method will *include* hidden writes from transaction with applyLocally set to false.\n * @param {!Path} path The path to the data we want\n * @param {Array.=} writeIdsToExclude A specific set to be excluded\n * @return {?Node}\n */\n calcCompleteEventCache(path: Path, writeIdsToExclude?: number[]): Node | null {\n const includeHiddenSets = true;\n const writeTree = this.pendingWriteTree_;\n const serverCache = this.syncPointTree_.findOnPath(path, function (pathSoFar, syncPoint) {\n const relativePath = Path.relativePath(pathSoFar, path);\n const serverCache = syncPoint.getCompleteServerCache(relativePath);\n if (serverCache) {\n return serverCache;\n }\n });\n return writeTree.calcCompleteEventCache(path, serverCache, writeIdsToExclude, includeHiddenSets);\n }\n\n /**\n * This collapses multiple unfiltered views into a single view, since we only need a single\n * listener for them.\n *\n * @param {!ImmutableTree.} subtree\n * @return {!Array.}\n * @private\n */\n private collectDistinctViewsForSubTree_(subtree: ImmutableTree): View[] {\n return subtree.fold((relativePath, maybeChildSyncPoint, childMap) => {\n if (maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {\n const completeView = maybeChildSyncPoint.getCompleteView();\n return [completeView];\n } else {\n // No complete view here, flatten any deeper listens into an array\n let views: View[] = [];\n if (maybeChildSyncPoint) {\n views = maybeChildSyncPoint.getQueryViews();\n }\n forEach(childMap, function (key: string, childViews: View[]) {\n views = views.concat(childViews);\n });\n return views;\n }\n });\n }\n\n /**\n * @param {!Array.} queries\n * @private\n */\n private removeTags_(queries: Query[]) {\n for (let j = 0; j < queries.length; ++j) {\n const removedQuery = queries[j];\n if (!removedQuery.getQueryParams().loadsAllData()) {\n // We should have a tag for this\n const removedQueryKey = SyncTree.makeQueryKey_(removedQuery);\n const removedQueryTag = this.queryToTagMap_[removedQueryKey];\n delete this.queryToTagMap_[removedQueryKey];\n delete this.tagToQueryMap_['_' + removedQueryTag];\n }\n }\n }\n\n\n /**\n * Normalizes a query to a query we send the server for listening\n * @param {!Query} query\n * @return {!Query} The normalized query\n * @private\n */\n private static queryForListening_(query: Query): Query {\n if (query.getQueryParams().loadsAllData() && !query.getQueryParams().isDefault()) {\n // We treat queries that load all data as default queries\n // Cast is necessary because ref() technically returns Firebase which is actually fb.api.Firebase which inherits\n // from Query\n return /** @type {!Query} */(query.getRef());\n } else {\n return query;\n }\n }\n\n\n /**\n * For a given new listen, manage the de-duplication of outstanding subscriptions.\n *\n * @param {!Query} query\n * @param {!View} view\n * @return {!Array.} This method can return events to support synchronous data sources\n * @private\n */\n private setupListener_(query: Query, view: View): Event[] {\n const path = query.path;\n const tag = this.tagForQuery_(query);\n const listener = this.createListenerForView_(view);\n\n const events = this.listenProvider_.startListening(SyncTree.queryForListening_(query), tag, listener.hashFn,\n listener.onComplete);\n\n const subtree = this.syncPointTree_.subtree(path);\n // The root of this subtree has our query. We're here because we definitely need to send a listen for that, but we\n // may need to shadow other listens as well.\n if (tag) {\n assert(!subtree.value.hasCompleteView(), 'If we\\'re adding a query, it shouldn\\'t be shadowed');\n } else {\n // Shadow everything at or below this location, this is a default listener.\n const queriesToStop = subtree.fold(function (relativePath, maybeChildSyncPoint, childMap) {\n if (!relativePath.isEmpty() && maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {\n return [maybeChildSyncPoint.getCompleteView().getQuery()];\n } else {\n // No default listener here, flatten any deeper queries into an array\n let queries: Query[] = [];\n if (maybeChildSyncPoint) {\n queries = queries.concat(\n maybeChildSyncPoint.getQueryViews().map(view=> view.getQuery())\n );\n }\n forEach(childMap, function (key: string, childQueries: Query[]) {\n queries = queries.concat(childQueries);\n });\n return queries;\n }\n });\n for (let i = 0; i < queriesToStop.length; ++i) {\n const queryToStop = queriesToStop[i];\n this.listenProvider_.stopListening(SyncTree.queryForListening_(queryToStop), this.tagForQuery_(queryToStop));\n }\n }\n return events;\n }\n\n /**\n *\n * @param {!View} view\n * @return {{hashFn: function(), onComplete: function(!string, *)}}\n * @private\n */\n private createListenerForView_(view: View): { hashFn(): string, onComplete(a: string, b?: any): Event[] } {\n const query = view.getQuery();\n const tag = this.tagForQuery_(query);\n\n return {\n hashFn: () => {\n const cache = view.getServerCache() || ChildrenNode.EMPTY_NODE;\n return cache.hash();\n },\n onComplete: (status: string): Event[] => {\n if (status === 'ok') {\n if (tag) {\n return this.applyTaggedListenComplete(query.path, tag);\n } else {\n return this.applyListenComplete(query.path);\n }\n } else {\n // If a listen failed, kill all of the listeners here, not just the one that triggered the error.\n // Note that this may need to be scoped to just this listener if we change permissions on filtered children\n const error = errorForServerCode(status, query);\n return this.removeEventRegistration(query, /*eventRegistration*/null, error);\n }\n }\n };\n }\n\n /**\n * Given a query, computes a \"queryKey\" suitable for use in our queryToTagMap_.\n * @private\n * @param {!Query} query\n * @return {string}\n */\n private static makeQueryKey_(query: Query): string {\n return query.path.toString() + '$' + query.queryIdentifier();\n }\n\n /**\n * Given a queryKey (created by makeQueryKey), parse it back into a path and queryId.\n * @private\n * @param {!string} queryKey\n * @return {{queryId: !string, path: !Path}}\n */\n private static parseQueryKey_(queryKey: string): { queryId: string, path: Path } {\n const splitIndex = queryKey.indexOf('$');\n assert(splitIndex !== -1 && splitIndex < queryKey.length - 1, 'Bad queryKey.');\n return {\n queryId: queryKey.substr(splitIndex + 1),\n path: new Path(queryKey.substr(0, splitIndex))\n };\n }\n\n /**\n * Return the query associated with the given tag, if we have one\n * @param {!number} tag\n * @return {?string}\n * @private\n */\n private queryKeyForTag_(tag: number): string | null {\n return this.tagToQueryMap_['_' + tag];\n }\n\n /**\n * Return the tag associated with the given query.\n * @param {!Query} query\n * @return {?number}\n * @private\n */\n private tagForQuery_(query: Query): number | null {\n const queryKey = SyncTree.makeQueryKey_(query);\n return safeGet(this.queryToTagMap_, queryKey);\n }\n\n /**\n * Static tracker for next query tag.\n * @type {number}\n * @private\n */\n private static nextQueryTag_ = 1;\n\n /**\n * Static accessor for query tags.\n * @return {number}\n * @private\n */\n private static getNextQueryTag_(): number {\n return SyncTree.nextQueryTag_++;\n }\n\n /**\n * A helper method to apply tagged operations\n *\n * @param {!Path} queryPath\n * @param {!Operation} operation\n * @return {!Array.}\n * @private\n */\n private applyTaggedOperation_(queryPath: Path, operation: Operation): Event[] {\n const syncPoint = this.syncPointTree_.get(queryPath);\n assert(syncPoint, 'Missing sync point for query tag that we\\'re tracking');\n const writesCache = this.pendingWriteTree_.childWrites(queryPath);\n return syncPoint.applyOperation(operation, writesCache, /*serverCache=*/null);\n }\n\n /**\n * A helper method that visits all descendant and ancestor SyncPoints, applying the operation.\n *\n * NOTES:\n * - Descendant SyncPoints will be visited first (since we raise events depth-first).\n\n * - We call applyOperation() on each SyncPoint passing three things:\n * 1. A version of the Operation that has been made relative to the SyncPoint location.\n * 2. A WriteTreeRef of any writes we have cached at the SyncPoint location.\n * 3. A snapshot Node with cached server data, if we have it.\n\n * - We concatenate all of the events returned by each SyncPoint and return the result.\n *\n * @param {!Operation} operation\n * @return {!Array.}\n * @private\n */\n private applyOperationToSyncPoints_(operation: Operation): Event[] {\n return this.applyOperationHelper_(operation, this.syncPointTree_, /*serverCache=*/ null,\n this.pendingWriteTree_.childWrites(Path.Empty));\n\n }\n\n /**\n * Recursive helper for applyOperationToSyncPoints_\n *\n * @private\n * @param {!Operation} operation\n * @param {ImmutableTree.} syncPointTree\n * @param {?Node} serverCache\n * @param {!WriteTreeRef} writesCache\n * @return {!Array.}\n */\n private applyOperationHelper_(operation: Operation, syncPointTree: ImmutableTree,\n serverCache: Node | null, writesCache: WriteTreeRef): Event[] {\n\n if (operation.path.isEmpty()) {\n return this.applyOperationDescendantsHelper_(operation, syncPointTree, serverCache, writesCache);\n } else {\n const syncPoint = syncPointTree.get(Path.Empty);\n\n // If we don't have cached server data, see if we can get it from this SyncPoint.\n if (serverCache == null && syncPoint != null) {\n serverCache = syncPoint.getCompleteServerCache(Path.Empty);\n }\n\n let events: Event[] = [];\n const childName = operation.path.getFront();\n const childOperation = operation.operationForChild(childName);\n const childTree = syncPointTree.children.get(childName);\n if (childTree && childOperation) {\n const childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null;\n const childWritesCache = writesCache.child(childName);\n events = events.concat(\n this.applyOperationHelper_(childOperation, childTree, childServerCache, childWritesCache));\n }\n\n if (syncPoint) {\n events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));\n }\n\n return events;\n }\n }\n\n /**\n * Recursive helper for applyOperationToSyncPoints_\n *\n * @private\n * @param {!Operation} operation\n * @param {ImmutableTree.} syncPointTree\n * @param {?Node} serverCache\n * @param {!WriteTreeRef} writesCache\n * @return {!Array.}\n */\n private applyOperationDescendantsHelper_(operation: Operation, syncPointTree: ImmutableTree,\n serverCache: Node | null, writesCache: WriteTreeRef): Event[] {\n const syncPoint = syncPointTree.get(Path.Empty);\n\n // If we don't have cached server data, see if we can get it from this SyncPoint.\n if (serverCache == null && syncPoint != null) {\n serverCache = syncPoint.getCompleteServerCache(Path.Empty);\n }\n\n let events: Event[] = [];\n syncPointTree.children.inorderTraversal((childName, childTree) => {\n const childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null;\n const childWritesCache = writesCache.child(childName);\n const childOperation = operation.operationForChild(childName);\n if (childOperation) {\n events = events.concat(\n this.applyOperationDescendantsHelper_(childOperation, childTree, childServerCache, childWritesCache));\n }\n });\n\n if (syncPoint) {\n events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));\n }\n\n return events;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/SyncTree.ts","/**\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\nimport { ChildrenNode } from \"./snap/ChildrenNode\";\nimport { Path } from './util/Path';\nimport { Node } from './snap/Node';\n\n/**\n * Mutable object which basically just stores a reference to the \"latest\" immutable snapshot.\n *\n * @constructor\n */\nexport class SnapshotHolder {\n private rootNode_: Node = ChildrenNode.EMPTY_NODE;\n\n getNode(path: Path): Node {\n return this.rootNode_.getChild(path);\n }\n\n updateSnapshot(path: Path, newSnapshotNode: Node) {\n this.rootNode_ = this.rootNode_.updateChild(path, newSnapshotNode);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/SnapshotHolder.ts","/**\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\nimport { log, warn } from './util/util';\nimport { FirebaseApp, FirebaseAuthTokenData } from '../../app/firebase_app';\n\n/**\n * Abstraction around FirebaseApp's token fetching capabilities.\n */\nexport class AuthTokenProvider {\n /**\n * @param {!FirebaseApp} app_\n */\n constructor(private app_: FirebaseApp) {\n }\n\n /**\n * @param {boolean} forceRefresh\n * @return {!Promise}\n */\n getToken(forceRefresh: boolean): Promise {\n return this.app_['INTERNAL']['getToken'](forceRefresh)\n .then(\n null,\n // .catch\n function (error) {\n // TODO: Need to figure out all the cases this is raised and whether\n // this makes sense.\n if (error && error.code === 'auth/token-not-initialized') {\n log('Got auth/token-not-initialized error. Treating as null token.');\n return null;\n } else {\n return Promise.reject(error);\n }\n });\n }\n\n addTokenChangeListener(listener: (token: string | null) => void) {\n // TODO: We might want to wrap the listener and call it with no args to\n // avoid a leaky abstraction, but that makes removing the listener harder.\n this.app_['INTERNAL']['addAuthTokenListener'](listener);\n }\n\n removeTokenChangeListener(listener: (token: string | null) => void) {\n this.app_['INTERNAL']['removeAuthTokenListener'](listener);\n }\n\n notifyForInvalidToken() {\n let errorMessage = 'Provided authentication credentials for the app named \"' +\n this.app_.name + '\" are invalid. This usually indicates your app was not ' +\n 'initialized correctly. ';\n if ('credential' in this.app_.options) {\n errorMessage += 'Make sure the \"credential\" property provided to initializeApp() ' +\n 'is authorized to access the specified \"databaseURL\" and is from the correct ' +\n 'project.';\n } else if ('serviceAccount' in this.app_.options) {\n errorMessage += 'Make sure the \"serviceAccount\" property provided to initializeApp() ' +\n 'is authorized to access the specified \"databaseURL\" and is from the correct ' +\n 'project.';\n } else {\n errorMessage += 'Make sure the \"apiKey\" and \"databaseURL\" properties provided to ' +\n 'initializeApp() match the values provided for your app at ' +\n 'https://console.firebase.google.com/.';\n }\n warn(errorMessage);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/AuthTokenProvider.ts","/**\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\nimport { clone, forEach } from '../../../utils/obj';\nimport { StatsCollection } from './StatsCollection';\n\n/**\n * Returns the delta from the previous call to get stats.\n *\n * @param collection_ The collection to \"listen\" to.\n * @constructor\n */\nexport class StatsListener {\n private last_: {[k: string]: number} | null = null;\n\n constructor(private collection_: StatsCollection) {\n }\n\n get(): {[k: string]: number} {\n const newStats = this.collection_.get();\n\n const delta: typeof newStats = clone(newStats);\n if (this.last_) {\n forEach(this.last_, (stat: string, value: number) => {\n delta[stat] = delta[stat] - value;\n });\n }\n this.last_ = newStats;\n\n return delta;\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/stats/StatsListener.ts","/**\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\nimport { contains, forEach } from '../../../utils/obj';\nimport { setTimeoutNonBlocking } from '../util/util';\nimport { StatsListener } from './StatsListener';\nimport { StatsCollection } from './StatsCollection';\nimport { ServerActions } from '../ServerActions';\n\n// Assuming some apps may have a short amount of time on page, and a bulk of firebase operations probably\n// happen on page load, we try to report our first set of stats pretty quickly, but we wait at least 10\n// seconds to try to ensure the Firebase connection is established / settled.\nconst FIRST_STATS_MIN_TIME = 10 * 1000;\nconst FIRST_STATS_MAX_TIME = 30 * 1000;\n\n// We'll continue to report stats on average every 5 minutes.\nconst REPORT_STATS_INTERVAL = 5 * 60 * 1000;\n\n/**\n * @constructor\n */\nexport class StatsReporter {\n private statsListener_: StatsListener;\n private statsToReport_: { [k: string]: boolean } = {};\n\n /**\n * @param collection\n * @param server_\n */\n constructor(collection: StatsCollection, private server_: ServerActions) {\n this.statsListener_ = new StatsListener(collection);\n\n const timeout = FIRST_STATS_MIN_TIME + (FIRST_STATS_MAX_TIME - FIRST_STATS_MIN_TIME) * Math.random();\n setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(timeout));\n }\n\n includeStat(stat: string) {\n this.statsToReport_[stat] = true;\n }\n\n private reportStats_() {\n const stats = this.statsListener_.get();\n const reportedStats: typeof stats = {};\n let haveStatsToReport = false;\n\n forEach(stats, (stat: string, value: number) => {\n if (value > 0 && contains(this.statsToReport_, stat)) {\n reportedStats[stat] = value;\n haveStatsToReport = true;\n }\n });\n\n if (haveStatsToReport) {\n this.server_.reportStats(reportedStats);\n }\n\n // queue our next run.\n setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL));\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/stats/StatsReporter.ts","/**\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\nimport { Path } from '../util/Path';\nimport { log, logger, exceptionGuard } from '../util/util';\nimport { Event } from './Event';\n\n/**\n * The event queue serves a few purposes:\n * 1. It ensures we maintain event order in the face of event callbacks doing operations that result in more\n * events being queued.\n * 2. raiseQueuedEvents() handles being called reentrantly nicely. That is, if in the course of raising events,\n * raiseQueuedEvents() is called again, the \"inner\" call will pick up raising events where the \"outer\" call\n * left off, ensuring that the events are still raised synchronously and in order.\n * 3. You can use raiseEventsAtPath and raiseEventsForChangedPath to ensure only relevant previously-queued\n * events are raised synchronously.\n *\n * NOTE: This can all go away if/when we move to async events.\n *\n * @constructor\n */\nexport class EventQueue {\n /**\n * @private\n * @type {!Array.}\n */\n private eventLists_: EventList[] = [];\n\n /**\n * Tracks recursion depth of raiseQueuedEvents_, for debugging purposes.\n * @private\n * @type {!number}\n */\n private recursionDepth_ = 0;\n\n\n /**\n * @param {!Array.} eventDataList The new events to queue.\n */\n queueEvents(eventDataList: Event[]) {\n // We group events by path, storing them in a single EventList, to make it easier to skip over them quickly.\n let currList = null;\n for (let i = 0; i < eventDataList.length; i++) {\n const eventData = eventDataList[i];\n const eventPath = eventData.getPath();\n if (currList !== null && !eventPath.equals(currList.getPath())) {\n this.eventLists_.push(currList);\n currList = null;\n }\n\n if (currList === null) {\n currList = new EventList(eventPath);\n }\n\n currList.add(eventData);\n }\n if (currList) {\n this.eventLists_.push(currList);\n }\n }\n\n /**\n * Queues the specified events and synchronously raises all events (including previously queued ones)\n * for the specified path.\n *\n * It is assumed that the new events are all for the specified path.\n *\n * @param {!Path} path The path to raise events for.\n * @param {!Array.} eventDataList The new events to raise.\n */\n raiseEventsAtPath(path: Path, eventDataList: Event[]) {\n this.queueEvents(eventDataList);\n this.raiseQueuedEventsMatchingPredicate_((eventPath: Path) => eventPath.equals(path));\n }\n\n /**\n * Queues the specified events and synchronously raises all events (including previously queued ones) for\n * locations related to the specified change path (i.e. all ancestors and descendants).\n *\n * It is assumed that the new events are all related (ancestor or descendant) to the specified path.\n *\n * @param {!Path} changedPath The path to raise events for.\n * @param {!Array.} eventDataList The events to raise\n */\n raiseEventsForChangedPath(changedPath: Path, eventDataList: Event[]) {\n this.queueEvents(eventDataList);\n\n this.raiseQueuedEventsMatchingPredicate_((eventPath: Path) => {\n return eventPath.contains(changedPath) || changedPath.contains(eventPath);\n });\n };\n\n /**\n * @param {!function(!Path):boolean} predicate\n * @private\n */\n private raiseQueuedEventsMatchingPredicate_(predicate: (path: Path) => boolean) {\n this.recursionDepth_++;\n\n let sentAll = true;\n for (let i = 0; i < this.eventLists_.length; i++) {\n const eventList = this.eventLists_[i];\n if (eventList) {\n const eventPath = eventList.getPath();\n if (predicate(eventPath)) {\n this.eventLists_[i].raise();\n this.eventLists_[i] = null;\n } else {\n sentAll = false;\n }\n }\n }\n\n if (sentAll) {\n this.eventLists_ = [];\n }\n\n this.recursionDepth_--;\n }\n}\n\n\n/**\n * @param {!Path} path\n * @constructor\n */\nexport class EventList {\n /**\n * @type {!Array.}\n * @private\n */\n private events_: Event[] = [];\n\n constructor(private readonly path_: Path) {\n }\n\n /**\n * @param {!Event} eventData\n */\n add(eventData: Event) {\n this.events_.push(eventData);\n }\n\n /**\n * Iterates through the list and raises each event\n */\n raise() {\n for (let i = 0; i < this.events_.length; i++) {\n const eventData = this.events_[i];\n if (eventData !== null) {\n this.events_[i] = null;\n const eventFn = eventData.getEventRunner();\n if (logger) {\n log('event: ' + eventData.toString());\n }\n exceptionGuard(eventFn);\n }\n }\n }\n\n /**\n * @return {!Path}\n */\n getPath(): Path {\n return this.path_;\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/EventQueue.ts","/**\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\nimport { assert } from '../../../utils/assert';\n\n/**\n * Base class to be used if you want to emit events. Call the constructor with\n * the set of allowed event names.\n */\nexport abstract class EventEmitter {\n private listeners_: { [eventType: string]: Array<{ callback(...args: any[]): void, context: any }> } = {};\n\n /**\n * @param {!Array.} allowedEvents_\n */\n constructor(private allowedEvents_: Array) {\n assert(Array.isArray(allowedEvents_) && allowedEvents_.length > 0,\n 'Requires a non-empty array');\n }\n\n /**\n * To be overridden by derived classes in order to fire an initial event when\n * somebody subscribes for data.\n *\n * @param {!string} eventType\n * @return {Array.<*>} Array of parameters to trigger initial event with.\n */\n abstract getInitialEvent(eventType: string): any[];\n\n /**\n * To be called by derived classes to trigger events.\n * @param {!string} eventType\n * @param {...*} var_args\n */\n protected trigger(eventType: string, ...var_args: any[]) {\n if (Array.isArray(this.listeners_[eventType])) {\n // Clone the list, since callbacks could add/remove listeners.\n const listeners = [\n ...this.listeners_[eventType]\n ];\n\n for (let i = 0; i < listeners.length; i++) {\n listeners[i].callback.apply(listeners[i].context, var_args);\n }\n }\n }\n\n on(eventType: string, callback: (a: any) => void, context: any) {\n this.validateEventType_(eventType);\n this.listeners_[eventType] = this.listeners_[eventType] || [];\n this.listeners_[eventType].push({callback, context});\n\n const eventData = this.getInitialEvent(eventType);\n if (eventData) {\n callback.apply(context, eventData);\n }\n }\n\n off(eventType: string, callback: (a: any) => void, context: any) {\n this.validateEventType_(eventType);\n const listeners = this.listeners_[eventType] || [];\n for (let i = 0; i < listeners.length; i++) {\n if (listeners[i].callback === callback && (!context || context === listeners[i].context)) {\n listeners.splice(i, 1);\n return;\n }\n }\n }\n\n private validateEventType_(eventType: string) {\n assert(this.allowedEvents_.find(function (et) {\n return et === eventType;\n }),\n 'Unknown event: ' + eventType\n );\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/EventEmitter.ts","/**\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\nimport { EventEmitter } from \"./EventEmitter\";\nimport { assert } from \"../../../utils/assert\";\n\ndeclare const document: any;\n\n/**\n * @extends {EventEmitter}\n */\nexport class VisibilityMonitor extends EventEmitter {\n private visible_: boolean;\n\n static getInstance() {\n return new VisibilityMonitor();\n }\n\n constructor() {\n super(['visible']);\n let hidden: string;\n let visibilityChange: string;\n if (typeof document !== 'undefined' && typeof document.addEventListener !== 'undefined') {\n if (typeof document['hidden'] !== 'undefined') {\n // Opera 12.10 and Firefox 18 and later support\n visibilityChange = 'visibilitychange';\n hidden = 'hidden';\n } else if (typeof document['mozHidden'] !== 'undefined') {\n visibilityChange = 'mozvisibilitychange';\n hidden = 'mozHidden';\n } else if (typeof document['msHidden'] !== 'undefined') {\n visibilityChange = 'msvisibilitychange';\n hidden = 'msHidden';\n } else if (typeof document['webkitHidden'] !== 'undefined') {\n visibilityChange = 'webkitvisibilitychange';\n hidden = 'webkitHidden';\n }\n }\n\n // Initially, we always assume we are visible. This ensures that in browsers\n // without page visibility support or in cases where we are never visible\n // (e.g. chrome extension), we act as if we are visible, i.e. don't delay\n // reconnects\n this.visible_ = true;\n\n if (visibilityChange) {\n document.addEventListener(visibilityChange, () => {\n const visible = !document[hidden];\n if (visible !== this.visible_) {\n this.visible_ = visible;\n this.trigger('visible', visible);\n }\n }, false);\n }\n }\n\n /**\n * @param {!string} eventType\n * @return {Array.}\n */\n getInitialEvent(eventType: string): boolean[] {\n assert(eventType === 'visible', 'Unknown event type: ' + eventType);\n return [this.visible_];\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/VisibilityMonitor.ts","/**\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\nimport { assert } from \"../../../utils/assert\";\nimport { EventEmitter } from \"./EventEmitter\";\nimport { isMobileCordova } from \"../../../utils/environment\";\n\n/**\n * Monitors online state (as reported by window.online/offline events).\n *\n * The expectation is that this could have many false positives (thinks we are online\n * when we're not), but no false negatives. So we can safely use it to determine when\n * we definitely cannot reach the internet.\n *\n * @extends {EventEmitter}\n */\nexport class OnlineMonitor extends EventEmitter {\n private online_ = true;\n\n static getInstance() {\n return new OnlineMonitor();\n }\n\n constructor() {\n super(['online']);\n\n // We've had repeated complaints that Cordova apps can get stuck \"offline\", e.g.\n // https://forum.ionicframework.com/t/firebase-connection-is-lost-and-never-come-back/43810\n // It would seem that the 'online' event does not always fire consistently. So we disable it\n // for Cordova.\n if (typeof window !== 'undefined' &&\n typeof window.addEventListener !== 'undefined' &&\n !isMobileCordova()) {\n window.addEventListener('online', () => {\n if (!this.online_) {\n this.online_ = true;\n this.trigger('online', true);\n }\n }, false);\n\n window.addEventListener('offline', () => {\n if (this.online_) {\n this.online_ = false;\n this.trigger('online', false);\n }\n }, false);\n }\n }\n\n /**\n * @param {!string} eventType\n * @return {Array.}\n */\n getInitialEvent(eventType: string): boolean[] {\n assert(eventType === 'online', 'Unknown event type: ' + eventType);\n return [this.online_];\n }\n\n /**\n * @return {boolean}\n */\n currentlyOnline(): boolean {\n return this.online_;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/OnlineMonitor.ts","/**\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\nimport { base64Decode } from \"../database/core/util/util\";\nimport { jsonEval } from \"./json\";\n\n/**\n * Decodes a Firebase auth. token into constituent parts.\n *\n * Notes:\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n *\n * @param {?string} token\n * @return {{header: *, claims: *, data: *, signature: string}}\n */\nexport const decode = function(token) {\n var header = {},\n claims = {},\n data = {},\n signature = '';\n\n try {\n var parts = token.split('.');\n header = jsonEval(base64Decode(parts[0]) || '');\n claims = jsonEval(base64Decode(parts[1]) || '');\n signature = parts[2];\n data = claims['d'] || {};\n delete claims['d'];\n } catch (e) {}\n\n return {\n header: header,\n claims: claims,\n data: data,\n signature: signature\n };\n};\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n *\n * @param {?string} token\n * @return {boolean}\n */\nexport const isValidTimestamp = function(token) {\n var claims = decode(token).claims,\n now = Math.floor(new Date().getTime() / 1000),\n validSince, validUntil;\n\n if (typeof claims === 'object') {\n if (claims.hasOwnProperty('nbf')) {\n validSince = claims['nbf'];\n } else if (claims.hasOwnProperty('iat')) {\n validSince = claims['iat'];\n }\n\n if (claims.hasOwnProperty('exp')) {\n validUntil = claims['exp'];\n } else {\n // token will expire after 24h by default\n validUntil = validSince + 86400;\n }\n }\n\n return now && validSince && validUntil &&\n (now >= validSince) && (now <= validUntil);\n};\n\n/**\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\n *\n * Notes:\n * - May return null if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n *\n * @param {?string} token\n * @return {?number}\n */\nexport const issuedAtTime = function(token) {\n var claims = decode(token).claims;\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\n return claims['iat'];\n }\n return null;\n};\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time and non-empty\n * signature.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n *\n * @param {?string} token\n * @return {boolean}\n */\nexport const isValidFormat = function(token) {\n var decoded = decode(token),\n claims = decoded.claims;\n\n return !!decoded.signature &&\n !!claims &&\n (typeof claims === 'object') &&\n claims.hasOwnProperty('iat');\n};\n\n/**\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n *\n * @param {?string} token\n * @return {boolean}\n */\nexport const isAdmin = function(token) {\n var claims = decode(token).claims;\n return (typeof claims === 'object' && claims['admin'] === true);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils/jwt.ts","/**\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\nimport { exceptionGuard } from '../../core/util/util';\n\n/**\n * This class ensures the packets from the server arrive in order\n * This class takes data from the server and ensures it gets passed into the callbacks in order.\n * @constructor\n */\nexport class PacketReceiver {\n pendingResponses: any[] = [];\n currentResponseNum = 0;\n closeAfterResponse = -1;\n onClose: (() => void) | null = null;\n\n /**\n * @param onMessage_\n */\n constructor(private onMessage_: (a: Object) => void) {\n }\n\n closeAfter(responseNum: number, callback: () => void) {\n this.closeAfterResponse = responseNum;\n this.onClose = callback;\n if (this.closeAfterResponse < this.currentResponseNum) {\n this.onClose();\n this.onClose = null;\n }\n }\n\n /**\n * Each message from the server comes with a response number, and an array of data. The responseNumber\n * allows us to ensure that we process them in the right order, since we can't be guaranteed that all\n * browsers will respond in the same order as the requests we sent\n * @param {number} requestNum\n * @param {Array} data\n */\n handleResponse(requestNum: number, data: any[]) {\n this.pendingResponses[requestNum] = data;\n while (this.pendingResponses[this.currentResponseNum]) {\n const toProcess = this.pendingResponses[this.currentResponseNum];\n delete this.pendingResponses[this.currentResponseNum];\n for (let i = 0; i < toProcess.length; ++i) {\n if (toProcess[i]) {\n exceptionGuard(() => {\n this.onMessage_(toProcess[i]);\n });\n }\n }\n if (this.currentResponseNum === this.closeAfterResponse) {\n if (this.onClose) {\n this.onClose();\n this.onClose = null;\n }\n break;\n }\n this.currentResponseNum++;\n }\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/realtime/polling/PacketReceiver.ts","/**\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\nimport {\n base64Encode,\n executeWhenDOMReady,\n isChromeExtensionContentScript,\n isWindowsStoreApp,\n log,\n logWrapper,\n LUIDGenerator,\n splitStringBySize\n} from '../core/util/util';\nimport { CountedSet } from '../core/util/CountedSet';\nimport { StatsManager } from '../core/stats/StatsManager';\nimport { PacketReceiver } from './polling/PacketReceiver';\nimport {\n FORGE_DOMAIN,\n FORGE_REF,\n LAST_SESSION_PARAM,\n LONG_POLLING,\n PROTOCOL_VERSION,\n REFERER_PARAM,\n TRANSPORT_SESSION_PARAM,\n VERSION_PARAM\n} from './Constants';\nimport { stringify } from '../../utils/json';\nimport { isNodeSdk } from '../../utils/environment';\nimport { Transport } from './Transport';\nimport { RepoInfo } from '../core/RepoInfo';\nimport { StatsCollection } from '../core/stats/StatsCollection';\n\n// URL query parameters associated with longpolling\nexport const FIREBASE_LONGPOLL_START_PARAM = 'start';\nexport const FIREBASE_LONGPOLL_CLOSE_COMMAND = 'close';\nexport const FIREBASE_LONGPOLL_COMMAND_CB_NAME = 'pLPCommand';\nexport const FIREBASE_LONGPOLL_DATA_CB_NAME = 'pRTLPCB';\nexport const FIREBASE_LONGPOLL_ID_PARAM = 'id';\nexport const FIREBASE_LONGPOLL_PW_PARAM = 'pw';\nexport const FIREBASE_LONGPOLL_SERIAL_PARAM = 'ser';\nexport const FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = 'cb';\nexport const FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = 'seg';\nexport const FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = 'ts';\nexport const FIREBASE_LONGPOLL_DATA_PARAM = 'd';\nexport const FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = 'disconn';\nexport const FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = 'dframe';\n\n//Data size constants.\n//TODO: Perf: the maximum length actually differs from browser to browser.\n// We should check what browser we're on and set accordingly.\nconst MAX_URL_DATA_SIZE = 1870;\nconst SEG_HEADER_SIZE = 30; //ie: &seg=8299234&ts=982389123&d=\nconst MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE;\n\n/**\n * Keepalive period\n * send a fresh request at minimum every 25 seconds. Opera has a maximum request\n * length of 30 seconds that we can't exceed.\n * @const\n * @type {number}\n */\nconst KEEPALIVE_REQUEST_INTERVAL = 25000;\n\n/**\n * How long to wait before aborting a long-polling connection attempt.\n * @const\n * @type {number}\n */\nconst LP_CONNECT_TIMEOUT = 30000;\n\n/**\n * This class manages a single long-polling connection.\n *\n * @constructor\n * @implements {Transport}\n */\nexport class BrowserPollConnection implements Transport {\n bytesSent = 0;\n bytesReceived = 0;\n urlFn: (params: object) => string;\n scriptTagHolder: FirebaseIFrameScriptHolder;\n myDisconnFrame: HTMLIFrameElement;\n curSegmentNum: number;\n myPacketOrderer: PacketReceiver;\n id: string;\n password: string;\n private log_: (...a: any[]) => void;\n private stats_: StatsCollection;\n private everConnected_ = false;\n private isClosed_: boolean;\n private connectTimeoutTimer_: number | null;\n private onDisconnect_: ((a?: boolean) => void) | null;\n\n /**\n * @param {string} connId An identifier for this connection, used for logging\n * @param {RepoInfo} repoInfo The info for the endpoint to send data to.\n * @param {string=} transportSessionId Optional transportSessionid if we are reconnecting for an existing\n * transport session\n * @param {string=} lastSessionId Optional lastSessionId if the PersistentConnection has already created a\n * connection previously\n */\n constructor(public connId: string, public repoInfo: RepoInfo,\n public transportSessionId?: string, public lastSessionId?: string) {\n this.log_ = logWrapper(connId);\n this.stats_ = StatsManager.getCollection(repoInfo);\n this.urlFn = (params: { [k: string]: string }) => repoInfo.connectionURL(LONG_POLLING, params);\n }\n\n /**\n *\n * @param {function(Object)} onMessage Callback when messages arrive\n * @param {function()} onDisconnect Callback with connection lost.\n */\n open(onMessage: (msg: Object) => void, onDisconnect: (a?: boolean) => void) {\n this.curSegmentNum = 0;\n this.onDisconnect_ = onDisconnect;\n this.myPacketOrderer = new PacketReceiver(onMessage);\n this.isClosed_ = false;\n\n this.connectTimeoutTimer_ = setTimeout(() => {\n this.log_('Timed out trying to connect.');\n // Make sure we clear the host cache\n this.onClosed_();\n this.connectTimeoutTimer_ = null;\n }, Math.floor(LP_CONNECT_TIMEOUT)) as any;\n\n // Ensure we delay the creation of the iframe until the DOM is loaded.\n executeWhenDOMReady(() => {\n if (this.isClosed_)\n return;\n\n //Set up a callback that gets triggered once a connection is set up.\n this.scriptTagHolder = new FirebaseIFrameScriptHolder((...args) => {\n const [command, arg1, arg2, arg3, arg4] = args;\n this.incrementIncomingBytes_(args);\n if (!this.scriptTagHolder)\n return; // we closed the connection.\n\n if (this.connectTimeoutTimer_) {\n clearTimeout(this.connectTimeoutTimer_);\n this.connectTimeoutTimer_ = null;\n }\n this.everConnected_ = true;\n if (command == FIREBASE_LONGPOLL_START_PARAM) {\n this.id = arg1;\n this.password = arg2;\n } else if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) {\n // Don't clear the host cache. We got a response from the server, so we know it's reachable\n if (arg1) {\n // We aren't expecting any more data (other than what the server's already in the process of sending us\n // through our already open polls), so don't send any more.\n this.scriptTagHolder.sendNewPolls = false;\n\n // arg1 in this case is the last response number sent by the server. We should try to receive\n // all of the responses up to this one before closing\n this.myPacketOrderer.closeAfter(arg1, () => { this.onClosed_(); });\n } else {\n this.onClosed_();\n }\n } else {\n throw new Error('Unrecognized command received: ' + command);\n }\n }, (...args) => {\n const [pN, data] = args;\n this.incrementIncomingBytes_(args);\n this.myPacketOrderer.handleResponse(pN, data);\n }, () => {\n this.onClosed_();\n }, this.urlFn);\n\n //Send the initial request to connect. The serial number is simply to keep the browser from pulling previous results\n //from cache.\n const urlParams: { [k: string]: string | number } = {};\n urlParams[FIREBASE_LONGPOLL_START_PARAM] = 't';\n urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(Math.random() * 100000000);\n if (this.scriptTagHolder.uniqueCallbackIdentifier)\n urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = this.scriptTagHolder.uniqueCallbackIdentifier;\n urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\n if (this.transportSessionId) {\n urlParams[TRANSPORT_SESSION_PARAM] = this.transportSessionId;\n }\n if (this.lastSessionId) {\n urlParams[LAST_SESSION_PARAM] = this.lastSessionId;\n }\n if (!isNodeSdk() &&\n typeof location !== 'undefined' &&\n location.href &&\n location.href.indexOf(FORGE_DOMAIN) !== -1) {\n urlParams[REFERER_PARAM] = FORGE_REF;\n }\n const connectURL = this.urlFn(urlParams);\n this.log_('Connecting via long-poll to ' + connectURL);\n this.scriptTagHolder.addTag(connectURL, () => { /* do nothing */ });\n });\n };\n\n /**\n * Call this when a handshake has completed successfully and we want to consider the connection established\n */\n start() {\n this.scriptTagHolder.startLongPoll(this.id, this.password);\n this.addDisconnectPingFrame(this.id, this.password);\n };\n\n private static forceAllow_: boolean;\n\n /**\n * Forces long polling to be considered as a potential transport\n */\n static forceAllow() {\n BrowserPollConnection.forceAllow_ = true;\n };\n\n private static forceDisallow_: boolean;\n\n /**\n * Forces longpolling to not be considered as a potential transport\n */\n static forceDisallow() {\n BrowserPollConnection.forceDisallow_ = true;\n };\n\n // Static method, use string literal so it can be accessed in a generic way\n static isAvailable() {\n // NOTE: In React-Native there's normally no 'document', but if you debug a React-Native app in\n // the Chrome debugger, 'document' is defined, but document.createElement is null (2015/06/08).\n return BrowserPollConnection.forceAllow_ || (\n !BrowserPollConnection.forceDisallow_ &&\n typeof document !== 'undefined' && document.createElement != null &&\n !isChromeExtensionContentScript() &&\n !isWindowsStoreApp() &&\n !isNodeSdk()\n );\n };\n\n /**\n * No-op for polling\n */\n markConnectionHealthy() { };\n\n /**\n * Stops polling and cleans up the iframe\n * @private\n */\n private shutdown_() {\n this.isClosed_ = true;\n\n if (this.scriptTagHolder) {\n this.scriptTagHolder.close();\n this.scriptTagHolder = null;\n }\n\n //remove the disconnect frame, which will trigger an XHR call to the server to tell it we're leaving.\n if (this.myDisconnFrame) {\n document.body.removeChild(this.myDisconnFrame);\n this.myDisconnFrame = null;\n }\n\n if (this.connectTimeoutTimer_) {\n clearTimeout(this.connectTimeoutTimer_);\n this.connectTimeoutTimer_ = null;\n }\n };\n\n /**\n * Triggered when this transport is closed\n * @private\n */\n private onClosed_() {\n if (!this.isClosed_) {\n this.log_('Longpoll is closing itself');\n this.shutdown_();\n\n if (this.onDisconnect_) {\n this.onDisconnect_(this.everConnected_);\n this.onDisconnect_ = null;\n }\n }\n };\n\n /**\n * External-facing close handler. RealTime has requested we shut down. Kill our connection and tell the server\n * that we've left.\n */\n close() {\n if (!this.isClosed_) {\n this.log_('Longpoll is being closed.');\n this.shutdown_();\n }\n };\n\n /**\n * Send the JSON object down to the server. It will need to be stringified, base64 encoded, and then\n * broken into chunks (since URLs have a small maximum length).\n * @param {!Object} data The JSON data to transmit.\n */\n send(data: Object) {\n const dataStr = stringify(data);\n this.bytesSent += dataStr.length;\n this.stats_.incrementCounter('bytes_sent', dataStr.length);\n\n //first, lets get the base64-encoded data\n const base64data = base64Encode(dataStr);\n\n //We can only fit a certain amount in each URL, so we need to split this request\n //up into multiple pieces if it doesn't fit in one request.\n const dataSegs = splitStringBySize(base64data, MAX_PAYLOAD_SIZE);\n\n //Enqueue each segment for transmission. We assign each chunk a sequential ID and a total number\n //of segments so that we can reassemble the packet on the server.\n for (let i = 0; i < dataSegs.length; i++) {\n this.scriptTagHolder.enqueueSegment(this.curSegmentNum, dataSegs.length, dataSegs[i]);\n this.curSegmentNum++;\n }\n };\n\n /**\n * This is how we notify the server that we're leaving.\n * We aren't able to send requests with DHTML on a window close event, but we can\n * trigger XHR requests in some browsers (everything but Opera basically).\n * @param {!string} id\n * @param {!string} pw\n */\n addDisconnectPingFrame(id: string, pw: string) {\n if (isNodeSdk()) return;\n this.myDisconnFrame = document.createElement('iframe');\n const urlParams: { [k: string]: string } = {};\n urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = 't';\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = id;\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = pw;\n this.myDisconnFrame.src = this.urlFn(urlParams);\n this.myDisconnFrame.style.display = 'none';\n\n document.body.appendChild(this.myDisconnFrame);\n };\n\n /**\n * Used to track the bytes received by this client\n * @param {*} args\n * @private\n */\n private incrementIncomingBytes_(args: any) {\n // TODO: This is an annoying perf hit just to track the number of incoming bytes. Maybe it should be opt-in.\n const bytesReceived = stringify(args).length;\n this.bytesReceived += bytesReceived;\n this.stats_.incrementCounter('bytes_received', bytesReceived);\n };\n}\n\nexport interface IFrameElement extends HTMLIFrameElement {\n doc: Document;\n}\n\n/*********************************************************************************************\n * A wrapper around an iframe that is used as a long-polling script holder.\n * @constructor\n *********************************************************************************************/\nexport class FirebaseIFrameScriptHolder {\n //We maintain a count of all of the outstanding requests, because if we have too many active at once it can cause\n //problems in some browsers.\n /**\n * @type {CountedSet.}\n */\n outstandingRequests = new CountedSet();\n\n //A queue of the pending segments waiting for transmission to the server.\n pendingSegs: { seg: number, ts: number, d: any }[] = [];\n\n //A serial number. We use this for two things:\n // 1) A way to ensure the browser doesn't cache responses to polls\n // 2) A way to make the server aware when long-polls arrive in a different order than we started them. The\n // server needs to release both polls in this case or it will cause problems in Opera since Opera can only execute\n // JSONP code in the order it was added to the iframe.\n currentSerial = Math.floor(Math.random() * 100000000);\n\n // This gets set to false when we're \"closing down\" the connection (e.g. we're switching transports but there's still\n // incoming data from the server that we're waiting for).\n sendNewPolls = true;\n\n uniqueCallbackIdentifier: number;\n myIFrame: IFrameElement;\n alive: boolean;\n myID: string;\n myPW: string;\n commandCB: (command: string, ...args: any[]) => void;\n onMessageCB: (...args: any[]) => void;\n\n /**\n * @param commandCB - The callback to be called when control commands are recevied from the server.\n * @param onMessageCB - The callback to be triggered when responses arrive from the server.\n * @param onDisconnect - The callback to be triggered when this tag holder is closed\n * @param urlFn - A function that provides the URL of the endpoint to send data to.\n */\n constructor(commandCB: (command: string, ...args: any[]) => void,\n onMessageCB: (...args: any[]) => void,\n public onDisconnect: () => void,\n public urlFn: (a: object) => string) {\n if (!isNodeSdk()) {\n //Each script holder registers a couple of uniquely named callbacks with the window. These are called from the\n //iframes where we put the long-polling script tags. We have two callbacks:\n // 1) Command Callback - Triggered for control issues, like starting a connection.\n // 2) Message Callback - Triggered when new data arrives.\n this.uniqueCallbackIdentifier = LUIDGenerator();\n (window as any)[FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier] = commandCB;\n (window as any)[FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier] = onMessageCB;\n\n //Create an iframe for us to add script tags to.\n this.myIFrame = FirebaseIFrameScriptHolder.createIFrame_();\n\n // Set the iframe's contents.\n let script = '';\n // if we set a javascript url, it's IE and we need to set the document domain. The javascript url is sufficient\n // for ie9, but ie8 needs to do it again in the document itself.\n if (this.myIFrame.src && this.myIFrame.src.substr(0, 'javascript:'.length) === 'javascript:') {\n const currentDomain = document.domain;\n script = '';\n }\n const iframeContents = '' + script + '';\n try {\n this.myIFrame.doc.open();\n this.myIFrame.doc.write(iframeContents);\n this.myIFrame.doc.close();\n } catch (e) {\n log('frame writing exception');\n if (e.stack) {\n log(e.stack);\n }\n log(e);\n }\n } else {\n this.commandCB = commandCB;\n this.onMessageCB = onMessageCB;\n }\n }\n\n /**\n * Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can\n * actually use.\n * @private\n * @return {Element}\n */\n private static createIFrame_(): IFrameElement {\n const iframe = document.createElement('iframe') as IFrameElement;\n iframe.style.display = 'none';\n\n // This is necessary in order to initialize the document inside the iframe\n if (document.body) {\n document.body.appendChild(iframe);\n try {\n // If document.domain has been modified in IE, this will throw an error, and we need to set the\n // domain of the iframe's document manually. We can do this via a javascript: url as the src attribute\n // Also note that we must do this *after* the iframe has been appended to the page. Otherwise it doesn't work.\n const a = iframe.contentWindow.document;\n if (!a) {\n // Apologies for the log-spam, I need to do something to keep closure from optimizing out the assignment above.\n log('No IE domain setting required');\n }\n } catch (e) {\n const domain = document.domain;\n iframe.src = 'javascript:void((function(){document.open();document.domain=\\'' + domain +\n '\\';document.close();})())';\n }\n } else {\n // LongPollConnection attempts to delay initialization until the document is ready, so hopefully this\n // never gets hit.\n throw 'Document body has not initialized. Wait to initialize Firebase until after the document is ready.';\n }\n\n // Get the document of the iframe in a browser-specific way.\n if (iframe.contentDocument) {\n (iframe as any).doc = iframe.contentDocument; // Firefox, Opera, Safari\n } else if (iframe.contentWindow) {\n (iframe as any).doc = iframe.contentWindow.document; // Internet Explorer\n } else if ((iframe as any).document) {\n (iframe as any).doc = (iframe as any).document; //others?\n }\n\n return iframe;\n }\n\n /**\n * Cancel all outstanding queries and remove the frame.\n */\n close() {\n //Mark this iframe as dead, so no new requests are sent.\n this.alive = false;\n\n if (this.myIFrame) {\n //We have to actually remove all of the html inside this iframe before removing it from the\n //window, or IE will continue loading and executing the script tags we've already added, which\n //can lead to some errors being thrown. Setting innerHTML seems to be the easiest way to do this.\n this.myIFrame.doc.body.innerHTML = '';\n setTimeout(() => {\n if (this.myIFrame !== null) {\n document.body.removeChild(this.myIFrame);\n this.myIFrame = null;\n }\n }, Math.floor(0));\n }\n\n if (isNodeSdk() && this.myID) {\n const urlParams: { [k: string]: string } = {};\n urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM] = 't';\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\n const theURL = this.urlFn(urlParams);\n (FirebaseIFrameScriptHolder as any).nodeRestRequest(theURL);\n }\n\n // Protect from being called recursively.\n const onDisconnect = this.onDisconnect;\n if (onDisconnect) {\n this.onDisconnect = null;\n onDisconnect();\n }\n }\n\n /**\n * Actually start the long-polling session by adding the first script tag(s) to the iframe.\n * @param {!string} id - The ID of this connection\n * @param {!string} pw - The password for this connection\n */\n startLongPoll(id: string, pw: string) {\n this.myID = id;\n this.myPW = pw;\n this.alive = true;\n\n //send the initial request. If there are requests queued, make sure that we transmit as many as we are currently able to.\n while (this.newRequest_()) {}\n };\n\n /**\n * This is called any time someone might want a script tag to be added. It adds a script tag when there aren't\n * too many outstanding requests and we are still alive.\n *\n * If there are outstanding packet segments to send, it sends one. If there aren't, it sends a long-poll anyways if\n * needed.\n */\n private newRequest_() {\n // We keep one outstanding request open all the time to receive data, but if we need to send data\n // (pendingSegs.length > 0) then we create a new request to send the data. The server will automatically\n // close the old request.\n if (this.alive && this.sendNewPolls && this.outstandingRequests.count() < (this.pendingSegs.length > 0 ? 2 : 1)) {\n //construct our url\n this.currentSerial++;\n const urlParams: { [k: string]: string | number } = {};\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\n urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial;\n let theURL = this.urlFn(urlParams);\n //Now add as much data as we can.\n let curDataString = '';\n let i = 0;\n\n while (this.pendingSegs.length > 0) {\n //first, lets see if the next segment will fit.\n const nextSeg = this.pendingSegs[0];\n if (nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <= MAX_URL_DATA_SIZE) {\n //great, the segment will fit. Lets append it.\n const theSeg = this.pendingSegs.shift();\n curDataString = curDataString + '&' + FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM + i + '=' + theSeg.seg +\n '&' + FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET + i + '=' + theSeg.ts + '&' + FIREBASE_LONGPOLL_DATA_PARAM + i + '=' + theSeg.d;\n i++;\n } else {\n break;\n }\n }\n\n theURL = theURL + curDataString;\n this.addLongPollTag_(theURL, this.currentSerial);\n\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Queue a packet for transmission to the server.\n * @param segnum - A sequential id for this packet segment used for reassembly\n * @param totalsegs - The total number of segments in this packet\n * @param data - The data for this segment.\n */\n enqueueSegment(segnum: number, totalsegs: number, data: any) {\n //add this to the queue of segments to send.\n this.pendingSegs.push({seg: segnum, ts: totalsegs, d: data});\n\n //send the data immediately if there isn't already data being transmitted, unless\n //startLongPoll hasn't been called yet.\n if (this.alive) {\n this.newRequest_();\n }\n };\n\n /**\n * Add a script tag for a regular long-poll request.\n * @param {!string} url - The URL of the script tag.\n * @param {!number} serial - The serial number of the request.\n * @private\n */\n private addLongPollTag_(url: string, serial: number) {\n //remember that we sent this request.\n this.outstandingRequests.add(serial, 1);\n\n const doNewRequest = () => {\n this.outstandingRequests.remove(serial);\n this.newRequest_();\n };\n\n // If this request doesn't return on its own accord (by the server sending us some data), we'll\n // create a new one after the KEEPALIVE interval to make sure we always keep a fresh request open.\n const keepaliveTimeout = setTimeout(doNewRequest, Math.floor(KEEPALIVE_REQUEST_INTERVAL));\n\n const readyStateCB = () => {\n // Request completed. Cancel the keepalive.\n clearTimeout(keepaliveTimeout);\n\n // Trigger a new request so we can continue receiving data.\n doNewRequest();\n };\n\n this.addTag(url, readyStateCB);\n };\n\n /**\n * Add an arbitrary script tag to the iframe.\n * @param {!string} url - The URL for the script tag source.\n * @param {!function()} loadCB - A callback to be triggered once the script has loaded.\n */\n addTag(url: string, loadCB: () => void) {\n if (isNodeSdk()) {\n (this as any).doNodeLongPoll(url, loadCB);\n } else {\n setTimeout(() => {\n try {\n // if we're already closed, don't add this poll\n if (!this.sendNewPolls) return;\n const newScript = this.myIFrame.doc.createElement('script');\n newScript.type = 'text/javascript';\n newScript.async = true;\n newScript.src = url;\n newScript.onload = (newScript as any).onreadystatechange = function () {\n const rstate = (newScript as any).readyState;\n if (!rstate || rstate === 'loaded' || rstate === 'complete') {\n newScript.onload = (newScript as any).onreadystatechange = null;\n if (newScript.parentNode) {\n newScript.parentNode.removeChild(newScript);\n }\n loadCB();\n }\n };\n newScript.onerror = () => {\n log('Long-poll script failed to load: ' + url);\n this.sendNewPolls = false;\n this.close();\n };\n this.myIFrame.doc.body.appendChild(newScript);\n } catch (e) {\n // TODO: we should make this error visible somehow\n }\n }, Math.floor(1));\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/realtime/BrowserPollConnection.ts","/**\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\nimport { BrowserPollConnection } from \"./BrowserPollConnection\";\nimport { WebSocketConnection } from \"./WebSocketConnection\";\nimport { warn, each } from \"../core/util/util\";\nimport { TransportConstructor } from './Transport';\nimport { RepoInfo } from '../core/RepoInfo';\n\n/**\n * Currently simplistic, this class manages what transport a Connection should use at various stages of its\n * lifecycle.\n *\n * It starts with longpolling in a browser, and httppolling on node. It then upgrades to websockets if\n * they are available.\n * @constructor\n */\nexport class TransportManager {\n private transports_: TransportConstructor[];\n\n /**\n * @const\n * @type {!Array.}\n */\n static get ALL_TRANSPORTS() {\n return [\n BrowserPollConnection,\n WebSocketConnection\n ];\n }\n\n /**\n * @param {!RepoInfo} repoInfo Metadata around the namespace we're connecting to\n */\n constructor(repoInfo: RepoInfo) {\n this.initTransports_(repoInfo);\n }\n\n /**\n * @param {!RepoInfo} repoInfo\n * @private\n */\n private initTransports_(repoInfo: RepoInfo) {\n const isWebSocketsAvailable: boolean = WebSocketConnection && WebSocketConnection['isAvailable']();\n let isSkipPollConnection = isWebSocketsAvailable && !WebSocketConnection.previouslyFailed();\n\n if (repoInfo.webSocketOnly) {\n if (!isWebSocketsAvailable)\n warn('wss:// URL used, but browser isn\\'t known to support websockets. Trying anyway.');\n\n isSkipPollConnection = true;\n }\n\n if (isSkipPollConnection) {\n this.transports_ = [WebSocketConnection];\n } else {\n const transports = this.transports_ = [] as TransportConstructor[];\n each(TransportManager.ALL_TRANSPORTS, (i: number, transport: TransportConstructor) => {\n if (transport && transport['isAvailable']()) {\n transports.push(transport);\n }\n });\n }\n }\n\n /**\n * @return {function(new:Transport, !string, !RepoInfo, string=, string=)} The constructor for the\n * initial transport to use\n */\n initialTransport(): TransportConstructor {\n if (this.transports_.length > 0) {\n return this.transports_[0];\n } else {\n throw new Error('No transports available');\n }\n }\n\n /**\n * @return {?function(new:Transport, function(),function(), string=)} The constructor for the next\n * transport, or null\n */\n upgradeTransport(): TransportConstructor | null {\n if (this.transports_.length > 1) {\n return this.transports_[1];\n } else {\n return null;\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/realtime/TransportManager.ts","/**\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\nimport {\n error,\n logWrapper,\n requireKey,\n setTimeoutNonBlocking,\n warn,\n} from '../core/util/util';\nimport { PersistentStorage } from '../core/storage/storage';\nimport { PROTOCOL_VERSION } from './Constants';\nimport { TransportManager } from './TransportManager';\nimport { RepoInfo } from '../core/RepoInfo';\nimport { Transport, TransportConstructor } from './Transport';\n\n// Abort upgrade attempt if it takes longer than 60s.\nconst UPGRADE_TIMEOUT = 60000;\n\n// For some transports (WebSockets), we need to \"validate\" the transport by exchanging a few requests and responses.\n// If we haven't sent enough requests within 5s, we'll start sending noop ping requests.\nconst DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5000;\n\n// If the initial data sent triggers a lot of bandwidth (i.e. it's a large put or a listen for a large amount of data)\n// then we may not be able to exchange our ping/pong requests within the healthy timeout. So if we reach the timeout\n// but we've sent/received enough bytes, we don't cancel the connection.\nconst BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024;\nconst BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024;\n\nconst enum RealtimeState {\n CONNECTING,\n CONNECTED,\n DISCONNECTED,\n}\n\nconst MESSAGE_TYPE = 't';\nconst MESSAGE_DATA = 'd';\nconst CONTROL_SHUTDOWN = 's';\nconst CONTROL_RESET = 'r';\nconst CONTROL_ERROR = 'e';\nconst CONTROL_PONG = 'o';\nconst SWITCH_ACK = 'a';\nconst END_TRANSMISSION = 'n';\nconst PING = 'p';\n\nconst SERVER_HELLO = 'h';\n\n\n/**\n * Creates a new real-time connection to the server using whichever method works\n * best in the current browser.\n *\n * @constructor\n */\nexport class Connection {\n connectionCount = 0;\n pendingDataMessages: any[] = [];\n sessionId: string;\n\n private conn_: Transport;\n private healthyTimeout_: number;\n private isHealthy_: boolean;\n private log_: (...args: any[]) => void;\n private primaryResponsesRequired_: number;\n private rx_: Transport;\n private secondaryConn_: Transport;\n private secondaryResponsesRequired_: number;\n private state_ = RealtimeState.CONNECTING;\n private transportManager_: TransportManager;\n private tx_: Transport;\n\n /**\n * @param {!string} id - an id for this connection\n * @param {!RepoInfo} repoInfo_ - the info for the endpoint to connect to\n * @param {function(Object)} onMessage_ - the callback to be triggered when a server-push message arrives\n * @param {function(number, string)} onReady_ - the callback to be triggered when this connection is ready to send messages.\n * @param {function()} onDisconnect_ - the callback to be triggered when a connection was lost\n * @param {function(string)} onKill_ - the callback to be triggered when this connection has permanently shut down.\n * @param {string=} lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server\n */\n constructor(public id: string,\n private repoInfo_: RepoInfo,\n private onMessage_: (a: Object) => void,\n private onReady_: (a: number, b: string) => void,\n private onDisconnect_: () => void,\n private onKill_: (a: string) => void,\n public lastSessionId?: string) {\n this.log_ = logWrapper('c:' + this.id + ':');\n this.transportManager_ = new TransportManager(repoInfo_);\n this.log_('Connection created');\n this.start_();\n }\n\n /**\n * Starts a connection attempt\n * @private\n */\n private start_() {\n const conn = this.transportManager_.initialTransport();\n this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_, undefined, this.lastSessionId);\n\n // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\n // can consider the transport healthy.\n this.primaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0;\n\n const onMessageReceived = this.connReceiver_(this.conn_);\n const onConnectionLost = this.disconnReceiver_(this.conn_);\n this.tx_ = this.conn_;\n this.rx_ = this.conn_;\n this.secondaryConn_ = null;\n this.isHealthy_ = false;\n\n /*\n * Firefox doesn't like when code from one iframe tries to create another iframe by way of the parent frame.\n * This can occur in the case of a redirect, i.e. we guessed wrong on what server to connect to and received a reset.\n * Somehow, setTimeout seems to make this ok. That doesn't make sense from a security perspective, since you should\n * still have the context of your originating frame.\n */\n setTimeout(() => {\n // this.conn_ gets set to null in some of the tests. Check to make sure it still exists before using it\n this.conn_ && this.conn_.open(onMessageReceived, onConnectionLost);\n }, Math.floor(0));\n\n\n const healthyTimeout_ms = conn['healthyTimeout'] || 0;\n if (healthyTimeout_ms > 0) {\n this.healthyTimeout_ = setTimeoutNonBlocking(() => {\n this.healthyTimeout_ = null;\n if (!this.isHealthy_) {\n if (this.conn_ && this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE) {\n this.log_('Connection exceeded healthy timeout but has received ' + this.conn_.bytesReceived +\n ' bytes. Marking connection healthy.');\n this.isHealthy_ = true;\n this.conn_.markConnectionHealthy();\n } else if (this.conn_ && this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE) {\n this.log_('Connection exceeded healthy timeout but has sent ' + this.conn_.bytesSent +\n ' bytes. Leaving connection alive.');\n // NOTE: We don't want to mark it healthy, since we have no guarantee that the bytes have made it to\n // the server.\n } else {\n this.log_('Closing unhealthy connection after timeout.');\n this.close();\n }\n }\n }, Math.floor(healthyTimeout_ms)) as any;\n }\n }\n\n /**\n * @return {!string}\n * @private\n */\n private nextTransportId_(): string {\n return 'c:' + this.id + ':' + this.connectionCount++;\n };\n\n private disconnReceiver_(conn) {\n return everConnected => {\n if (conn === this.conn_) {\n this.onConnectionLost_(everConnected);\n } else if (conn === this.secondaryConn_) {\n this.log_('Secondary connection lost.');\n this.onSecondaryConnectionLost_();\n } else {\n this.log_('closing an old connection');\n }\n }\n }\n\n private connReceiver_(conn: Transport) {\n return (message: object) => {\n if (this.state_ != RealtimeState.DISCONNECTED) {\n if (conn === this.rx_) {\n this.onPrimaryMessageReceived_(message);\n } else if (conn === this.secondaryConn_) {\n this.onSecondaryMessageReceived_(message);\n } else {\n this.log_('message on old connection');\n }\n }\n };\n }\n\n /**\n *\n * @param {Object} dataMsg An arbitrary data message to be sent to the server\n */\n sendRequest(dataMsg: object) {\n // wrap in a data message envelope and send it on\n const msg = {'t': 'd', 'd': dataMsg};\n this.sendData_(msg);\n }\n\n tryCleanupConnection() {\n if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) {\n this.log_('cleaning up and promoting a connection: ' + this.secondaryConn_.connId);\n this.conn_ = this.secondaryConn_;\n this.secondaryConn_ = null;\n // the server will shutdown the old connection\n }\n }\n\n private onSecondaryControl_(controlData: { [k: string]: any }) {\n if (MESSAGE_TYPE in controlData) {\n const cmd = controlData[MESSAGE_TYPE] as string;\n if (cmd === SWITCH_ACK) {\n this.upgradeIfSecondaryHealthy_();\n } else if (cmd === CONTROL_RESET) {\n // Most likely the session wasn't valid. Abandon the switch attempt\n this.log_('Got a reset on secondary, closing it');\n this.secondaryConn_.close();\n // If we were already using this connection for something, than we need to fully close\n if (this.tx_ === this.secondaryConn_ || this.rx_ === this.secondaryConn_) {\n this.close();\n }\n } else if (cmd === CONTROL_PONG) {\n this.log_('got pong on secondary.');\n this.secondaryResponsesRequired_--;\n this.upgradeIfSecondaryHealthy_();\n }\n }\n }\n\n private onSecondaryMessageReceived_(parsedData: object) {\n const layer: string = requireKey('t', parsedData);\n const data: any = requireKey('d', parsedData);\n if (layer == 'c') {\n this.onSecondaryControl_(data);\n } else if (layer == 'd') {\n // got a data message, but we're still second connection. Need to buffer it up\n this.pendingDataMessages.push(data);\n } else {\n throw new Error('Unknown protocol layer: ' + layer);\n }\n }\n\n private upgradeIfSecondaryHealthy_() {\n if (this.secondaryResponsesRequired_ <= 0) {\n this.log_('Secondary connection is healthy.');\n this.isHealthy_ = true;\n this.secondaryConn_.markConnectionHealthy();\n this.proceedWithUpgrade_();\n } else {\n // Send a ping to make sure the connection is healthy.\n this.log_('sending ping on secondary.');\n this.secondaryConn_.send({'t': 'c', 'd': {'t': PING, 'd': {}}});\n }\n }\n\n private proceedWithUpgrade_() {\n // tell this connection to consider itself open\n this.secondaryConn_.start();\n // send ack\n this.log_('sending client ack on secondary');\n this.secondaryConn_.send({'t': 'c', 'd': {'t': SWITCH_ACK, 'd': {}}});\n\n // send end packet on primary transport, switch to sending on this one\n // can receive on this one, buffer responses until end received on primary transport\n this.log_('Ending transmission on primary');\n this.conn_.send({'t': 'c', 'd': {'t': END_TRANSMISSION, 'd': {}}});\n this.tx_ = this.secondaryConn_;\n\n this.tryCleanupConnection();\n }\n\n private onPrimaryMessageReceived_(parsedData: { [k: string]: any }) {\n // Must refer to parsedData properties in quotes, so closure doesn't touch them.\n const layer: string = requireKey('t', parsedData);\n const data: any = requireKey('d', parsedData);\n if (layer == 'c') {\n this.onControl_(data);\n } else if (layer == 'd') {\n this.onDataMessage_(data);\n }\n }\n\n private onDataMessage_(message: any) {\n this.onPrimaryResponse_();\n\n // We don't do anything with data messages, just kick them up a level\n this.onMessage_(message);\n }\n\n private onPrimaryResponse_() {\n if (!this.isHealthy_) {\n this.primaryResponsesRequired_--;\n if (this.primaryResponsesRequired_ <= 0) {\n this.log_('Primary connection is healthy.');\n this.isHealthy_ = true;\n this.conn_.markConnectionHealthy();\n }\n }\n };\n\n private onControl_(controlData: { [k: string]: any }) {\n const cmd: string = requireKey(MESSAGE_TYPE, controlData);\n if (MESSAGE_DATA in controlData) {\n const payload = controlData[MESSAGE_DATA];\n if (cmd === SERVER_HELLO) {\n this.onHandshake_(payload);\n } else if (cmd === END_TRANSMISSION) {\n this.log_('recvd end transmission on primary');\n this.rx_ = this.secondaryConn_;\n for (let i = 0; i < this.pendingDataMessages.length; ++i) {\n this.onDataMessage_(this.pendingDataMessages[i]);\n }\n this.pendingDataMessages = [];\n this.tryCleanupConnection();\n } else if (cmd === CONTROL_SHUTDOWN) {\n // This was previously the 'onKill' callback passed to the lower-level connection\n // payload in this case is the reason for the shutdown. Generally a human-readable error\n this.onConnectionShutdown_(payload);\n } else if (cmd === CONTROL_RESET) {\n // payload in this case is the host we should contact\n this.onReset_(payload);\n } else if (cmd === CONTROL_ERROR) {\n error('Server Error: ' + payload);\n } else if (cmd === CONTROL_PONG) {\n this.log_('got pong on primary.');\n this.onPrimaryResponse_();\n this.sendPingOnPrimaryIfNecessary_();\n } else {\n error('Unknown control packet command: ' + cmd);\n }\n }\n }\n\n /**\n *\n * @param {Object} handshake The handshake data returned from the server\n * @private\n */\n private onHandshake_(handshake: { ts: number, v: string, h: string, s: string }) {\n const timestamp = handshake.ts;\n const version = handshake.v;\n const host = handshake.h;\n this.sessionId = handshake.s;\n this.repoInfo_.updateHost(host);\n // if we've already closed the connection, then don't bother trying to progress further\n if (this.state_ == RealtimeState.CONNECTING) {\n this.conn_.start();\n this.onConnectionEstablished_(this.conn_, timestamp);\n if (PROTOCOL_VERSION !== version) {\n warn('Protocol version mismatch detected');\n }\n // TODO: do we want to upgrade? when? maybe a delay?\n this.tryStartUpgrade_();\n }\n }\n\n private tryStartUpgrade_() {\n const conn = this.transportManager_.upgradeTransport();\n if (conn) {\n this.startUpgrade_(conn);\n }\n }\n\n private startUpgrade_(conn: TransportConstructor) {\n this.secondaryConn_ = new conn(this.nextTransportId_(),\n this.repoInfo_, this.sessionId);\n // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\n // can consider the transport healthy.\n this.secondaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0;\n\n const onMessage = this.connReceiver_(this.secondaryConn_);\n const onDisconnect = this.disconnReceiver_(this.secondaryConn_);\n this.secondaryConn_.open(onMessage, onDisconnect);\n\n // If we haven't successfully upgraded after UPGRADE_TIMEOUT, give up and kill the secondary.\n setTimeoutNonBlocking(() => {\n if (this.secondaryConn_) {\n this.log_('Timed out trying to upgrade.');\n this.secondaryConn_.close();\n }\n }, Math.floor(UPGRADE_TIMEOUT));\n }\n\n private onReset_(host: string) {\n this.log_('Reset packet received. New host: ' + host);\n this.repoInfo_.updateHost(host);\n // TODO: if we're already \"connected\", we need to trigger a disconnect at the next layer up.\n // We don't currently support resets after the connection has already been established\n if (this.state_ === RealtimeState.CONNECTED) {\n this.close();\n } else {\n // Close whatever connections we have open and start again.\n this.closeConnections_();\n this.start_();\n }\n }\n\n private onConnectionEstablished_(conn: Transport, timestamp: number) {\n this.log_('Realtime connection established.');\n this.conn_ = conn;\n this.state_ = RealtimeState.CONNECTED;\n\n if (this.onReady_) {\n this.onReady_(timestamp, this.sessionId);\n this.onReady_ = null;\n }\n\n // If after 5 seconds we haven't sent enough requests to the server to get the connection healthy,\n // send some pings.\n if (this.primaryResponsesRequired_ === 0) {\n this.log_('Primary connection is healthy.');\n this.isHealthy_ = true;\n } else {\n setTimeoutNonBlocking(() => {\n this.sendPingOnPrimaryIfNecessary_();\n }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS));\n }\n }\n\n private sendPingOnPrimaryIfNecessary_() {\n // If the connection isn't considered healthy yet, we'll send a noop ping packet request.\n if (!this.isHealthy_ && this.state_ === RealtimeState.CONNECTED) {\n this.log_('sending ping on primary.');\n this.sendData_({'t': 'c', 'd': {'t': PING, 'd': {}}});\n }\n }\n\n private onSecondaryConnectionLost_() {\n const conn = this.secondaryConn_;\n this.secondaryConn_ = null;\n if (this.tx_ === conn || this.rx_ === conn) {\n // we are relying on this connection already in some capacity. Therefore, a failure is real\n this.close();\n }\n }\n\n /**\n *\n * @param {boolean} everConnected Whether or not the connection ever reached a server. Used to determine if\n * we should flush the host cache\n * @private\n */\n private onConnectionLost_(everConnected: boolean) {\n this.conn_ = null;\n\n // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting\n // called on window close and RealtimeState.CONNECTING is no longer defined. Just a guess.\n if (!everConnected && this.state_ === RealtimeState.CONNECTING) {\n this.log_('Realtime connection failed.');\n // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away\n if (this.repoInfo_.isCacheableHost()) {\n PersistentStorage.remove('host:' + this.repoInfo_.host);\n // reset the internal host to what we would show the user, i.e. .firebaseio.com\n this.repoInfo_.internalHost = this.repoInfo_.host;\n }\n } else if (this.state_ === RealtimeState.CONNECTED) {\n this.log_('Realtime connection lost.');\n }\n\n this.close();\n }\n\n /**\n *\n * @param {string} reason\n * @private\n */\n private onConnectionShutdown_(reason: string) {\n this.log_('Connection shutdown command received. Shutting down...');\n\n if (this.onKill_) {\n this.onKill_(reason);\n this.onKill_ = null;\n }\n\n // We intentionally don't want to fire onDisconnect (kill is a different case),\n // so clear the callback.\n this.onDisconnect_ = null;\n\n this.close();\n }\n\n\n private sendData_(data: object) {\n if (this.state_ !== RealtimeState.CONNECTED) {\n throw 'Connection is not connected';\n } else {\n this.tx_.send(data);\n }\n }\n\n /**\n * Cleans up this connection, calling the appropriate callbacks\n */\n close() {\n if (this.state_ !== RealtimeState.DISCONNECTED) {\n this.log_('Closing realtime connection.');\n this.state_ = RealtimeState.DISCONNECTED;\n\n this.closeConnections_();\n\n if (this.onDisconnect_) {\n this.onDisconnect_();\n this.onDisconnect_ = null;\n }\n }\n }\n\n /**\n *\n * @private\n */\n private closeConnections_() {\n this.log_('Shutting down all connections');\n if (this.conn_) {\n this.conn_.close();\n this.conn_ = null;\n }\n\n if (this.secondaryConn_) {\n this.secondaryConn_.close();\n this.secondaryConn_ = null;\n }\n\n if (this.healthyTimeout_) {\n clearTimeout(this.healthyTimeout_);\n this.healthyTimeout_ = null;\n }\n }\n}\n\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/realtime/Connection.ts","/**\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\nimport { Query } from '../api/Query';\n\n/**\n * Interface defining the set of actions that can be performed against the Firebase server\n * (basically corresponds to our wire protocol).\n *\n * @interface\n */\nexport abstract class ServerActions {\n\n /**\n * @param {!Query} query\n * @param {function():string} currentHashFn\n * @param {?number} tag\n * @param {function(string, *)} onComplete\n */\n abstract listen(query: Query, currentHashFn: () => string, tag: number | null,\n onComplete: (a: string, b: any) => void): void;\n\n /**\n * Remove a listen.\n *\n * @param {!Query} query\n * @param {?number} tag\n */\n abstract unlisten(query: Query, tag: number | null): void;\n\n /**\n * @param {string} pathString\n * @param {*} data\n * @param {function(string, string)=} onComplete\n * @param {string=} hash\n */\n put(pathString: string, data: any, onComplete?: (a: string, b: string) => void, hash?: string) { }\n\n /**\n * @param {string} pathString\n * @param {*} data\n * @param {function(string, ?string)} onComplete\n * @param {string=} hash\n */\n merge(pathString: string, data: any, onComplete: (a: string, b: string | null) => void, hash?: string) { }\n\n /**\n * Refreshes the auth token for the current connection.\n * @param {string} token The authentication token\n */\n refreshAuthToken(token: string) { }\n\n /**\n * @param {string} pathString\n * @param {*} data\n * @param {function(string, string)=} onComplete\n */\n onDisconnectPut(pathString: string, data: any, onComplete?: (a: string, b: string) => void) { }\n\n /**\n * @param {string} pathString\n * @param {*} data\n * @param {function(string, string)=} onComplete\n */\n onDisconnectMerge(pathString: string, data: any, onComplete?: (a: string, b: string) => void) { }\n\n /**\n * @param {string} pathString\n * @param {function(string, string)=} onComplete\n */\n onDisconnectCancel(pathString: string, onComplete?: (a: string, b: string) => void) { }\n\n /**\n * @param {Object.} stats\n */\n reportStats(stats: { [k: string]: any }) { }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/ServerActions.ts","/**\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\nimport firebase from '../../app';\nimport { forEach, contains, isEmpty, getCount, safeGet } from '../../utils/obj';\nimport { stringify } from '../../utils/json';\nimport { assert } from '../../utils/assert';\nimport { error, log, logWrapper, warn, ObjectToUniqueKey } from './util/util';\nimport { Path } from './util/Path';\nimport { VisibilityMonitor } from './util/VisibilityMonitor';\nimport { OnlineMonitor } from './util/OnlineMonitor';\nimport { isAdmin, isValidFormat } from '../../utils/jwt';\nimport { Connection } from '../realtime/Connection';\nimport { CONSTANTS } from '../../utils/constants';\nimport {\n isMobileCordova,\n isReactNative,\n isNodeSdk\n} from '../../utils/environment';\nimport { ServerActions } from './ServerActions';\nimport { AuthTokenProvider } from './AuthTokenProvider';\nimport { RepoInfo } from './RepoInfo';\nimport { Query } from '../api/Query';\n\nconst RECONNECT_MIN_DELAY = 1000;\nconst RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1000; // 5 minutes in milliseconds (Case: 1858)\nconst RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1000; // 30 seconds for admin clients (likely to be a backend server)\nconst RECONNECT_DELAY_MULTIPLIER = 1.3;\nconst RECONNECT_DELAY_RESET_TIMEOUT = 30000; // Reset delay back to MIN_DELAY after being connected for 30sec.\nconst SERVER_KILL_INTERRUPT_REASON = 'server_kill';\n\n// If auth fails repeatedly, we'll assume something is wrong and log a warning / back off.\nconst INVALID_AUTH_TOKEN_THRESHOLD = 3;\n\ninterface ListenSpec {\n onComplete(s: string, p?: any): void;\n\n hashFn(): string;\n\n query: Query;\n tag: number | null;\n}\n\ninterface OnDisconnectRequest {\n pathString: string;\n action: string;\n data: any;\n onComplete?: (a: string, b: string) => void;\n}\n\ninterface OutstandingPut {\n action: string;\n request: Object;\n queued?: boolean;\n onComplete: (a: string, b?: string) => void;\n}\n\n/**\n * Firebase connection. Abstracts wire protocol and handles reconnecting.\n *\n * NOTE: All JSON objects sent to the realtime connection must have property names enclosed\n * in quotes to make sure the closure compiler does not minify them.\n */\nexport class PersistentConnection extends ServerActions {\n // Used for diagnostic logging.\n id = PersistentConnection.nextPersistentConnectionId_++;\n private log_ = logWrapper('p:' + this.id + ':');\n\n /** @private {Object} */\n private interruptReasons_: { [reason: string]: boolean } = {};\n private listens_: { [path: string]: { [queryId: string]: ListenSpec } } = {};\n private outstandingPuts_: OutstandingPut[] = [];\n private outstandingPutCount_ = 0;\n private onDisconnectRequestQueue_: OnDisconnectRequest[] = [];\n private connected_ = false;\n private reconnectDelay_ = RECONNECT_MIN_DELAY;\n private maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT;\n private securityDebugCallback_: ((a: Object) => void) | null = null;\n lastSessionId: string | null = null;\n\n /** @private {number|null} */\n private establishConnectionTimer_: number | null = null;\n\n /** @private {boolean} */\n private visible_: boolean = false;\n\n // Before we get connected, we keep a queue of pending messages to send.\n private requestCBHash_: { [k: number]: (a: any) => void } = {};\n private requestNumber_ = 0;\n\n /** @private {?{\n * sendRequest(Object),\n * close()\n * }} */\n private realtime_: { sendRequest(a: Object): void, close(): void } | null = null;\n\n /** @private {string|null} */\n private authToken_: string | null = null;\n private forceTokenRefresh_ = false;\n private invalidAuthTokenCount_ = 0;\n\n private firstConnection_ = true;\n private lastConnectionAttemptTime_: number | null = null;\n private lastConnectionEstablishedTime_: number | null = null;\n\n\n /**\n * @private\n */\n private static nextPersistentConnectionId_ = 0;\n\n /**\n * Counter for number of connections created. Mainly used for tagging in the logs\n * @type {number}\n * @private\n */\n private static nextConnectionId_ = 0;\n\n /**\n * @implements {ServerActions}\n * @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to\n * @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server\n * @param onConnectStatus_\n * @param onServerInfoUpdate_\n * @param authTokenProvider_\n * @param authOverride_\n */\n constructor(private repoInfo_: RepoInfo,\n private onDataUpdate_: (a: string, b: any, c: boolean, d: number | null) => void,\n private onConnectStatus_: (a: boolean) => void,\n private onServerInfoUpdate_: (a: any) => void,\n private authTokenProvider_: AuthTokenProvider,\n private authOverride_?: Object | null) {\n super();\n\n if (authOverride_ && !isNodeSdk()) {\n throw new Error('Auth override specified in options, but not supported on non Node.js platforms');\n }\n this.scheduleConnect_(0);\n\n VisibilityMonitor.getInstance().on('visible', this.onVisible_, this);\n\n if (repoInfo_.host.indexOf('fblocal') === -1) {\n OnlineMonitor.getInstance().on('online', this.onOnline_, this);\n }\n }\n\n /**\n * @param {!string} action\n * @param {*} body\n * @param {function(*)=} onResponse\n * @protected\n */\n protected sendRequest(action: string, body: any, onResponse?: (a: any) => void) {\n const curReqNum = ++this.requestNumber_;\n\n const msg = {'r': curReqNum, 'a': action, 'b': body};\n this.log_(stringify(msg));\n assert(this.connected_, 'sendRequest call when we\\'re not connected not allowed.');\n this.realtime_.sendRequest(msg);\n if (onResponse) {\n this.requestCBHash_[curReqNum] = onResponse;\n }\n }\n\n /**\n * @inheritDoc\n */\n listen(query: Query, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: any) => void) {\n const queryId = query.queryIdentifier();\n const pathString = query.path.toString();\n this.log_('Listen called for ' + pathString + ' ' + queryId);\n this.listens_[pathString] = this.listens_[pathString] || {};\n assert(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(),\n 'listen() called for non-default but complete query');\n assert(!this.listens_[pathString][queryId], 'listen() called twice for same path/queryId.');\n const listenSpec: ListenSpec = {\n onComplete: onComplete,\n hashFn: currentHashFn,\n query: query,\n tag: tag\n };\n this.listens_[pathString][queryId] = listenSpec;\n\n if (this.connected_) {\n this.sendListen_(listenSpec);\n }\n }\n\n /**\n * @param {!{onComplete(),\n * hashFn():!string,\n * query: !Query,\n * tag: ?number}} listenSpec\n * @private\n */\n private sendListen_(listenSpec: ListenSpec) {\n const query = listenSpec.query;\n const pathString = query.path.toString();\n const queryId = query.queryIdentifier();\n this.log_('Listen on ' + pathString + ' for ' + queryId);\n const req: { [k: string]: any } = {/*path*/ 'p': pathString};\n\n const action = 'q';\n\n // Only bother to send query if it's non-default.\n if (listenSpec.tag) {\n req['q'] = query.queryObject();\n req['t'] = listenSpec.tag;\n }\n\n req[/*hash*/'h'] = listenSpec.hashFn();\n\n this.sendRequest(action, req, (message: { [k: string]: any }) => {\n const payload: any = message[/*data*/ 'd'];\n const status: string = message[/*status*/ 's'];\n\n // print warnings in any case...\n PersistentConnection.warnOnListenWarnings_(payload, query);\n\n const currentListenSpec = this.listens_[pathString] && this.listens_[pathString][queryId];\n // only trigger actions if the listen hasn't been removed and readded\n if (currentListenSpec === listenSpec) {\n this.log_('listen response', message);\n\n if (status !== 'ok') {\n this.removeListen_(pathString, queryId);\n }\n\n if (listenSpec.onComplete) {\n listenSpec.onComplete(status, payload);\n }\n }\n });\n }\n\n /**\n * @param {*} payload\n * @param {!Query} query\n * @private\n */\n private static warnOnListenWarnings_(payload: any, query: Query) {\n if (payload && typeof payload === 'object' && contains(payload, 'w')) {\n const warnings = safeGet(payload, 'w');\n if (Array.isArray(warnings) && ~warnings.indexOf('no_index')) {\n const indexSpec = '\".indexOn\": \"' + query.getQueryParams().getIndex().toString() + '\"';\n const indexPath = query.path.toString();\n warn('Using an unspecified index. Consider adding ' + indexSpec + ' at ' + indexPath +\n ' to your security rules for better performance');\n }\n }\n }\n\n /**\n * @inheritDoc\n */\n refreshAuthToken(token: string) {\n this.authToken_ = token;\n this.log_('Auth token refreshed');\n if (this.authToken_) {\n this.tryAuth();\n } else {\n //If we're connected we want to let the server know to unauthenticate us. If we're not connected, simply delete\n //the credential so we dont become authenticated next time we connect.\n if (this.connected_) {\n this.sendRequest('unauth', {}, () => { });\n }\n }\n\n this.reduceReconnectDelayIfAdminCredential_(token);\n }\n\n /**\n * @param {!string} credential\n * @private\n */\n private reduceReconnectDelayIfAdminCredential_(credential: string) {\n // NOTE: This isn't intended to be bulletproof (a malicious developer can always just modify the client).\n // Additionally, we don't bother resetting the max delay back to the default if auth fails / expires.\n const isFirebaseSecret = credential && credential.length === 40;\n if (isFirebaseSecret || isAdmin(credential)) {\n this.log_('Admin auth credential detected. Reducing max reconnect time.');\n this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\n }\n }\n\n /**\n * Attempts to authenticate with the given credentials. If the authentication attempt fails, it's triggered like\n * a auth revoked (the connection is closed).\n */\n tryAuth() {\n if (this.connected_ && this.authToken_) {\n const token = this.authToken_;\n const authMethod = isValidFormat(token) ? 'auth' : 'gauth';\n const requestData: { [k: string]: any } = {'cred': token};\n if (this.authOverride_ === null) {\n requestData['noauth'] = true;\n } else if (typeof this.authOverride_ === 'object') {\n requestData['authvar'] = this.authOverride_;\n }\n this.sendRequest(authMethod, requestData, (res: { [k: string]: any }) => {\n const status: string = res[/*status*/ 's'];\n const data: string = res[/*data*/ 'd'] || 'error';\n\n if (this.authToken_ === token) {\n if (status === 'ok') {\n this.invalidAuthTokenCount_ = 0;\n } else {\n // Triggers reconnect and force refresh for auth token\n this.onAuthRevoked_(status, data);\n }\n }\n });\n }\n }\n\n /**\n * @inheritDoc\n */\n unlisten(query: Query, tag: number | null) {\n const pathString = query.path.toString();\n const queryId = query.queryIdentifier();\n\n this.log_('Unlisten called for ' + pathString + ' ' + queryId);\n\n assert(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(),\n 'unlisten() called for non-default but complete query');\n const listen = this.removeListen_(pathString, queryId);\n if (listen && this.connected_) {\n this.sendUnlisten_(pathString, queryId, query.queryObject(), tag);\n }\n }\n\n private sendUnlisten_(pathString: string, queryId: string, queryObj: Object, tag: number | null) {\n this.log_('Unlisten on ' + pathString + ' for ' + queryId);\n\n const req: { [k: string]: any } = {/*path*/ 'p': pathString};\n const action = 'n';\n // Only bother sending queryId if it's non-default.\n if (tag) {\n req['q'] = queryObj;\n req['t'] = tag;\n }\n\n this.sendRequest(action, req);\n }\n\n /**\n * @inheritDoc\n */\n onDisconnectPut(pathString: string, data: any, onComplete?: (a: string, b: string) => void) {\n if (this.connected_) {\n this.sendOnDisconnect_('o', pathString, data, onComplete);\n } else {\n this.onDisconnectRequestQueue_.push({\n pathString,\n action: 'o',\n data,\n onComplete\n });\n }\n }\n\n /**\n * @inheritDoc\n */\n onDisconnectMerge(pathString: string, data: any, onComplete?: (a: string, b: string) => void) {\n if (this.connected_) {\n this.sendOnDisconnect_('om', pathString, data, onComplete);\n } else {\n this.onDisconnectRequestQueue_.push({\n pathString,\n action: 'om',\n data,\n onComplete\n });\n }\n }\n\n /**\n * @inheritDoc\n */\n onDisconnectCancel(pathString: string, onComplete?: (a: string, b: string) => void) {\n if (this.connected_) {\n this.sendOnDisconnect_('oc', pathString, null, onComplete);\n } else {\n this.onDisconnectRequestQueue_.push({\n pathString,\n action: 'oc',\n data: null,\n onComplete\n });\n }\n }\n\n private sendOnDisconnect_(action: string, pathString: string, data: any, onComplete: (a: string, b: string) => void) {\n const request = {/*path*/ 'p': pathString, /*data*/ 'd': data};\n this.log_('onDisconnect ' + action, request);\n this.sendRequest(action, request, (response: { [k: string]: any }) => {\n if (onComplete) {\n setTimeout(function () {\n onComplete(response[/*status*/ 's'], response[/* data */'d']);\n }, Math.floor(0));\n }\n });\n }\n\n /**\n * @inheritDoc\n */\n put(pathString: string, data: any, onComplete?: (a: string, b: string) => void, hash?: string) {\n this.putInternal('p', pathString, data, onComplete, hash);\n }\n\n /**\n * @inheritDoc\n */\n merge(pathString: string, data: any, onComplete: (a: string, b: string | null) => void, hash?: string) {\n this.putInternal('m', pathString, data, onComplete, hash);\n }\n\n putInternal(action: string, pathString: string, data: any,\n onComplete: (a: string, b: string | null) => void, hash?: string) {\n const request: { [k: string]: any } = {/*path*/ 'p': pathString, /*data*/ 'd': data};\n\n if (hash !== undefined)\n request[/*hash*/ 'h'] = hash;\n\n // TODO: Only keep track of the most recent put for a given path?\n this.outstandingPuts_.push({\n action,\n request,\n onComplete\n });\n\n this.outstandingPutCount_++;\n const index = this.outstandingPuts_.length - 1;\n\n if (this.connected_) {\n this.sendPut_(index);\n } else {\n this.log_('Buffering put: ' + pathString);\n }\n }\n\n private sendPut_(index: number) {\n const action = this.outstandingPuts_[index].action;\n const request = this.outstandingPuts_[index].request;\n const onComplete = this.outstandingPuts_[index].onComplete;\n this.outstandingPuts_[index].queued = this.connected_;\n\n this.sendRequest(action, request, (message: { [k: string]: any }) => {\n this.log_(action + ' response', message);\n\n delete this.outstandingPuts_[index];\n this.outstandingPutCount_--;\n\n // Clean up array occasionally.\n if (this.outstandingPutCount_ === 0) {\n this.outstandingPuts_ = [];\n }\n\n if (onComplete)\n onComplete(message[/*status*/ 's'], message[/* data */ 'd']);\n });\n }\n\n /**\n * @inheritDoc\n */\n reportStats(stats: { [k: string]: any }) {\n // If we're not connected, we just drop the stats.\n if (this.connected_) {\n const request = {/*counters*/ 'c': stats};\n this.log_('reportStats', request);\n\n this.sendRequest(/*stats*/ 's', request, (result) => {\n const status = result[/*status*/ 's'];\n if (status !== 'ok') {\n const errorReason = result[/* data */ 'd'];\n this.log_('reportStats', 'Error sending stats: ' + errorReason);\n }\n });\n }\n }\n\n /**\n * @param {*} message\n * @private\n */\n private onDataMessage_(message: { [k: string]: any }) {\n if ('r' in message) {\n // this is a response\n this.log_('from server: ' + stringify(message));\n const reqNum = message['r'];\n const onResponse = this.requestCBHash_[reqNum];\n if (onResponse) {\n delete this.requestCBHash_[reqNum];\n onResponse(message[/*body*/ 'b']);\n }\n } else if ('error' in message) {\n throw 'A server-side error has occurred: ' + message['error'];\n } else if ('a' in message) {\n // a and b are action and body, respectively\n this.onDataPush_(message['a'], message['b']);\n }\n }\n\n private onDataPush_(action: string, body: { [k: string]: any }) {\n this.log_('handleServerMessage', action, body);\n if (action === 'd')\n this.onDataUpdate_(body[/*path*/ 'p'], body[/*data*/ 'd'], /*isMerge*/false, body['t']);\n else if (action === 'm')\n this.onDataUpdate_(body[/*path*/ 'p'], body[/*data*/ 'd'], /*isMerge=*/true, body['t']);\n else if (action === 'c')\n this.onListenRevoked_(body[/*path*/ 'p'], body[/*query*/ 'q']);\n else if (action === 'ac')\n this.onAuthRevoked_(body[/*status code*/ 's'], body[/* explanation */ 'd']);\n else if (action === 'sd')\n this.onSecurityDebugPacket_(body);\n else\n error('Unrecognized action received from server: ' + stringify(action) +\n '\\nAre you using the latest client?');\n }\n\n private onReady_(timestamp: number, sessionId: string) {\n this.log_('connection ready');\n this.connected_ = true;\n this.lastConnectionEstablishedTime_ = new Date().getTime();\n this.handleTimestamp_(timestamp);\n this.lastSessionId = sessionId;\n if (this.firstConnection_) {\n this.sendConnectStats_();\n }\n this.restoreState_();\n this.firstConnection_ = false;\n this.onConnectStatus_(true);\n }\n\n private scheduleConnect_(timeout: number) {\n assert(!this.realtime_, 'Scheduling a connect when we\\'re already connected/ing?');\n\n if (this.establishConnectionTimer_) {\n clearTimeout(this.establishConnectionTimer_);\n }\n\n // NOTE: Even when timeout is 0, it's important to do a setTimeout to work around an infuriating \"Security Error\" in\n // Firefox when trying to write to our long-polling iframe in some scenarios (e.g. Forge or our unit tests).\n\n this.establishConnectionTimer_ = setTimeout(() => {\n this.establishConnectionTimer_ = null;\n this.establishConnection_();\n }, Math.floor(timeout)) as any;\n }\n\n /**\n * @param {boolean} visible\n * @private\n */\n private onVisible_(visible: boolean) {\n // NOTE: Tabbing away and back to a window will defeat our reconnect backoff, but I think that's fine.\n if (visible && !this.visible_ && this.reconnectDelay_ === this.maxReconnectDelay_) {\n this.log_('Window became visible. Reducing delay.');\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n\n if (!this.realtime_) {\n this.scheduleConnect_(0);\n }\n }\n this.visible_ = visible;\n }\n\n private onOnline_(online: boolean) {\n if (online) {\n this.log_('Browser went online.');\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n if (!this.realtime_) {\n this.scheduleConnect_(0);\n }\n } else {\n this.log_('Browser went offline. Killing connection.');\n if (this.realtime_) {\n this.realtime_.close();\n }\n }\n }\n\n private onRealtimeDisconnect_() {\n this.log_('data client disconnected');\n this.connected_ = false;\n this.realtime_ = null;\n\n // Since we don't know if our sent transactions succeeded or not, we need to cancel them.\n this.cancelSentTransactions_();\n\n // Clear out the pending requests.\n this.requestCBHash_ = {};\n\n if (this.shouldReconnect_()) {\n if (!this.visible_) {\n this.log_('Window isn\\'t visible. Delaying reconnect.');\n this.reconnectDelay_ = this.maxReconnectDelay_;\n this.lastConnectionAttemptTime_ = new Date().getTime();\n } else if (this.lastConnectionEstablishedTime_) {\n // If we've been connected long enough, reset reconnect delay to minimum.\n const timeSinceLastConnectSucceeded = new Date().getTime() - this.lastConnectionEstablishedTime_;\n if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT)\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n this.lastConnectionEstablishedTime_ = null;\n }\n\n const timeSinceLastConnectAttempt = new Date().getTime() - this.lastConnectionAttemptTime_;\n let reconnectDelay = Math.max(0, this.reconnectDelay_ - timeSinceLastConnectAttempt);\n reconnectDelay = Math.random() * reconnectDelay;\n\n this.log_('Trying to reconnect in ' + reconnectDelay + 'ms');\n this.scheduleConnect_(reconnectDelay);\n\n // Adjust reconnect delay for next time.\n this.reconnectDelay_ = Math.min(this.maxReconnectDelay_, this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER);\n }\n this.onConnectStatus_(false);\n }\n\n private establishConnection_() {\n if (this.shouldReconnect_()) {\n this.log_('Making a connection attempt');\n this.lastConnectionAttemptTime_ = new Date().getTime();\n this.lastConnectionEstablishedTime_ = null;\n const onDataMessage = this.onDataMessage_.bind(this);\n const onReady = this.onReady_.bind(this);\n const onDisconnect = this.onRealtimeDisconnect_.bind(this);\n const connId = this.id + ':' + PersistentConnection.nextConnectionId_++;\n const self = this;\n const lastSessionId = this.lastSessionId;\n let canceled = false;\n let connection: Connection | null = null;\n const closeFn = function () {\n if (connection) {\n connection.close();\n } else {\n canceled = true;\n onDisconnect();\n }\n };\n const sendRequestFn = function (msg: Object) {\n assert(connection, 'sendRequest call when we\\'re not connected not allowed.');\n connection.sendRequest(msg);\n };\n\n this.realtime_ = {\n close: closeFn,\n sendRequest: sendRequestFn\n };\n\n const forceRefresh = this.forceTokenRefresh_;\n this.forceTokenRefresh_ = false;\n\n // First fetch auth token, and establish connection after fetching the token was successful\n this.authTokenProvider_.getToken(forceRefresh).then(function (result) {\n if (!canceled) {\n log('getToken() completed. Creating connection.');\n self.authToken_ = result && result.accessToken;\n connection = new Connection(connId, self.repoInfo_,\n onDataMessage,\n onReady,\n onDisconnect, /* onKill= */ function (reason) {\n warn(reason + ' (' + self.repoInfo_.toString() + ')');\n self.interrupt(SERVER_KILL_INTERRUPT_REASON);\n },\n lastSessionId);\n } else {\n log('getToken() completed but was canceled');\n }\n }).then(null, function (error) {\n self.log_('Failed to get token: ' + error);\n if (!canceled) {\n if (CONSTANTS.NODE_ADMIN) {\n // This may be a critical error for the Admin Node.js SDK, so log a warning.\n // But getToken() may also just have temporarily failed, so we still want to\n // continue retrying.\n warn(error);\n }\n closeFn();\n }\n });\n }\n }\n\n /**\n * @param {string} reason\n */\n interrupt(reason: string) {\n log('Interrupting connection for reason: ' + reason);\n this.interruptReasons_[reason] = true;\n if (this.realtime_) {\n this.realtime_.close();\n } else {\n if (this.establishConnectionTimer_) {\n clearTimeout(this.establishConnectionTimer_);\n this.establishConnectionTimer_ = null;\n }\n if (this.connected_) {\n this.onRealtimeDisconnect_();\n }\n }\n }\n\n /**\n * @param {string} reason\n */\n resume(reason: string) {\n log('Resuming connection for reason: ' + reason);\n delete this.interruptReasons_[reason];\n if (isEmpty(this.interruptReasons_)) {\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\n if (!this.realtime_) {\n this.scheduleConnect_(0);\n }\n }\n }\n\n private handleTimestamp_(timestamp: number) {\n const delta = timestamp - new Date().getTime();\n this.onServerInfoUpdate_({'serverTimeOffset': delta});\n }\n\n private cancelSentTransactions_() {\n for (let i = 0; i < this.outstandingPuts_.length; i++) {\n const put = this.outstandingPuts_[i];\n if (put && /*hash*/'h' in put.request && put.queued) {\n if (put.onComplete)\n put.onComplete('disconnect');\n\n delete this.outstandingPuts_[i];\n this.outstandingPutCount_--;\n }\n }\n\n // Clean up array occasionally.\n if (this.outstandingPutCount_ === 0)\n this.outstandingPuts_ = [];\n }\n\n /**\n * @param {!string} pathString\n * @param {Array.<*>=} query\n * @private\n */\n private onListenRevoked_(pathString: string, query?: any[]) {\n // Remove the listen and manufacture a \"permission_denied\" error for the failed listen.\n let queryId;\n if (!query) {\n queryId = 'default';\n } else {\n queryId = query.map(q => ObjectToUniqueKey(q)).join('$');\n }\n const listen = this.removeListen_(pathString, queryId);\n if (listen && listen.onComplete)\n listen.onComplete('permission_denied');\n }\n\n /**\n * @param {!string} pathString\n * @param {!string} queryId\n * @return {{queries:Array., onComplete:function(string)}}\n * @private\n */\n private removeListen_(pathString: string, queryId: string): ListenSpec {\n const normalizedPathString = new Path(pathString).toString(); // normalize path.\n let listen;\n if (this.listens_[normalizedPathString] !== undefined) {\n listen = this.listens_[normalizedPathString][queryId];\n delete this.listens_[normalizedPathString][queryId];\n if (getCount(this.listens_[normalizedPathString]) === 0) {\n delete this.listens_[normalizedPathString];\n }\n } else {\n // all listens for this path has already been removed\n listen = undefined;\n }\n return listen;\n }\n\n private onAuthRevoked_(statusCode: string, explanation: string) {\n log('Auth token revoked: ' + statusCode + '/' + explanation);\n this.authToken_ = null;\n this.forceTokenRefresh_ = true;\n this.realtime_.close();\n if (statusCode === 'invalid_token' || statusCode === 'permission_denied') {\n // We'll wait a couple times before logging the warning / increasing the\n // retry period since oauth tokens will report as \"invalid\" if they're\n // just expired. Plus there may be transient issues that resolve themselves.\n this.invalidAuthTokenCount_++;\n if (this.invalidAuthTokenCount_ >= INVALID_AUTH_TOKEN_THRESHOLD) {\n // Set a long reconnect delay because recovery is unlikely\n this.reconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\n\n // Notify the auth token provider that the token is invalid, which will log\n // a warning\n this.authTokenProvider_.notifyForInvalidToken();\n }\n }\n }\n\n private onSecurityDebugPacket_(body: { [k: string]: any }) {\n if (this.securityDebugCallback_) {\n this.securityDebugCallback_(body);\n } else {\n if ('msg' in body && typeof console !== 'undefined') {\n console.log('FIREBASE: ' + body['msg'].replace('\\n', '\\nFIREBASE: '));\n }\n }\n }\n\n private restoreState_() {\n //Re-authenticate ourselves if we have a credential stored.\n this.tryAuth();\n\n // Puts depend on having received the corresponding data update from the server before they complete, so we must\n // make sure to send listens before puts.\n forEach(this.listens_, (pathString: string, queries: Object) => {\n forEach(queries, (key: string, listenSpec: ListenSpec) => {\n this.sendListen_(listenSpec);\n });\n });\n\n for (let i = 0; i < this.outstandingPuts_.length; i++) {\n if (this.outstandingPuts_[i])\n this.sendPut_(i);\n }\n\n while (this.onDisconnectRequestQueue_.length) {\n const request = this.onDisconnectRequestQueue_.shift();\n this.sendOnDisconnect_(request.action, request.pathString, request.data, request.onComplete);\n }\n }\n\n /**\n * Sends client stats for first connection\n * @private\n */\n private sendConnectStats_() {\n const stats: { [k: string]: number } = {};\n\n let clientName = 'js';\n if (CONSTANTS.NODE_ADMIN) {\n clientName = 'admin_node';\n } else if (CONSTANTS.NODE_CLIENT) {\n clientName = 'node';\n }\n\n stats['sdk.' + clientName + '.' + firebase.SDK_VERSION.replace(/\\./g, '-')] = 1;\n\n if (isMobileCordova()) {\n stats['framework.cordova'] = 1;\n }\n else if (isReactNative()) {\n stats['framework.reactnative'] = 1;\n }\n this.reportStats(stats);\n }\n\n /**\n * @return {boolean}\n * @private\n */\n private shouldReconnect_(): boolean {\n const online = OnlineMonitor.getInstance().currentlyOnline();\n return isEmpty(this.interruptReasons_) && online;\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/PersistentConnection.ts","/**\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\nimport { forEach } from \"./obj\";\n\n/**\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a params\n * object (e.g. {arg: 'val', arg2: 'val2'})\n * Note: You must prepend it with ? when adding it to a URL.\n *\n * @param {!Object} querystringParams\n * @return {string}\n */\nexport const querystring = function(querystringParams) {\n var params = [];\n forEach(querystringParams, function(key, value) {\n if (Array.isArray(value)) {\n value.forEach(function(arrayVal) {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal));\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return (params.length) ? '&' + params.join('&') : '';\n};\n\n\n/**\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object (e.g. {arg: 'val', arg2: 'val2'})\n *\n * @param {string} querystring\n * @return {!Object}\n */\nexport const querystringDecode = function(querystring) {\n var obj = {};\n var tokens = querystring.replace(/^\\?/, '').split('&');\n\n tokens.forEach(function(token) {\n if (token) {\n var key = token.split('=');\n obj[key[0]] = key[1];\n }\n });\n return obj;\n};\n\n\n// WEBPACK FOOTER //\n// ./src/utils/util.ts","/**\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\nimport { assert } from '../../utils/assert';\nimport { logWrapper, warn } from './util/util';\nimport { jsonEval } from '../../utils/json';\nimport { safeGet } from '../../utils/obj';\nimport { querystring } from '../../utils/util';\nimport { ServerActions } from './ServerActions';\nimport { RepoInfo } from './RepoInfo';\nimport { AuthTokenProvider } from './AuthTokenProvider';\nimport { Query } from '../api/Query';\n\n/**\n * An implementation of ServerActions that communicates with the server via REST requests.\n * This is mostly useful for compatibility with crawlers, where we don't want to spin up a full\n * persistent connection (using WebSockets or long-polling)\n */\nexport class ReadonlyRestClient extends ServerActions {\n reportStats(stats: {\n [k: string]: any;\n }): void {\n throw new Error('Method not implemented.');\n }\n\n /** @private {function(...[*])} */\n private log_: (...args: any[]) => void = logWrapper('p:rest:');\n\n /**\n * We don't actually need to track listens, except to prevent us calling an onComplete for a listen\n * that's been removed. :-/\n *\n * @private {!Object.}\n */\n private listens_: { [k: string]: Object } = {};\n\n /**\n * @param {!Query} query\n * @param {?number=} tag\n * @return {string}\n * @private\n */\n static getListenId_(query: Query, tag?: number | null): string {\n if (tag !== undefined) {\n return 'tag$' + tag;\n } else {\n assert(query.getQueryParams().isDefault(), 'should have a tag if it\\'s not a default query.');\n return query.path.toString();\n }\n }\n\n /**\n * @param {!RepoInfo} repoInfo_ Data about the namespace we are connecting to\n * @param {function(string, *, boolean, ?number)} onDataUpdate_ A callback for new data from the server\n * @param {AuthTokenProvider} authTokenProvider_\n * @implements {ServerActions}\n */\n constructor(private repoInfo_: RepoInfo,\n private onDataUpdate_: (a: string, b: any, c: boolean, d: number | null) => void,\n private authTokenProvider_: AuthTokenProvider) {\n super();\n }\n\n /** @inheritDoc */\n listen(query: Query, currentHashFn: () => string, tag: number | null, onComplete: (a: string, b: any) => void) {\n const pathString = query.path.toString();\n this.log_('Listen called for ' + pathString + ' ' + query.queryIdentifier());\n\n // Mark this listener so we can tell if it's removed.\n const listenId = ReadonlyRestClient.getListenId_(query, tag);\n const thisListen = {};\n this.listens_[listenId] = thisListen;\n\n const queryStringParamaters = query.getQueryParams().toRestQueryStringParameters();\n\n this.restRequest_(pathString + '.json', queryStringParamaters, (error, result) => {\n let data = result;\n\n if (error === 404) {\n data = null;\n error = null;\n }\n\n if (error === null) {\n this.onDataUpdate_(pathString, data, /*isMerge=*/false, tag);\n }\n\n if (safeGet(this.listens_, listenId) === thisListen) {\n let status;\n if (!error) {\n status = 'ok';\n } else if (error == 401) {\n status = 'permission_denied';\n } else {\n status = 'rest_error:' + error;\n }\n\n onComplete(status, null);\n }\n });\n }\n\n /** @inheritDoc */\n unlisten(query: Query, tag: number | null) {\n const listenId = ReadonlyRestClient.getListenId_(query, tag);\n delete this.listens_[listenId];\n }\n\n /** @inheritDoc */\n refreshAuthToken(token: string) {\n // no-op since we just always call getToken.\n }\n\n /**\n * Performs a REST request to the given path, with the provided query string parameters,\n * and any auth credentials we have.\n *\n * @param {!string} pathString\n * @param {!Object.} queryStringParameters\n * @param {?function(?number, *=)} callback\n * @private\n */\n private restRequest_(pathString: string, queryStringParameters: { [k: string]: any } = {},\n callback: ((a: number | null, b?: any) => void) | null) {\n queryStringParameters['format'] = 'export';\n\n this.authTokenProvider_.getToken(/*forceRefresh=*/false).then((authTokenData) => {\n const authToken = authTokenData && authTokenData.accessToken;\n if (authToken) {\n queryStringParameters['auth'] = authToken;\n }\n\n const url = (this.repoInfo_.secure ? 'https://' : 'http://') +\n this.repoInfo_.host +\n pathString +\n '?' +\n querystring(queryStringParameters);\n\n this.log_('Sending REST request for ' + url);\n const xhr = new XMLHttpRequest();\n xhr.onreadystatechange = () => {\n if (callback && xhr.readyState === 4) {\n this.log_('REST Response for ' + url + ' received. status:', xhr.status, 'response:', xhr.responseText);\n let res = null;\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n res = jsonEval(xhr.responseText);\n } catch (e) {\n warn('Failed to parse JSON response for ' + url + ': ' + xhr.responseText);\n }\n callback(null, res);\n } else {\n // 401 and 404 are expected.\n if (xhr.status !== 401 && xhr.status !== 404) {\n warn('Got unsuccessful REST response for ' + url + ' Status: ' + xhr.status);\n }\n callback(xhr.status);\n }\n callback = null;\n }\n };\n\n xhr.open('GET', url, /*asynchronous=*/true);\n xhr.send();\n });\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/ReadonlyRestClient.ts","/**\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\nimport {\n generateWithValues,\n resolveDeferredValueSnapshot,\n resolveDeferredValueTree\n} from './util/ServerValues';\nimport { nodeFromJSON } from './snap/nodeFromJSON';\nimport { Path } from './util/Path';\nimport { SparseSnapshotTree } from './SparseSnapshotTree';\nimport { SyncTree } from './SyncTree';\nimport { SnapshotHolder } from './SnapshotHolder';\nimport { stringify } from '../../utils/json';\nimport { beingCrawled, each, exceptionGuard, warn, log } from './util/util';\nimport { map, forEach, isEmpty } from '../../utils/obj';\nimport { AuthTokenProvider } from './AuthTokenProvider';\nimport { StatsManager } from './stats/StatsManager';\nimport { StatsReporter } from './stats/StatsReporter';\nimport { StatsListener } from './stats/StatsListener';\nimport { EventQueue } from './view/EventQueue';\nimport { PersistentConnection } from './PersistentConnection';\nimport { ReadonlyRestClient } from './ReadonlyRestClient';\nimport { FirebaseApp } from '../../app/firebase_app';\nimport { RepoInfo } from './RepoInfo';\nimport { Database } from '../api/Database';\nimport { ServerActions } from './ServerActions';\nimport { Query } from '../api/Query';\nimport { EventRegistration } from './view/EventRegistration';\nimport { StatsCollection } from './stats/StatsCollection';\nimport { Event } from './view/Event';\nimport { Node } from './snap/Node';\n\nconst INTERRUPT_REASON = 'repo_interrupt';\n\n/**\n * A connection to a single data repository.\n */\nexport class Repo {\n dataUpdateCount = 0;\n private infoSyncTree_: SyncTree;\n private serverSyncTree_: SyncTree;\n\n private stats_: StatsCollection;\n private statsListener_: StatsListener | null = null;\n private eventQueue_ = new EventQueue();\n private nextWriteId_ = 1;\n private server_: ServerActions;\n private statsReporter_: StatsReporter;\n private transactions_init_: () => void;\n private infoData_: SnapshotHolder;\n private abortTransactions_: (path: Path) => Path;\n private rerunTransactions_: (changedPath: Path) => Path;\n private interceptServerDataCallback_: ((a: string, b: any) => void) | null = null;\n private __database: Database;\n\n // A list of data pieces and paths to be set when this client disconnects.\n private onDisconnect_ = new SparseSnapshotTree();\n\n /**\n * TODO: This should be @private but it's used by test_access.js and internal.js\n * @type {?PersistentConnection}\n */\n persistentConnection_: PersistentConnection | null = null;\n\n /**\n * @param {!RepoInfo} repoInfo_\n * @param {boolean} forceRestClient\n * @param {!FirebaseApp} app\n */\n constructor(private repoInfo_: RepoInfo, forceRestClient: boolean, public app: FirebaseApp) {\n /** @type {!AuthTokenProvider} */\n const authTokenProvider = new AuthTokenProvider(app);\n\n this.stats_ = StatsManager.getCollection(repoInfo_);\n\n if (forceRestClient || beingCrawled()) {\n this.server_ = new ReadonlyRestClient(this.repoInfo_,\n this.onDataUpdate_.bind(this),\n authTokenProvider);\n\n // Minor hack: Fire onConnect immediately, since there's no actual connection.\n setTimeout(this.onConnectStatus_.bind(this, true), 0);\n } else {\n const authOverride = app.options['databaseAuthVariableOverride'];\n // Validate authOverride\n if (typeof authOverride !== 'undefined' && authOverride !== null) {\n if (typeof authOverride !== 'object') {\n throw new Error('Only objects are supported for option databaseAuthVariableOverride');\n }\n try {\n stringify(authOverride);\n } catch (e) {\n throw new Error('Invalid authOverride provided: ' + e);\n }\n }\n\n this.persistentConnection_ = new PersistentConnection(this.repoInfo_,\n this.onDataUpdate_.bind(this),\n this.onConnectStatus_.bind(this),\n this.onServerInfoUpdate_.bind(this),\n authTokenProvider,\n authOverride);\n\n this.server_ = this.persistentConnection_;\n }\n\n authTokenProvider.addTokenChangeListener((token) => {\n this.server_.refreshAuthToken(token);\n });\n\n // In the case of multiple Repos for the same repoInfo (i.e. there are multiple Firebase.Contexts being used),\n // we only want to create one StatsReporter. As such, we'll report stats over the first Repo created.\n this.statsReporter_ = StatsManager.getOrCreateReporter(repoInfo_,\n () => new StatsReporter(this.stats_, this.server_));\n\n this.transactions_init_();\n\n // Used for .info.\n this.infoData_ = new SnapshotHolder();\n this.infoSyncTree_ = new SyncTree({\n startListening: (query, tag, currentHashFn, onComplete) => {\n let infoEvents: Event[] = [];\n const node = this.infoData_.getNode(query.path);\n // This is possibly a hack, but we have different semantics for .info endpoints. We don't raise null events\n // on initial data...\n if (!node.isEmpty()) {\n infoEvents = this.infoSyncTree_.applyServerOverwrite(query.path, node);\n setTimeout(() => {\n onComplete('ok');\n }, 0);\n }\n return infoEvents;\n },\n stopListening: () => {}\n });\n this.updateInfo_('connected', false);\n\n this.serverSyncTree_ = new SyncTree({\n startListening: (query, tag, currentHashFn, onComplete) => {\n this.server_.listen(query, currentHashFn, tag, (status, data) => {\n const events = onComplete(status, data);\n this.eventQueue_.raiseEventsForChangedPath(query.path, events);\n });\n // No synchronous events for network-backed sync trees\n return [];\n },\n stopListening: (query, tag) => {\n this.server_.unlisten(query, tag);\n }\n });\n }\n\n /**\n * @return {string} The URL corresponding to the root of this Firebase.\n */\n toString(): string {\n return (this.repoInfo_.secure ? 'https://' : 'http://') + this.repoInfo_.host;\n }\n\n /**\n * @return {!string} The namespace represented by the repo.\n */\n name(): string {\n return this.repoInfo_.namespace;\n }\n\n /**\n * @return {!number} The time in milliseconds, taking the server offset into account if we have one.\n */\n serverTime(): number {\n const offsetNode = this.infoData_.getNode(new Path('.info/serverTimeOffset'));\n const offset = (offsetNode.val() as number) || 0;\n return new Date().getTime() + offset;\n }\n\n /**\n * Generate ServerValues using some variables from the repo object.\n * @return {!Object}\n */\n generateServerValues(): Object {\n return generateWithValues({\n 'timestamp': this.serverTime()\n });\n }\n\n /**\n * Called by realtime when we get new messages from the server.\n *\n * @private\n * @param {string} pathString\n * @param {*} data\n * @param {boolean} isMerge\n * @param {?number} tag\n */\n private onDataUpdate_(pathString: string, data: any, isMerge: boolean, tag: number | null) {\n // For testing.\n this.dataUpdateCount++;\n const path = new Path(pathString);\n data = this.interceptServerDataCallback_ ? this.interceptServerDataCallback_(pathString, data) : data;\n let events = [];\n if (tag) {\n if (isMerge) {\n const taggedChildren = map(data as { [k: string]: any }, (raw: any) => nodeFromJSON(raw));\n events = this.serverSyncTree_.applyTaggedQueryMerge(path, taggedChildren, tag);\n } else {\n const taggedSnap = nodeFromJSON(data);\n events = this.serverSyncTree_.applyTaggedQueryOverwrite(path, taggedSnap, tag);\n }\n } else if (isMerge) {\n const changedChildren = map(data as { [k: string]: any }, (raw: any) => nodeFromJSON(raw));\n events = this.serverSyncTree_.applyServerMerge(path, changedChildren);\n } else {\n const snap = nodeFromJSON(data);\n events = this.serverSyncTree_.applyServerOverwrite(path, snap);\n }\n let affectedPath = path;\n if (events.length > 0) {\n // Since we have a listener outstanding for each transaction, receiving any events\n // is a proxy for some change having occurred.\n affectedPath = this.rerunTransactions_(path);\n }\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, events);\n }\n\n /**\n * TODO: This should be @private but it's used by test_access.js and internal.js\n * @param {?function(!string, *):*} callback\n * @private\n */\n interceptServerData_(callback: ((a: string, b: any) => any) | null) {\n this.interceptServerDataCallback_ = callback;\n }\n\n /**\n * @param {!boolean} connectStatus\n * @private\n */\n private onConnectStatus_(connectStatus: boolean) {\n this.updateInfo_('connected', connectStatus);\n if (connectStatus === false) {\n this.runOnDisconnectEvents_();\n }\n }\n\n /**\n * @param {!Object} updates\n * @private\n */\n private onServerInfoUpdate_(updates: Object) {\n each(updates, (value: any, key: string) => {\n this.updateInfo_(key, value);\n });\n }\n\n /**\n *\n * @param {!string} pathString\n * @param {*} value\n * @private\n */\n private updateInfo_(pathString: string, value: any) {\n const path = new Path('/.info/' + pathString);\n const newNode = nodeFromJSON(value);\n this.infoData_.updateSnapshot(path, newNode);\n const events = this.infoSyncTree_.applyServerOverwrite(path, newNode);\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n }\n\n /**\n * @return {!number}\n * @private\n */\n private getNextWriteId_(): number {\n return this.nextWriteId_++;\n }\n\n /**\n * @param {!Path} path\n * @param {*} newVal\n * @param {number|string|null} newPriority\n * @param {?function(?Error, *=)} onComplete\n */\n setWithPriority(path: Path, newVal: any,\n newPriority: number | string | null,\n onComplete: ((status: Error | null, errorReason?: string) => void) | null) {\n this.log_('set', {path: path.toString(), value: newVal, priority: newPriority});\n\n // TODO: Optimize this behavior to either (a) store flag to skip resolving where possible and / or\n // (b) store unresolved paths on JSON parse\n const serverValues = this.generateServerValues();\n const newNodeUnresolved = nodeFromJSON(newVal, newPriority);\n const newNode = resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\n\n const writeId = this.getNextWriteId_();\n const events = this.serverSyncTree_.applyUserOverwrite(path, newNode, writeId, true);\n this.eventQueue_.queueEvents(events);\n this.server_.put(path.toString(), newNodeUnresolved.val(/*export=*/true), (status, errorReason) => {\n const success = status === 'ok';\n if (!success) {\n warn('set at ' + path + ' failed: ' + status);\n }\n\n const clearEvents = this.serverSyncTree_.ackUserWrite(writeId, !success);\n this.eventQueue_.raiseEventsForChangedPath(path, clearEvents);\n this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n const affectedPath = this.abortTransactions_(path);\n this.rerunTransactions_(affectedPath);\n // We queued the events above, so just flush the queue here\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, []);\n }\n\n /**\n * @param {!Path} path\n * @param {!Object} childrenToMerge\n * @param {?function(?Error, *=)} onComplete\n */\n update(path: Path, childrenToMerge: { [k: string]: any },\n onComplete: ((status: Error | null, errorReason?: string) => void) | null) {\n this.log_('update', {path: path.toString(), value: childrenToMerge});\n\n // Start with our existing data and merge each child into it.\n let empty = true;\n const serverValues = this.generateServerValues();\n const changedChildren: { [k: string]: Node } = {};\n forEach(childrenToMerge, (changedKey: string, changedValue: any) => {\n empty = false;\n const newNodeUnresolved = nodeFromJSON(changedValue);\n changedChildren[changedKey] = resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\n });\n\n if (!empty) {\n const writeId = this.getNextWriteId_();\n const events = this.serverSyncTree_.applyUserMerge(path, changedChildren, writeId);\n this.eventQueue_.queueEvents(events);\n this.server_.merge(path.toString(), childrenToMerge, (status, errorReason) => {\n const success = status === 'ok';\n if (!success) {\n warn('update at ' + path + ' failed: ' + status);\n }\n\n const clearEvents = this.serverSyncTree_.ackUserWrite(writeId, !success);\n const affectedPath = (clearEvents.length > 0) ? this.rerunTransactions_(path) : path;\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, clearEvents);\n this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n\n forEach(childrenToMerge, (changedPath: string) => {\n const affectedPath = this.abortTransactions_(path.child(changedPath));\n this.rerunTransactions_(affectedPath);\n });\n\n // We queued the events above, so just flush the queue here\n this.eventQueue_.raiseEventsForChangedPath(path, []);\n } else {\n log('update() called with empty data. Don\\'t do anything.');\n this.callOnCompleteCallback(onComplete, 'ok');\n }\n }\n\n /**\n * Applies all of the changes stored up in the onDisconnect_ tree.\n * @private\n */\n private runOnDisconnectEvents_() {\n this.log_('onDisconnectEvents');\n\n const serverValues = this.generateServerValues();\n const resolvedOnDisconnectTree = resolveDeferredValueTree(this.onDisconnect_, serverValues);\n let events: Event[] = [];\n\n resolvedOnDisconnectTree.forEachTree(Path.Empty, (path, snap) => {\n events = events.concat(this.serverSyncTree_.applyServerOverwrite(path, snap));\n const affectedPath = this.abortTransactions_(path);\n this.rerunTransactions_(affectedPath);\n });\n\n this.onDisconnect_ = new SparseSnapshotTree();\n this.eventQueue_.raiseEventsForChangedPath(Path.Empty, events);\n }\n\n /**\n * @param {!Path} path\n * @param {?function(?Error, *=)} onComplete\n */\n onDisconnectCancel(path: Path, onComplete: ((status: Error | null, errorReason?: string) => void) | null) {\n this.server_.onDisconnectCancel(path.toString(), (status, errorReason) => {\n if (status === 'ok') {\n this.onDisconnect_.forget(path);\n }\n this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n }\n\n /**\n * @param {!Path} path\n * @param {*} value\n * @param {?function(?Error, *=)} onComplete\n */\n onDisconnectSet(path: Path, value: any, onComplete: ((status: Error | null, errorReason?: string) => void) | null) {\n const newNode = nodeFromJSON(value);\n this.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/true), (status, errorReason) => {\n if (status === 'ok') {\n this.onDisconnect_.remember(path, newNode);\n }\n this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n }\n\n /**\n * @param {!Path} path\n * @param {*} value\n * @param {*} priority\n * @param {?function(?Error, *=)} onComplete\n */\n onDisconnectSetWithPriority(path: Path, value: any, priority: any, onComplete: ((status: Error | null, errorReason?: string) => void) | null) {\n const newNode = nodeFromJSON(value, priority);\n this.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/true), (status, errorReason) => {\n if (status === 'ok') {\n this.onDisconnect_.remember(path, newNode);\n }\n this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n }\n\n /**\n * @param {!Path} path\n * @param {*} childrenToMerge\n * @param {?function(?Error, *=)} onComplete\n */\n onDisconnectUpdate(path: Path, childrenToMerge: { [k: string]: any },\n onComplete: ((status: Error | null, errorReason?: string) => void) | null) {\n if (isEmpty(childrenToMerge)) {\n log('onDisconnect().update() called with empty data. Don\\'t do anything.');\n this.callOnCompleteCallback(onComplete, 'ok');\n return;\n }\n\n this.server_.onDisconnectMerge(path.toString(), childrenToMerge, (status, errorReason) => {\n if (status === 'ok') {\n forEach(childrenToMerge, (childName: string, childNode: any) => {\n const newChildNode = nodeFromJSON(childNode);\n this.onDisconnect_.remember(path.child(childName), newChildNode);\n });\n }\n this.callOnCompleteCallback(onComplete, status, errorReason);\n });\n }\n\n /**\n * @param {!Query} query\n * @param {!EventRegistration} eventRegistration\n */\n addEventCallbackForQuery(query: Query, eventRegistration: EventRegistration) {\n let events;\n if (query.path.getFront() === '.info') {\n events = this.infoSyncTree_.addEventRegistration(query, eventRegistration);\n } else {\n events = this.serverSyncTree_.addEventRegistration(query, eventRegistration);\n }\n this.eventQueue_.raiseEventsAtPath(query.path, events);\n }\n\n /**\n * @param {!Query} query\n * @param {?EventRegistration} eventRegistration\n */\n removeEventCallbackForQuery(query: Query, eventRegistration: EventRegistration) {\n // These are guaranteed not to raise events, since we're not passing in a cancelError. However, we can future-proof\n // a little bit by handling the return values anyways.\n let events;\n if (query.path.getFront() === '.info') {\n events = this.infoSyncTree_.removeEventRegistration(query, eventRegistration);\n } else {\n events = this.serverSyncTree_.removeEventRegistration(query, eventRegistration);\n }\n this.eventQueue_.raiseEventsAtPath(query.path, events);\n }\n\n interrupt() {\n if (this.persistentConnection_) {\n this.persistentConnection_.interrupt(INTERRUPT_REASON);\n }\n }\n\n resume() {\n if (this.persistentConnection_) {\n this.persistentConnection_.resume(INTERRUPT_REASON);\n }\n }\n\n stats(showDelta: boolean = false) {\n if (typeof console === 'undefined')\n return;\n\n let stats: { [k: string]: any };\n if (showDelta) {\n if (!this.statsListener_)\n this.statsListener_ = new StatsListener(this.stats_);\n stats = this.statsListener_.get();\n } else {\n stats = this.stats_.get();\n }\n\n const longestName = Object.keys(stats).reduce(\n (previousValue, currentValue) => Math.max(currentValue.length, previousValue), 0);\n\n forEach(stats, (stat: string, value: any) => {\n // pad stat names to be the same length (plus 2 extra spaces).\n for (let i = stat.length; i < longestName + 2; i++)\n stat += ' ';\n console.log(stat + value);\n });\n }\n\n statsIncrementCounter(metric: string) {\n this.stats_.incrementCounter(metric);\n this.statsReporter_.includeStat(metric);\n }\n\n /**\n * @param {...*} var_args\n * @private\n */\n private log_(...var_args: any[]) {\n let prefix = '';\n if (this.persistentConnection_) {\n prefix = this.persistentConnection_.id + ':';\n }\n log(prefix, ...var_args);\n }\n\n /**\n * @param {?function(?Error, *=)} callback\n * @param {!string} status\n * @param {?string=} errorReason\n */\n callOnCompleteCallback(callback: ((status: Error | null, errorReason?: string) => void) | null,\n status: string, errorReason?: string | null) {\n if (callback) {\n exceptionGuard(function () {\n if (status == 'ok') {\n callback(null);\n } else {\n const code = (status || 'error').toUpperCase();\n let message = code;\n if (errorReason)\n message += ': ' + errorReason;\n\n const error = new Error(message);\n (error as any).code = code;\n callback(error);\n }\n });\n }\n }\n\n get database(): Database {\n return this.__database || (this.__database = new Database(this));\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/Repo.ts","/**\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\nimport { IndexedFilter } from './IndexedFilter';\nimport { PRIORITY_INDEX } from '../../snap/indexes/PriorityIndex';\nimport { NamedNode, Node } from '../../../core/snap/Node';\nimport { ChildrenNode } from '../../snap/ChildrenNode';\nimport { NodeFilter } from './NodeFilter';\nimport { QueryParams } from '../QueryParams';\nimport { Index } from '../../snap/indexes/Index';\nimport { Path } from '../../util/Path';\nimport { CompleteChildSource } from '../CompleteChildSource';\nimport { ChildChangeAccumulator } from '../ChildChangeAccumulator';\n\n/**\n * Filters nodes by range and uses an IndexFilter to track any changes after filtering the node\n *\n * @constructor\n * @implements {NodeFilter}\n */\nexport class RangedFilter implements NodeFilter {\n /**\n * @type {!IndexedFilter}\n * @const\n * @private\n */\n private indexedFilter_: IndexedFilter;\n\n /**\n * @const\n * @type {!Index}\n * @private\n */\n private index_: Index;\n\n /**\n * @const\n * @type {!NamedNode}\n * @private\n */\n private startPost_: NamedNode;\n\n /**\n * @const\n * @type {!NamedNode}\n * @private\n */\n private endPost_: NamedNode;\n\n /**\n * @param {!QueryParams} params\n */\n constructor(params: QueryParams) {\n this.indexedFilter_ = new IndexedFilter(params.getIndex());\n this.index_ = params.getIndex();\n this.startPost_ = RangedFilter.getStartPost_(params);\n this.endPost_ = RangedFilter.getEndPost_(params);\n }\n\n /**\n * @return {!NamedNode}\n */\n getStartPost(): NamedNode {\n return this.startPost_;\n }\n\n /**\n * @return {!NamedNode}\n */\n getEndPost(): NamedNode {\n return this.endPost_;\n }\n\n /**\n * @param {!NamedNode} node\n * @return {boolean}\n */\n matches(node: NamedNode): boolean {\n return (this.index_.compare(this.getStartPost(), node) <= 0 && this.index_.compare(node, this.getEndPost()) <= 0);\n }\n\n /**\n * @inheritDoc\n */\n updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path,\n source: CompleteChildSource,\n optChangeAccumulator: ChildChangeAccumulator | null): Node {\n if (!this.matches(new NamedNode(key, newChild))) {\n newChild = ChildrenNode.EMPTY_NODE;\n }\n return this.indexedFilter_.updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator);\n }\n\n /**\n * @inheritDoc\n */\n updateFullNode(oldSnap: Node, newSnap: Node,\n optChangeAccumulator: ChildChangeAccumulator | null): Node {\n if (newSnap.isLeafNode()) {\n // Make sure we have a children node with the correct index, not a leaf node;\n newSnap = ChildrenNode.EMPTY_NODE;\n }\n let filtered = newSnap.withIndex(this.index_);\n // Don't support priorities on queries\n filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);\n const self = this;\n newSnap.forEachChild(PRIORITY_INDEX, function (key, childNode) {\n if (!self.matches(new NamedNode(key, childNode))) {\n filtered = filtered.updateImmediateChild(key, ChildrenNode.EMPTY_NODE);\n }\n });\n return this.indexedFilter_.updateFullNode(oldSnap, filtered, optChangeAccumulator);\n }\n\n /**\n * @inheritDoc\n */\n updatePriority(oldSnap: Node, newPriority: Node): Node {\n // Don't support priorities on queries\n return oldSnap;\n }\n\n /**\n * @inheritDoc\n */\n filtersNodes(): boolean {\n return true;\n }\n\n /**\n * @inheritDoc\n */\n getIndexedFilter(): IndexedFilter {\n return this.indexedFilter_;\n }\n\n /**\n * @inheritDoc\n */\n getIndex(): Index {\n return this.index_;\n }\n\n /**\n * @param {!QueryParams} params\n * @return {!NamedNode}\n * @private\n */\n private static getStartPost_(params: QueryParams): NamedNode {\n if (params.hasStart()) {\n const startName = params.getIndexStartName();\n return params.getIndex().makePost(params.getIndexStartValue(), startName);\n } else {\n return params.getIndex().minPost();\n }\n }\n\n /**\n * @param {!QueryParams} params\n * @return {!NamedNode}\n * @private\n */\n private static getEndPost_(params: QueryParams): NamedNode {\n if (params.hasEnd()) {\n const endName = params.getIndexEndName();\n return params.getIndex().makePost(params.getIndexEndValue(), endName);\n } else {\n return params.getIndex().maxPost();\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/filter/RangedFilter.ts","/**\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\nimport { RangedFilter } from './RangedFilter';\nimport { ChildrenNode } from '../../snap/ChildrenNode';\nimport { Node, NamedNode } from '../../snap/Node';\nimport { assert } from '../../../../utils/assert';\nimport { Change } from '../Change';\nimport { NodeFilter } from './NodeFilter';\nimport { Index } from '../../snap/indexes/Index';\nimport { IndexedFilter } from './IndexedFilter';\nimport { QueryParams } from '../QueryParams';\nimport { Path } from '../../util/Path';\nimport { CompleteChildSource } from '../CompleteChildSource';\nimport { ChildChangeAccumulator } from '../ChildChangeAccumulator';\n\n/**\n * Applies a limit and a range to a node and uses RangedFilter to do the heavy lifting where possible\n *\n * @constructor\n * @implements {NodeFilter}\n */\nexport class LimitedFilter implements NodeFilter {\n /**\n * @const\n * @type {RangedFilter}\n * @private\n */\n private readonly rangedFilter_: RangedFilter;\n\n /**\n * @const\n * @type {!Index}\n * @private\n */\n private readonly index_: Index;\n\n /**\n * @const\n * @type {number}\n * @private\n */\n private readonly limit_: number;\n\n /**\n * @const\n * @type {boolean}\n * @private\n */\n private readonly reverse_: boolean;\n\n /**\n * @param {!QueryParams} params\n */\n constructor(params: QueryParams) {\n this.rangedFilter_ = new RangedFilter(params);\n this.index_ = params.getIndex();\n this.limit_ = params.getLimit();\n this.reverse_ = !params.isViewFromLeft();\n }\n\n /**\n * @inheritDoc\n */\n updateChild(snap: Node, key: string, newChild: Node, affectedPath: Path,\n source: CompleteChildSource,\n optChangeAccumulator: ChildChangeAccumulator | null): Node {\n if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {\n newChild = ChildrenNode.EMPTY_NODE;\n }\n if (snap.getImmediateChild(key).equals(newChild)) {\n // No change\n return snap;\n } else if (snap.numChildren() < this.limit_) {\n return this.rangedFilter_.getIndexedFilter().updateChild(snap, key, newChild, affectedPath, source,\n optChangeAccumulator);\n } else {\n return this.fullLimitUpdateChild_(snap, key, newChild, source, optChangeAccumulator);\n }\n }\n\n /**\n * @inheritDoc\n */\n updateFullNode(oldSnap: Node, newSnap: Node,\n optChangeAccumulator: ChildChangeAccumulator | null): Node {\n let filtered;\n if (newSnap.isLeafNode() || newSnap.isEmpty()) {\n // Make sure we have a children node with the correct index, not a leaf node;\n filtered = ChildrenNode.EMPTY_NODE.withIndex(this.index_);\n } else {\n if (this.limit_ * 2 < newSnap.numChildren() && newSnap.isIndexed(this.index_)) {\n // Easier to build up a snapshot, since what we're given has more than twice the elements we want\n filtered = ChildrenNode.EMPTY_NODE.withIndex(this.index_);\n // anchor to the startPost, endPost, or last element as appropriate\n let iterator;\n if (this.reverse_) {\n iterator = (newSnap as ChildrenNode).getReverseIteratorFrom(this.rangedFilter_.getEndPost(), this.index_);\n } else {\n iterator = (newSnap as ChildrenNode).getIteratorFrom(this.rangedFilter_.getStartPost(), this.index_);\n }\n let count = 0;\n while (iterator.hasNext() && count < this.limit_) {\n const next = iterator.getNext();\n let inRange;\n if (this.reverse_) {\n inRange = this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;\n } else {\n inRange = this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;\n }\n if (inRange) {\n filtered = filtered.updateImmediateChild(next.name, next.node);\n count++;\n } else {\n // if we have reached the end post, we cannot keep adding elemments\n break;\n }\n }\n } else {\n // The snap contains less than twice the limit. Faster to delete from the snap than build up a new one\n filtered = newSnap.withIndex(this.index_);\n // Don't support priorities on queries\n filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE) as ChildrenNode;\n let startPost;\n let endPost;\n let cmp;\n let iterator;\n if (this.reverse_) {\n iterator = filtered.getReverseIterator(this.index_);\n startPost = this.rangedFilter_.getEndPost();\n endPost = this.rangedFilter_.getStartPost();\n const indexCompare = this.index_.getCompare();\n cmp = (a: NamedNode, b: NamedNode) => indexCompare(b, a);\n } else {\n iterator = filtered.getIterator(this.index_);\n startPost = this.rangedFilter_.getStartPost();\n endPost = this.rangedFilter_.getEndPost();\n cmp = this.index_.getCompare();\n }\n\n let count = 0;\n let foundStartPost = false;\n while (iterator.hasNext()) {\n let next = iterator.getNext();\n if (!foundStartPost && cmp(startPost, next) <= 0) {\n // start adding\n foundStartPost = true;\n }\n let inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;\n if (inRange) {\n count++;\n } else {\n filtered = filtered.updateImmediateChild(next.name, ChildrenNode.EMPTY_NODE);\n }\n }\n }\n }\n return this.rangedFilter_.getIndexedFilter().updateFullNode(oldSnap, filtered, optChangeAccumulator);\n }\n\n /**\n * @inheritDoc\n */\n updatePriority(oldSnap: Node, newPriority: Node): Node {\n // Don't support priorities on queries\n return oldSnap;\n }\n\n /**\n * @inheritDoc\n */\n filtersNodes(): boolean {\n return true;\n }\n\n /**\n * @inheritDoc\n */\n getIndexedFilter(): IndexedFilter {\n return this.rangedFilter_.getIndexedFilter();\n }\n\n /**\n * @inheritDoc\n */\n getIndex(): Index {\n return this.index_;\n }\n\n /**\n * @param {!Node} snap\n * @param {string} childKey\n * @param {!Node} childSnap\n * @param {!CompleteChildSource} source\n * @param {?ChildChangeAccumulator} changeAccumulator\n * @return {!Node}\n * @private\n */\n private fullLimitUpdateChild_(snap: Node, childKey: string, childSnap: Node, source: CompleteChildSource,\n changeAccumulator: ChildChangeAccumulator | null): Node {\n // TODO: rename all cache stuff etc to general snap terminology\n let cmp;\n if (this.reverse_) {\n const indexCmp = this.index_.getCompare();\n cmp = (a: NamedNode, b: NamedNode) => indexCmp(b, a);\n } else {\n cmp = this.index_.getCompare();\n }\n const oldEventCache = snap as ChildrenNode;\n assert(oldEventCache.numChildren() == this.limit_, '');\n const newChildNamedNode = new NamedNode(childKey, childSnap);\n const windowBoundary = this.reverse_ ? oldEventCache.getFirstChild(this.index_) : oldEventCache.getLastChild(this.index_) as NamedNode;\n const inRange = this.rangedFilter_.matches(newChildNamedNode);\n if (oldEventCache.hasChild(childKey)) {\n const oldChildSnap = oldEventCache.getImmediateChild(childKey);\n let nextChild = source.getChildAfterChild(this.index_, windowBoundary, this.reverse_);\n while (nextChild != null && (nextChild.name == childKey || oldEventCache.hasChild(nextChild.name))) {\n // There is a weird edge case where a node is updated as part of a merge in the write tree, but hasn't\n // been applied to the limited filter yet. Ignore this next child which will be updated later in\n // the limited filter...\n nextChild = source.getChildAfterChild(this.index_, nextChild, this.reverse_);\n }\n const compareNext = nextChild == null ? 1 : cmp(nextChild, newChildNamedNode);\n const remainsInWindow = inRange && !childSnap.isEmpty() && compareNext >= 0;\n if (remainsInWindow) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childChangedChange(childKey, childSnap, oldChildSnap));\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap);\n } else {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childRemovedChange(childKey, oldChildSnap));\n }\n const newEventCache = oldEventCache.updateImmediateChild(childKey, ChildrenNode.EMPTY_NODE);\n const nextChildInRange = nextChild != null && this.rangedFilter_.matches(nextChild);\n if (nextChildInRange) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childAddedChange(nextChild.name, nextChild.node));\n }\n return newEventCache.updateImmediateChild(nextChild.name, nextChild.node);\n } else {\n return newEventCache;\n }\n }\n } else if (childSnap.isEmpty()) {\n // we're deleting a node, but it was not in the window, so ignore it\n return snap;\n } else if (inRange) {\n if (cmp(windowBoundary, newChildNamedNode) >= 0) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change.childRemovedChange(windowBoundary.name, windowBoundary.node));\n changeAccumulator.trackChildChange(Change.childAddedChange(childKey, childSnap));\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap).updateImmediateChild(windowBoundary.name,\n ChildrenNode.EMPTY_NODE);\n } else {\n return snap;\n }\n } else {\n return snap;\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/filter/LimitedFilter.ts","/**\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\nimport { assert } from '../../../utils/assert';\nimport {\n MIN_NAME,\n MAX_NAME\n} from '../util/util';\nimport { KEY_INDEX } from '../snap/indexes/KeyIndex';\nimport { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';\nimport { VALUE_INDEX } from '../snap/indexes/ValueIndex';\nimport { PathIndex } from '../snap/indexes/PathIndex';\nimport { IndexedFilter } from './filter/IndexedFilter';\nimport { LimitedFilter } from './filter/LimitedFilter';\nimport { RangedFilter } from './filter/RangedFilter';\nimport { stringify } from '../../../utils/json';\nimport { NodeFilter } from './filter/NodeFilter';\nimport { Index } from '../snap/indexes/Index';\n\n/**\n * This class is an immutable-from-the-public-api struct containing a set of query parameters defining a\n * range to be returned for a particular location. It is assumed that validation of parameters is done at the\n * user-facing API level, so it is not done here.\n * @constructor\n */\nexport class QueryParams {\n private limitSet_ = false;\n private startSet_ = false;\n private startNameSet_ = false;\n private endSet_ = false;\n private endNameSet_ = false;\n\n private limit_ = 0;\n private viewFrom_ = '';\n private indexStartValue_: any | null = null;\n private indexStartName_ = '';\n private indexEndValue_: any | null = null;\n private indexEndName_ = '';\n\n private index_ = PRIORITY_INDEX;\n\n /**\n * Wire Protocol Constants\n * @const\n * @enum {string}\n * @private\n */\n private static readonly WIRE_PROTOCOL_CONSTANTS_ = {\n INDEX_START_VALUE: 'sp',\n INDEX_START_NAME: 'sn',\n INDEX_END_VALUE: 'ep',\n INDEX_END_NAME: 'en',\n LIMIT: 'l',\n VIEW_FROM: 'vf',\n VIEW_FROM_LEFT: 'l',\n VIEW_FROM_RIGHT: 'r',\n INDEX: 'i'\n };\n\n /**\n * REST Query Constants\n * @const\n * @enum {string}\n * @private\n */\n private static readonly REST_QUERY_CONSTANTS_ = {\n ORDER_BY: 'orderBy',\n PRIORITY_INDEX: '$priority',\n VALUE_INDEX: '$value',\n KEY_INDEX: '$key',\n START_AT: 'startAt',\n END_AT: 'endAt',\n LIMIT_TO_FIRST: 'limitToFirst',\n LIMIT_TO_LAST: 'limitToLast'\n };\n\n /**\n * Default, empty query parameters\n * @type {!QueryParams}\n * @const\n */\n static readonly DEFAULT = new QueryParams();\n\n /**\n * @return {boolean}\n */\n hasStart(): boolean {\n return this.startSet_;\n }\n\n /**\n * @return {boolean} True if it would return from left.\n */\n isViewFromLeft(): boolean {\n if (this.viewFrom_ === '') {\n // limit(), rather than limitToFirst or limitToLast was called.\n // This means that only one of startSet_ and endSet_ is true. Use them\n // to calculate which side of the view to anchor to. If neither is set,\n // anchor to the end.\n return this.startSet_;\n } else {\n return this.viewFrom_ === QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;\n }\n }\n\n /**\n * Only valid to call if hasStart() returns true\n * @return {*}\n */\n getIndexStartValue(): any {\n assert(this.startSet_, 'Only valid if start has been set');\n return this.indexStartValue_;\n }\n\n /**\n * Only valid to call if hasStart() returns true.\n * Returns the starting key name for the range defined by these query parameters\n * @return {!string}\n */\n getIndexStartName(): string {\n assert(this.startSet_, 'Only valid if start has been set');\n if (this.startNameSet_) {\n return this.indexStartName_;\n } else {\n return MIN_NAME;\n }\n }\n\n /**\n * @return {boolean}\n */\n hasEnd(): boolean {\n return this.endSet_;\n }\n\n /**\n * Only valid to call if hasEnd() returns true.\n * @return {*}\n */\n getIndexEndValue(): any {\n assert(this.endSet_, 'Only valid if end has been set');\n return this.indexEndValue_;\n }\n\n /**\n * Only valid to call if hasEnd() returns true.\n * Returns the end key name for the range defined by these query parameters\n * @return {!string}\n */\n getIndexEndName(): string {\n assert(this.endSet_, 'Only valid if end has been set');\n if (this.endNameSet_) {\n return this.indexEndName_;\n } else {\n return MAX_NAME;\n }\n }\n\n /**\n * @return {boolean}\n */\n hasLimit(): boolean {\n return this.limitSet_;\n }\n\n /**\n * @return {boolean} True if a limit has been set and it has been explicitly anchored\n */\n hasAnchoredLimit(): boolean {\n return this.limitSet_ && this.viewFrom_ !== '';\n }\n\n /**\n * Only valid to call if hasLimit() returns true\n * @return {!number}\n */\n getLimit(): number {\n assert(this.limitSet_, 'Only valid if limit has been set');\n return this.limit_;\n }\n\n /**\n * @return {!Index}\n */\n getIndex(): Index {\n return this.index_;\n }\n\n /**\n * @return {!QueryParams}\n * @private\n */\n private copy_(): QueryParams {\n const copy = new QueryParams();\n copy.limitSet_ = this.limitSet_;\n copy.limit_ = this.limit_;\n copy.startSet_ = this.startSet_;\n copy.indexStartValue_ = this.indexStartValue_;\n copy.startNameSet_ = this.startNameSet_;\n copy.indexStartName_ = this.indexStartName_;\n copy.endSet_ = this.endSet_;\n copy.indexEndValue_ = this.indexEndValue_;\n copy.endNameSet_ = this.endNameSet_;\n copy.indexEndName_ = this.indexEndName_;\n copy.index_ = this.index_;\n copy.viewFrom_ = this.viewFrom_;\n return copy;\n }\n\n /**\n * @param {!number} newLimit\n * @return {!QueryParams}\n */\n limit(newLimit: number): QueryParams {\n const newParams = this.copy_();\n newParams.limitSet_ = true;\n newParams.limit_ = newLimit;\n newParams.viewFrom_ = '';\n return newParams;\n }\n\n /**\n * @param {!number} newLimit\n * @return {!QueryParams}\n */\n limitToFirst(newLimit: number): QueryParams {\n const newParams = this.copy_();\n newParams.limitSet_ = true;\n newParams.limit_ = newLimit;\n newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;\n return newParams;\n }\n\n /**\n * @param {!number} newLimit\n * @return {!QueryParams}\n */\n limitToLast(newLimit: number): QueryParams {\n const newParams = this.copy_();\n newParams.limitSet_ = true;\n newParams.limit_ = newLimit;\n newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_RIGHT;\n return newParams;\n };\n\n /**\n * @param {*} indexValue\n * @param {?string=} key\n * @return {!QueryParams}\n */\n startAt(indexValue: any, key?: string | null): QueryParams {\n const newParams = this.copy_();\n newParams.startSet_ = true;\n if (!(indexValue !== undefined)) {\n indexValue = null;\n }\n newParams.indexStartValue_ = indexValue;\n if (key != null) {\n newParams.startNameSet_ = true;\n newParams.indexStartName_ = key;\n } else {\n newParams.startNameSet_ = false;\n newParams.indexStartName_ = '';\n }\n return newParams;\n }\n\n /**\n * @param {*} indexValue\n * @param {?string=} key\n * @return {!QueryParams}\n */\n endAt(indexValue: any, key?: string | null): QueryParams {\n const newParams = this.copy_();\n newParams.endSet_ = true;\n if (!(indexValue !== undefined)) {\n indexValue = null;\n }\n newParams.indexEndValue_ = indexValue;\n if (key !== undefined) {\n newParams.endNameSet_ = true;\n newParams.indexEndName_ = key;\n } else {\n newParams.endNameSet_ = false;\n newParams.indexEndName_ = '';\n }\n return newParams;\n };\n\n /**\n * @param {!Index} index\n * @return {!QueryParams}\n */\n orderBy(index: Index): QueryParams {\n const newParams = this.copy_();\n newParams.index_ = index;\n return newParams;\n }\n\n /**\n * @return {!Object}\n */\n getQueryObject(): Object {\n const WIRE_PROTOCOL_CONSTANTS = QueryParams.WIRE_PROTOCOL_CONSTANTS_;\n const obj: { [k: string]: any } = {};\n if (this.startSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE] = this.indexStartValue_;\n if (this.startNameSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME] = this.indexStartName_;\n }\n }\n if (this.endSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE] = this.indexEndValue_;\n if (this.endNameSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME] = this.indexEndName_;\n }\n }\n if (this.limitSet_) {\n obj[WIRE_PROTOCOL_CONSTANTS.LIMIT] = this.limit_;\n let viewFrom = this.viewFrom_;\n if (viewFrom === '') {\n if (this.isViewFromLeft()) {\n viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT;\n } else {\n viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT;\n }\n }\n obj[WIRE_PROTOCOL_CONSTANTS.VIEW_FROM] = viewFrom;\n }\n // For now, priority index is the default, so we only specify if it's some other index\n if (this.index_ !== PRIORITY_INDEX) {\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX] = this.index_.toString();\n }\n return obj;\n }\n\n /**\n * @return {boolean}\n */\n loadsAllData(): boolean {\n return !(this.startSet_ || this.endSet_ || this.limitSet_);\n }\n\n /**\n * @return {boolean}\n */\n isDefault(): boolean {\n return this.loadsAllData() && this.index_ == PRIORITY_INDEX;\n }\n\n /**\n * @return {!NodeFilter}\n */\n getNodeFilter(): NodeFilter {\n if (this.loadsAllData()) {\n return new IndexedFilter(this.getIndex());\n } else if (this.hasLimit()) {\n return new LimitedFilter(this);\n } else {\n return new RangedFilter(this);\n }\n }\n\n\n /**\n * Returns a set of REST query string parameters representing this query.\n *\n * @return {!Object.} query string parameters\n */\n toRestQueryStringParameters(): { [k: string]: any } {\n const REST_CONSTANTS = QueryParams.REST_QUERY_CONSTANTS_;\n const qs: { [k: string]: string | number } = {};\n\n if (this.isDefault()) {\n return qs;\n }\n\n let orderBy;\n if (this.index_ === PRIORITY_INDEX) {\n orderBy = REST_CONSTANTS.PRIORITY_INDEX;\n } else if (this.index_ === VALUE_INDEX) {\n orderBy = REST_CONSTANTS.VALUE_INDEX;\n } else if (this.index_ === KEY_INDEX) {\n orderBy = REST_CONSTANTS.KEY_INDEX;\n } else {\n assert(this.index_ instanceof PathIndex, 'Unrecognized index type!');\n orderBy = this.index_.toString();\n }\n qs[REST_CONSTANTS.ORDER_BY] = stringify(orderBy);\n\n if (this.startSet_) {\n qs[REST_CONSTANTS.START_AT] = stringify(this.indexStartValue_);\n if (this.startNameSet_) {\n qs[REST_CONSTANTS.START_AT] += ',' + stringify(this.indexStartName_);\n }\n }\n\n if (this.endSet_) {\n qs[REST_CONSTANTS.END_AT] = stringify(this.indexEndValue_);\n if (this.endNameSet_) {\n qs[REST_CONSTANTS.END_AT] += ',' + stringify(this.indexEndName_);\n }\n }\n\n if (this.limitSet_) {\n if (this.isViewFromLeft()) {\n qs[REST_CONSTANTS.LIMIT_TO_FIRST] = this.limit_;\n } else {\n qs[REST_CONSTANTS.LIMIT_TO_LAST] = this.limit_;\n }\n }\n\n return qs;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/view/QueryParams.ts","/**\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\nimport { OnDisconnect } from './onDisconnect';\nimport { TransactionResult } from './TransactionResult';\nimport { warn } from '../core/util/util';\nimport { nextPushId } from '../core/util/NextPushId';\nimport { Query } from './Query';\nimport { Repo } from '../core/Repo';\nimport { Path } from '../core/util/Path';\nimport { QueryParams } from '../core/view/QueryParams';\nimport {\n validateRootPathString,\n validatePathString,\n validateFirebaseMergeDataArg,\n validateBoolean,\n validatePriority,\n validateFirebaseDataArg,\n validateWritablePath,\n} from '../core/util/validation';\nimport {\n validateArgCount,\n validateCallback,\n} from '../../utils/validation';\nimport { Deferred, attachDummyErrorHandler, PromiseImpl } from '../../utils/promise';\nimport { SyncPoint } from '../core/SyncPoint';\nimport { Database } from './Database';\nimport { DataSnapshot } from './DataSnapshot';\n\nexport interface ReferenceConstructor {\n new(repo: Repo, path: Path): Reference;\n}\n\nexport class Reference extends Query {\n public then: (a?: any) => Promise;\n public catch: (a?: Error) => Promise;\n\n /**\n * Call options:\n * new Reference(Repo, Path) or\n * new Reference(url: string, string|RepoManager)\n *\n * Externally - this is the firebase.database.Reference type.\n *\n * @param {!Repo} repo\n * @param {(!Path)} path\n * @extends {Query}\n */\n constructor(repo: Repo, path: Path) {\n if (!(repo instanceof Repo)) {\n throw new Error('new Reference() no longer supported - use app.database().');\n }\n\n // call Query's constructor, passing in the repo and path.\n super(repo, path, QueryParams.DEFAULT, false);\n }\n\n /** @return {?string} */\n getKey(): string | null {\n validateArgCount('Reference.key', 0, 0, arguments.length);\n\n if (this.path.isEmpty())\n return null;\n else\n return this.path.getBack();\n }\n\n /**\n * @param {!(string|Path)} pathString\n * @return {!Reference}\n */\n child(pathString: string | Path): Reference {\n validateArgCount('Reference.child', 1, 1, arguments.length);\n if (typeof pathString === 'number') {\n pathString = String(pathString);\n } else if (!(pathString instanceof Path)) {\n if (this.path.getFront() === null)\n validateRootPathString('Reference.child', 1, pathString, false);\n else\n validatePathString('Reference.child', 1, pathString, false);\n }\n\n return new Reference(this.repo, this.path.child(pathString));\n }\n\n /** @return {?Reference} */\n getParent(): Reference | null {\n validateArgCount('Reference.parent', 0, 0, arguments.length);\n\n const parentPath = this.path.parent();\n return parentPath === null ? null : new Reference(this.repo, parentPath);\n }\n\n /** @return {!Reference} */\n getRoot(): Reference {\n validateArgCount('Reference.root', 0, 0, arguments.length);\n\n let ref = (this as any);\n while (ref.getParent() !== null) {\n ref = ref.getParent();\n }\n return ref;\n }\n\n /** @return {!Database} */\n databaseProp(): Database {\n return this.repo.database;\n }\n\n /**\n * @param {*} newVal\n * @param {function(?Error)=} onComplete\n * @return {!Promise}\n */\n set(newVal: any, onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('Reference.set', 1, 2, arguments.length);\n validateWritablePath('Reference.set', this.path);\n validateFirebaseDataArg('Reference.set', 1, newVal, this.path, false);\n validateCallback('Reference.set', 2, onComplete, true);\n\n const deferred = new Deferred();\n this.repo.setWithPriority(this.path, newVal, /*priority=*/ null, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {!Object} objectToMerge\n * @param {function(?Error)=} onComplete\n * @return {!Promise}\n */\n update(objectToMerge: Object, onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('Reference.update', 1, 2, arguments.length);\n validateWritablePath('Reference.update', this.path);\n\n if (Array.isArray(objectToMerge)) {\n const newObjectToMerge: { [k: string]: any } = {};\n for (let i = 0; i < objectToMerge.length; ++i) {\n newObjectToMerge['' + i] = objectToMerge[i];\n }\n objectToMerge = newObjectToMerge;\n warn('Passing an Array to Firebase.update() is deprecated. ' +\n 'Use set() if you want to overwrite the existing data, or ' +\n 'an Object with integer keys if you really do want to ' +\n 'only update some of the children.'\n );\n }\n validateFirebaseMergeDataArg('Reference.update', 1, objectToMerge, this.path, false);\n validateCallback('Reference.update', 2, onComplete, true);\n const deferred = new Deferred();\n this.repo.update(this.path, objectToMerge, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {*} newVal\n * @param {string|number|null} newPriority\n * @param {function(?Error)=} onComplete\n * @return {!Promise}\n */\n setWithPriority(newVal: any, newPriority: string | number | null,\n onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('Reference.setWithPriority', 2, 3, arguments.length);\n validateWritablePath('Reference.setWithPriority', this.path);\n validateFirebaseDataArg('Reference.setWithPriority', 1, newVal, this.path, false);\n validatePriority('Reference.setWithPriority', 2, newPriority, false);\n validateCallback('Reference.setWithPriority', 3, onComplete, true);\n\n if (this.getKey() === '.length' || this.getKey() === '.keys')\n throw 'Reference.setWithPriority failed: ' + this.getKey() + ' is a read-only object.';\n\n const deferred = new Deferred();\n this.repo.setWithPriority(this.path, newVal, newPriority, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {function(?Error)=} onComplete\n * @return {!Promise}\n */\n remove(onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('Reference.remove', 0, 1, arguments.length);\n validateWritablePath('Reference.remove', this.path);\n validateCallback('Reference.remove', 1, onComplete, true);\n\n return this.set(null, onComplete);\n }\n\n /**\n * @param {function(*):*} transactionUpdate\n * @param {(function(?Error, boolean, ?DataSnapshot))=} onComplete\n * @param {boolean=} applyLocally\n * @return {!Promise}\n */\n transaction(transactionUpdate: (a: any) => any,\n onComplete?: (a: Error | null, b: boolean, c: DataSnapshot | null) => void,\n applyLocally?: boolean): Promise {\n validateArgCount('Reference.transaction', 1, 3, arguments.length);\n validateWritablePath('Reference.transaction', this.path);\n validateCallback('Reference.transaction', 1, transactionUpdate, false);\n validateCallback('Reference.transaction', 2, onComplete, true);\n // NOTE: applyLocally is an internal-only option for now. We need to decide if we want to keep it and how\n // to expose it.\n validateBoolean('Reference.transaction', 3, applyLocally, true);\n\n if (this.getKey() === '.length' || this.getKey() === '.keys')\n throw 'Reference.transaction failed: ' + this.getKey() + ' is a read-only object.';\n\n if (applyLocally === undefined)\n applyLocally = true;\n\n const deferred = new Deferred();\n if (typeof onComplete === 'function') {\n attachDummyErrorHandler(deferred.promise);\n }\n\n const promiseComplete = function (error: Error, committed: boolean, snapshot: DataSnapshot) {\n if (error) {\n deferred.reject(error);\n } else {\n deferred.resolve(new TransactionResult(committed, snapshot));\n }\n if (typeof onComplete === 'function') {\n onComplete(error, committed, snapshot);\n }\n };\n this.repo.startTransaction(this.path, transactionUpdate, promiseComplete, applyLocally);\n\n return deferred.promise;\n }\n\n /**\n * @param {string|number|null} priority\n * @param {function(?Error)=} onComplete\n * @return {!Promise}\n */\n setPriority(priority: string | number | null, onComplete?: (a: Error | null) => void): Promise {\n validateArgCount('Reference.setPriority', 1, 2, arguments.length);\n validateWritablePath('Reference.setPriority', this.path);\n validatePriority('Reference.setPriority', 1, priority, false);\n validateCallback('Reference.setPriority', 2, onComplete, true);\n\n const deferred = new Deferred();\n this.repo.setWithPriority(this.path.child('.priority'), priority, null, deferred.wrapCallback(onComplete));\n return deferred.promise;\n }\n\n /**\n * @param {*=} value\n * @param {function(?Error)=} onComplete\n * @return {!Reference}\n */\n push(value?: any, onComplete?: (a: Error | null) => void): Reference {\n validateArgCount('Reference.push', 0, 2, arguments.length);\n validateWritablePath('Reference.push', this.path);\n validateFirebaseDataArg('Reference.push', 1, value, this.path, true);\n validateCallback('Reference.push', 2, onComplete, true);\n\n const now = this.repo.serverTime();\n const name = nextPushId(now);\n\n // push() returns a ThennableReference whose promise is fulfilled with a regular Reference.\n // We use child() to create handles to two different references. The first is turned into a\n // ThennableReference below by adding then() and catch() methods and is used as the\n // return value of push(). The second remains a regular Reference and is used as the fulfilled\n // value of the first ThennableReference.\n const thennablePushRef = this.child(name);\n const pushRef = this.child(name);\n\n let promise;\n if (value != null) {\n promise = thennablePushRef.set(value, onComplete).then(() => pushRef);\n } else {\n promise = PromiseImpl.resolve(pushRef);\n }\n\n thennablePushRef.then = promise.then.bind(promise);\n thennablePushRef.catch = promise.then.bind(promise, undefined);\n\n if (typeof onComplete === 'function') {\n attachDummyErrorHandler(promise);\n }\n\n return thennablePushRef;\n }\n\n /**\n * @return {!OnDisconnect}\n */\n onDisconnect(): OnDisconnect {\n validateWritablePath('Reference.onDisconnect', this.path);\n return new OnDisconnect(this.repo, this.path);\n }\n\n get database(): Database {\n return this.databaseProp();\n }\n\n get key(): string | null {\n return this.getKey();\n }\n\n get parent(): Reference | null {\n return this.getParent();\n }\n\n get root(): Reference {\n return this.getRoot();\n }\n}\n\n/**\n * Define reference constructor in various modules\n *\n * We are doing this here to avoid several circular\n * dependency issues\n */\nQuery.__referenceConstructor = Reference;\nSyncPoint.__referenceConstructor = Reference;\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/Reference.ts","/**\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\nimport { assert } from '../../utils/assert';\nimport { Reference } from '../api/Reference';\nimport { DataSnapshot } from '../api/DataSnapshot';\nimport { Path } from './util/Path';\nimport { Tree } from './util/Tree';\nimport { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';\nimport { Node } from './snap/Node';\nimport {\n LUIDGenerator,\n warn,\n exceptionGuard,\n} from './util/util';\nimport { resolveDeferredValueSnapshot } from './util/ServerValues';\nimport { isValidPriority, validateFirebaseData } from './util/validation';\nimport { contains, safeGet } from '../../utils/obj';\nimport { nodeFromJSON } from './snap/nodeFromJSON';\nimport { ChildrenNode } from './snap/ChildrenNode';\nimport { Repo } from './Repo';\nimport { Event } from './view/Event';\n\n// TODO: This is pretty messy. Ideally, a lot of this would move into FirebaseData, or a transaction-specific\n// component used by FirebaseData, but it has ties to user callbacks (transaction update and onComplete) as well\n// as the realtime connection (to send transactions to the server). So that all needs to be decoupled first.\n// For now it's part of Repo, but in its own file.\n\n/**\n * @enum {number}\n */\nexport enum TransactionStatus {\n // We've run the transaction and updated transactionResultData_ with the result, but it isn't currently sent to the\n // server. A transaction will go from RUN -> SENT -> RUN if it comes back from the server as rejected due to\n // mismatched hash.\n RUN,\n\n // We've run the transaction and sent it to the server and it's currently outstanding (hasn't come back as accepted\n // or rejected yet).\n SENT,\n\n // Temporary state used to mark completed transactions (whether successful or aborted). The transaction will be\n // removed when we get a chance to prune completed ones.\n COMPLETED,\n\n // Used when an already-sent transaction needs to be aborted (e.g. due to a conflicting set() call that was made).\n // If it comes back as unsuccessful, we'll abort it.\n SENT_NEEDS_ABORT,\n\n // Temporary state used to mark transactions that need to be aborted.\n NEEDS_ABORT\n}\n\n/**\n * If a transaction does not succeed after 25 retries, we abort it. Among other things this ensure that if there's\n * ever a bug causing a mismatch between client / server hashes for some data, we won't retry indefinitely.\n * @type {number}\n * @const\n * @private\n */\n(Repo as any).MAX_TRANSACTION_RETRIES_ = 25;\n\n/**\n * @typedef {{\n * path: !Path,\n * update: function(*):*,\n * onComplete: ?function(?Error, boolean, ?DataSnapshot),\n * status: ?TransactionStatus,\n * order: !number,\n * applyLocally: boolean,\n * retryCount: !number,\n * unwatcher: function(),\n * abortReason: ?string,\n * currentWriteId: !number,\n * currentInputSnapshot: ?Node,\n * currentOutputSnapshotRaw: ?Node,\n * currentOutputSnapshotResolved: ?Node\n * }}\n */\ntype Transaction = {\n path: Path;\n update: (a: any) => any;\n onComplete: (a: Error | null, b: boolean, c: DataSnapshot | null) => void;\n status: TransactionStatus;\n order: number;\n applyLocally: boolean;\n retryCount: number;\n unwatcher: () => void;\n abortReason: string | null;\n currentWriteId: number;\n currentInputSnapshot: Node | null;\n currentOutputSnapshotRaw: Node | null;\n currentOutputSnapshotResolved: Node | null;\n}\n\n/**\n * Setup the transaction data structures\n * @private\n */\n(Repo.prototype as any).transactions_init_ = function () {\n /**\n * Stores queues of outstanding transactions for Firebase locations.\n *\n * @type {!Tree.>}\n * @private\n */\n this.transactionQueueTree_ = new Tree();\n};\n\ndeclare module './Repo' {\n interface Repo {\n startTransaction(path: Path,\n transactionUpdate: (a: any) => void,\n onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null,\n applyLocally: boolean): void\n }\n}\n\n/**\n * Creates a new transaction, adds it to the transactions we're tracking, and sends it to the server if possible.\n *\n * @param {!Path} path Path at which to do transaction.\n * @param {function(*):*} transactionUpdate Update callback.\n * @param {?function(?Error, boolean, ?DataSnapshot)} onComplete Completion callback.\n * @param {boolean} applyLocally Whether or not to make intermediate results visible\n */\nRepo.prototype.startTransaction = function (path: Path,\n transactionUpdate: (a: any) => any,\n onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null,\n applyLocally: boolean) {\n this.log_('transaction on ' + path);\n\n // Add a watch to make sure we get server updates.\n const valueCallback = function () { };\n const watchRef = new Reference(this, path);\n watchRef.on('value', valueCallback);\n const unwatcher = function () { watchRef.off('value', valueCallback); };\n\n // Initialize transaction.\n const transaction: Transaction = {\n path,\n update: transactionUpdate,\n onComplete,\n\n // One of TransactionStatus enums.\n status: null,\n\n // Used when combining transactions at different locations to figure out which one goes first.\n order: LUIDGenerator(),\n\n // Whether to raise local events for this transaction.\n applyLocally: applyLocally,\n\n // Count of how many times we've retried the transaction.\n retryCount: 0,\n\n // Function to call to clean up our .on() listener.\n unwatcher,\n\n // Stores why a transaction was aborted.\n abortReason: null,\n\n currentWriteId: null,\n\n currentInputSnapshot: null,\n\n currentOutputSnapshotRaw: null,\n\n currentOutputSnapshotResolved: null\n };\n\n\n // Run transaction initially.\n const currentState = this.getLatestState_(path);\n transaction.currentInputSnapshot = currentState;\n const newVal = transaction.update(currentState.val());\n if (newVal === undefined) {\n // Abort transaction.\n transaction.unwatcher();\n transaction.currentOutputSnapshotRaw = null;\n transaction.currentOutputSnapshotResolved = null;\n if (transaction.onComplete) {\n // We just set the input snapshot, so this cast should be safe\n const snapshot = new DataSnapshot(transaction.currentInputSnapshot, new Reference(this, transaction.path), PRIORITY_INDEX);\n transaction.onComplete(null, false, snapshot);\n }\n } else {\n validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path);\n\n // Mark as run and add to our queue.\n transaction.status = TransactionStatus.RUN;\n const queueNode = this.transactionQueueTree_.subTree(path);\n const nodeQueue = queueNode.getValue() || [];\n nodeQueue.push(transaction);\n\n queueNode.setValue(nodeQueue);\n\n // Update visibleData and raise events\n // Note: We intentionally raise events after updating all of our transaction state, since the user could\n // start new transactions from the event callbacks.\n let priorityForNode;\n if (typeof newVal === 'object' && newVal !== null && contains(newVal, '.priority')) {\n priorityForNode = safeGet(newVal, '.priority');\n assert(isValidPriority(priorityForNode), 'Invalid priority returned by transaction. ' +\n 'Priority must be a valid string, finite number, server value, or null.');\n } else {\n const currentNode = this.serverSyncTree_.calcCompleteEventCache(path) || ChildrenNode.EMPTY_NODE;\n priorityForNode = currentNode.getPriority().val();\n }\n priorityForNode = /** @type {null|number|string} */ (priorityForNode);\n\n const serverValues = this.generateServerValues();\n const newNodeUnresolved = nodeFromJSON(newVal, priorityForNode);\n const newNode = resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\n transaction.currentOutputSnapshotRaw = newNodeUnresolved;\n transaction.currentOutputSnapshotResolved = newNode;\n transaction.currentWriteId = this.getNextWriteId_();\n\n const events = this.serverSyncTree_.applyUserOverwrite(path, newNode, transaction.currentWriteId, transaction.applyLocally);\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n\n this.sendReadyTransactions_();\n }\n};\n\n/**\n * @param {!Path} path\n * @param {Array.=} excludeSets A specific set to exclude\n * @return {Node}\n * @private\n */\n(Repo.prototype as any).getLatestState_ = function (path: Path, excludeSets?: number[]): Node {\n return this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) || ChildrenNode.EMPTY_NODE;\n};\n\n\n/**\n * Sends any already-run transactions that aren't waiting for outstanding transactions to\n * complete.\n *\n * Externally it's called with no arguments, but it calls itself recursively with a particular\n * transactionQueueTree node to recurse through the tree.\n *\n * @param {Tree.>=} node transactionQueueTree node to start at.\n * @private\n */\n(Repo.prototype as any).sendReadyTransactions_ = function (node: Tree = this.transactionQueueTree_) {\n // Before recursing, make sure any completed transactions are removed.\n if (!node) {\n this.pruneCompletedTransactionsBelowNode_(node);\n }\n\n if (node.getValue() !== null) {\n const queue = this.buildTransactionQueue_(node);\n assert(queue.length > 0, 'Sending zero length transaction queue');\n\n const allRun = queue.every((transaction: Transaction) => transaction.status === TransactionStatus.RUN);\n\n // If they're all run (and not sent), we can send them. Else, we must wait.\n if (allRun) {\n this.sendTransactionQueue_(node.path(), queue);\n }\n } else if (node.hasChildren()) {\n node.forEachChild((childNode) => {\n this.sendReadyTransactions_(childNode);\n });\n }\n};\n\n\n/**\n * Given a list of run transactions, send them to the server and then handle the result (success or failure).\n *\n * @param {!Path} path The location of the queue.\n * @param {!Array.} queue Queue of transactions under the specified location.\n * @private\n */\n(Repo.prototype as any).sendTransactionQueue_ = function (path: Path, queue: Array) {\n // Mark transactions as sent and increment retry count!\n const setsToIgnore = queue.map(function (txn) { return txn.currentWriteId; });\n const latestState = this.getLatestState_(path, setsToIgnore);\n let snapToSend = latestState;\n const latestHash = latestState.hash();\n for (let i = 0; i < queue.length; i++) {\n const txn = queue[i];\n assert(txn.status === TransactionStatus.RUN,\n 'tryToSendTransactionQueue_: items in queue should all be run.');\n txn.status = TransactionStatus.SENT;\n txn.retryCount++;\n const relativePath = Path.relativePath(path, txn.path);\n // If we've gotten to this point, the output snapshot must be defined.\n snapToSend = snapToSend.updateChild(relativePath, /**@type {!Node} */ (txn.currentOutputSnapshotRaw));\n }\n\n const dataToSend = snapToSend.val(true);\n const pathToSend = path;\n\n // Send the put.\n this.server_.put(pathToSend.toString(), dataToSend, (status: string) => {\n this.log_('transaction put response', {path: pathToSend.toString(), status});\n\n let events: Event[] = [];\n if (status === 'ok') {\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n // the callback could trigger more transactions or sets.\n const callbacks = [];\n for (let i = 0; i < queue.length; i++) {\n queue[i].status = TransactionStatus.COMPLETED;\n events = events.concat(this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId));\n if (queue[i].onComplete) {\n // We never unset the output snapshot, and given that this transaction is complete, it should be set\n const node = queue[i].currentOutputSnapshotResolved as Node;\n const ref = new Reference(this, queue[i].path);\n const snapshot = new DataSnapshot(node, ref, PRIORITY_INDEX);\n callbacks.push(queue[i].onComplete.bind(null, null, true, snapshot));\n }\n queue[i].unwatcher();\n }\n\n // Now remove the completed transactions.\n this.pruneCompletedTransactionsBelowNode_(this.transactionQueueTree_.subTree(path));\n // There may be pending transactions that we can now send.\n this.sendReadyTransactions_();\n\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n\n // Finally, trigger onComplete callbacks.\n for (let i = 0; i < callbacks.length; i++) {\n exceptionGuard(callbacks[i]);\n }\n } else {\n // transactions are no longer sent. Update their status appropriately.\n if (status === 'datastale') {\n for (let i = 0; i < queue.length; i++) {\n if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT)\n queue[i].status = TransactionStatus.NEEDS_ABORT;\n else\n queue[i].status = TransactionStatus.RUN;\n }\n } else {\n warn('transaction at ' + pathToSend.toString() + ' failed: ' + status);\n for (let i = 0; i < queue.length; i++) {\n queue[i].status = TransactionStatus.NEEDS_ABORT;\n queue[i].abortReason = status;\n }\n }\n\n this.rerunTransactions_(path);\n }\n }, latestHash);\n};\n\n/**\n * Finds all transactions dependent on the data at changedPath and reruns them.\n *\n * Should be called any time cached data changes.\n *\n * Return the highest path that was affected by rerunning transactions. This is the path at which events need to\n * be raised for.\n *\n * @param {!Path} changedPath The path in mergedData that changed.\n * @return {!Path} The rootmost path that was affected by rerunning transactions.\n * @private\n */\n(Repo.prototype as any).rerunTransactions_ = function (changedPath: Path): Path {\n const rootMostTransactionNode = this.getAncestorTransactionNode_(changedPath);\n const path = rootMostTransactionNode.path();\n\n const queue = this.buildTransactionQueue_(rootMostTransactionNode);\n this.rerunTransactionQueue_(queue, path);\n\n return path;\n};\n\n\n/**\n * Does all the work of rerunning transactions (as well as cleans up aborted transactions and whatnot).\n *\n * @param {Array.} queue The queue of transactions to run.\n * @param {!Path} path The path the queue is for.\n * @private\n */\n(Repo.prototype as any).rerunTransactionQueue_ = function (queue: Array, path: Path) {\n if (queue.length === 0) {\n return; // Nothing to do!\n }\n\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n // the callback could trigger more transactions or sets.\n const callbacks = [];\n let events: Event[] = [];\n // Ignore all of the sets we're going to re-run.\n const txnsToRerun = queue.filter(function (q) { return q.status === TransactionStatus.RUN; });\n const setsToIgnore = txnsToRerun.map(function (q) { return q.currentWriteId; });\n for (let i = 0; i < queue.length; i++) {\n const transaction = queue[i];\n const relativePath = Path.relativePath(path, transaction.path);\n let abortTransaction = false, abortReason;\n assert(relativePath !== null, 'rerunTransactionsUnderNode_: relativePath should not be null.');\n\n if (transaction.status === TransactionStatus.NEEDS_ABORT) {\n abortTransaction = true;\n abortReason = transaction.abortReason;\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\n } else if (transaction.status === TransactionStatus.RUN) {\n if (transaction.retryCount >= (Repo as any).MAX_TRANSACTION_RETRIES_) {\n abortTransaction = true;\n abortReason = 'maxretry';\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\n } else {\n // This code reruns a transaction\n const currentNode = this.getLatestState_(transaction.path, setsToIgnore);\n transaction.currentInputSnapshot = currentNode;\n const newData = queue[i].update(currentNode.val());\n if (newData !== undefined) {\n validateFirebaseData('transaction failed: Data returned ', newData, transaction.path);\n let newDataNode = nodeFromJSON(newData);\n const hasExplicitPriority = (typeof newData === 'object' && newData != null &&\n contains(newData, '.priority'));\n if (!hasExplicitPriority) {\n // Keep the old priority if there wasn't a priority explicitly specified.\n newDataNode = newDataNode.updatePriority(currentNode.getPriority());\n }\n\n const oldWriteId = transaction.currentWriteId;\n const serverValues = this.generateServerValues();\n const newNodeResolved = resolveDeferredValueSnapshot(newDataNode, serverValues);\n\n transaction.currentOutputSnapshotRaw = newDataNode;\n transaction.currentOutputSnapshotResolved = newNodeResolved;\n transaction.currentWriteId = this.getNextWriteId_();\n // Mutates setsToIgnore in place\n setsToIgnore.splice(setsToIgnore.indexOf(oldWriteId), 1);\n events = events.concat(\n this.serverSyncTree_.applyUserOverwrite(transaction.path, newNodeResolved, transaction.currentWriteId,\n transaction.applyLocally)\n );\n events = events.concat(this.serverSyncTree_.ackUserWrite(oldWriteId, true));\n } else {\n abortTransaction = true;\n abortReason = 'nodata';\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\n }\n }\n }\n this.eventQueue_.raiseEventsForChangedPath(path, events);\n events = [];\n if (abortTransaction) {\n // Abort.\n queue[i].status = TransactionStatus.COMPLETED;\n\n // Removing a listener can trigger pruning which can muck with mergedData/visibleData (as it prunes data).\n // So defer the unwatcher until we're done.\n (function (unwatcher) {\n setTimeout(unwatcher, Math.floor(0));\n })(queue[i].unwatcher);\n\n if (queue[i].onComplete) {\n if (abortReason === 'nodata') {\n const ref = new Reference(this, queue[i].path);\n // We set this field immediately, so it's safe to cast to an actual snapshot\n const lastInput = /** @type {!Node} */ (queue[i].currentInputSnapshot);\n const snapshot = new DataSnapshot(lastInput, ref, PRIORITY_INDEX);\n callbacks.push(queue[i].onComplete.bind(null, null, false, snapshot));\n } else {\n callbacks.push(queue[i].onComplete.bind(null, new Error(abortReason), false, null));\n }\n }\n }\n }\n\n // Clean up completed transactions.\n this.pruneCompletedTransactionsBelowNode_(this.transactionQueueTree_);\n\n // Now fire callbacks, now that we're in a good, known state.\n for (let i = 0; i < callbacks.length; i++) {\n exceptionGuard(callbacks[i]);\n }\n\n // Try to send the transaction result to the server.\n this.sendReadyTransactions_();\n};\n\n\n/**\n * Returns the rootmost ancestor node of the specified path that has a pending transaction on it, or just returns\n * the node for the given path if there are no pending transactions on any ancestor.\n *\n * @param {!Path} path The location to start at.\n * @return {!Tree.>} The rootmost node with a transaction.\n * @private\n */\n(Repo.prototype as any).getAncestorTransactionNode_ = function (path: Path): Tree {\n let front;\n\n // Start at the root and walk deeper into the tree towards path until we find a node with pending transactions.\n let transactionNode = this.transactionQueueTree_;\n while ((front = path.getFront()) !== null && transactionNode.getValue() === null) {\n transactionNode = transactionNode.subTree(front);\n path = path.popFront();\n }\n\n return transactionNode;\n};\n\n\n/**\n * Builds the queue of all transactions at or below the specified transactionNode.\n *\n * @param {!Tree.>} transactionNode\n * @return {Array.} The generated queue.\n * @private\n */\n(Repo.prototype as any).buildTransactionQueue_ = function (transactionNode: Tree): Array {\n // Walk any child transaction queues and aggregate them into a single queue.\n const transactionQueue: Transaction[] = [];\n this.aggregateTransactionQueuesForNode_(transactionNode, transactionQueue);\n\n // Sort them by the order the transactions were created.\n transactionQueue.sort(function (a, b) { return a.order - b.order; });\n\n return transactionQueue;\n};\n\n/**\n * @param {!Tree.>} node\n * @param {Array.} queue\n * @private\n */\n(Repo.prototype as any).aggregateTransactionQueuesForNode_ = function (node: Tree,\n queue: Array) {\n const nodeQueue = node.getValue();\n if (nodeQueue !== null) {\n for (let i = 0; i < nodeQueue.length; i++) {\n queue.push(nodeQueue[i]);\n }\n }\n\n node.forEachChild((child) => {\n this.aggregateTransactionQueuesForNode_(child, queue);\n });\n};\n\n\n/**\n * Remove COMPLETED transactions at or below this node in the transactionQueueTree_.\n *\n * @param {!Tree.>} node\n * @private\n */\n(Repo.prototype as any).pruneCompletedTransactionsBelowNode_ = function (node: Tree) {\n const queue = node.getValue();\n if (queue) {\n let to = 0;\n for (let from = 0; from < queue.length; from++) {\n if (queue[from].status !== TransactionStatus.COMPLETED) {\n queue[to] = queue[from];\n to++;\n }\n }\n queue.length = to;\n node.setValue(queue.length > 0 ? queue : null);\n }\n\n node.forEachChild((childNode) => {\n this.pruneCompletedTransactionsBelowNode_(childNode);\n });\n};\n\n\n/**\n * Aborts all transactions on ancestors or descendants of the specified path. Called when doing a set() or update()\n * since we consider them incompatible with transactions.\n *\n * @param {!Path} path Path for which we want to abort related transactions.\n * @return {!Path}\n * @private\n */\n(Repo.prototype as any).abortTransactions_ = function (path: Path): Path {\n const affectedPath = this.getAncestorTransactionNode_(path).path();\n\n const transactionNode = this.transactionQueueTree_.subTree(path);\n\n transactionNode.forEachAncestor((node: Tree) => {\n this.abortTransactionsOnNode_(node);\n });\n\n this.abortTransactionsOnNode_(transactionNode);\n\n transactionNode.forEachDescendant((node: Tree) => {\n this.abortTransactionsOnNode_(node);\n });\n\n return affectedPath;\n};\n\n\n/**\n * Abort transactions stored in this transaction queue node.\n *\n * @param {!Tree.>} node Node to abort transactions for.\n * @private\n */\n(Repo.prototype as any).abortTransactionsOnNode_ = function (node: Tree) {\n const queue = node.getValue();\n if (queue !== null) {\n\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\n // the callback could trigger more transactions or sets.\n const callbacks = [];\n\n // Go through queue. Any already-sent transactions must be marked for abort, while the unsent ones\n // can be immediately aborted and removed.\n let events: Event[] = [];\n let lastSent = -1;\n for (let i = 0; i < queue.length; i++) {\n if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT) {\n // Already marked. No action needed.\n } else if (queue[i].status === TransactionStatus.SENT) {\n assert(lastSent === i - 1, 'All SENT items should be at beginning of queue.');\n lastSent = i;\n // Mark transaction for abort when it comes back.\n queue[i].status = TransactionStatus.SENT_NEEDS_ABORT;\n queue[i].abortReason = 'set';\n } else {\n assert(queue[i].status === TransactionStatus.RUN,\n 'Unexpected transaction status in abort');\n // We can abort it immediately.\n queue[i].unwatcher();\n events = events.concat(this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId, true));\n if (queue[i].onComplete) {\n const snapshot: DataSnapshot | null = null;\n callbacks.push(queue[i].onComplete.bind(null, new Error('set'), false, snapshot));\n }\n }\n }\n if (lastSent === -1) {\n // We're not waiting for any sent transactions. We can clear the queue.\n node.setValue(null);\n } else {\n // Remove the transactions we aborted.\n queue.length = lastSent + 1;\n }\n\n // Now fire the callbacks.\n this.eventQueue_.raiseEventsForChangedPath(node.path(), events);\n for (let i = 0; i < callbacks.length; i++) {\n exceptionGuard(callbacks[i]);\n }\n }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/Repo_transaction.ts","/**\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\nimport { assert } from '../../../utils/assert';\nimport { Path } from './Path';\nimport { forEach, contains, safeGet } from '../../../utils/obj'\n\n/**\n * Node in a Tree.\n */\nexport class TreeNode {\n // TODO: Consider making accessors that create children and value lazily or\n // separate Internal / Leaf 'types'.\n children: { [name: string]: TreeNode } = {};\n childCount = 0;\n value: T | null = null;\n}\n\n\n/**\n * A light-weight tree, traversable by path. Nodes can have both values and children.\n * Nodes are not enumerated (by forEachChild) unless they have a value or non-empty\n * children.\n */\nexport class Tree {\n /**\n * @template T\n * @param {string=} name_ Optional name of the node.\n * @param {Tree=} parent_ Optional parent node.\n * @param {TreeNode=} node_ Optional node to wrap.\n */\n constructor(private name_: string = '',\n private parent_: Tree | null = null,\n private node_: TreeNode = new TreeNode()) {\n }\n\n /**\n * Returns a sub-Tree for the given path.\n *\n * @param {!(string|Path)} pathObj Path to look up.\n * @return {!Tree.} Tree for path.\n */\n subTree(pathObj: string | Path): Tree {\n // TODO: Require pathObj to be Path?\n let path = (pathObj instanceof Path) ?\n pathObj : new Path(pathObj);\n let child = this as any, next;\n while ((next = path.getFront()) !== null) {\n const childNode = safeGet(child.node_.children, next) || new TreeNode();\n child = new Tree(next, child, childNode);\n path = path.popFront();\n }\n\n return child;\n }\n\n /**\n * Returns the data associated with this tree node.\n *\n * @return {?T} The data or null if no data exists.\n */\n getValue(): T | null {\n return this.node_.value;\n }\n\n /**\n * Sets data to this tree node.\n *\n * @param {!T} value Value to set.\n */\n setValue(value: T) {\n assert(typeof value !== 'undefined', 'Cannot set value to undefined');\n this.node_.value = value;\n this.updateParents_();\n }\n\n /**\n * Clears the contents of the tree node (its value and all children).\n */\n clear() {\n this.node_.value = null;\n this.node_.children = {};\n this.node_.childCount = 0;\n this.updateParents_();\n }\n\n /**\n * @return {boolean} Whether the tree has any children.\n */\n hasChildren(): boolean {\n return this.node_.childCount > 0;\n }\n\n /**\n * @return {boolean} Whether the tree is empty (no value or children).\n */\n isEmpty(): boolean {\n return this.getValue() === null && !this.hasChildren();\n }\n\n /**\n * Calls action for each child of this tree node.\n *\n * @param {function(!Tree.)} action Action to be called for each child.\n */\n forEachChild(action: (tree: Tree) => void) {\n forEach(this.node_.children, (child: string, childTree: TreeNode) => {\n action(new Tree(child, this, childTree));\n });\n }\n\n /**\n * Does a depth-first traversal of this node's descendants, calling action for each one.\n *\n * @param {function(!Tree.)} action Action to be called for each child.\n * @param {boolean=} includeSelf Whether to call action on this node as well. Defaults to\n * false.\n * @param {boolean=} childrenFirst Whether to call action on children before calling it on\n * parent.\n */\n forEachDescendant(action: (tree: Tree) => void, includeSelf?: boolean, childrenFirst?: boolean) {\n if (includeSelf && !childrenFirst)\n action(this);\n\n this.forEachChild(function (child) {\n child.forEachDescendant(action, /*includeSelf=*/true, childrenFirst);\n });\n\n if (includeSelf && childrenFirst)\n action(this);\n }\n\n /**\n * Calls action on each ancestor node.\n *\n * @param {function(!Tree.)} action Action to be called on each parent; return\n * true to abort.\n * @param {boolean=} includeSelf Whether to call action on this node as well.\n * @return {boolean} true if the action callback returned true.\n */\n forEachAncestor(action: (tree: Tree) => void, includeSelf?: boolean): boolean {\n let node = includeSelf ? this : this.parent();\n while (node !== null) {\n if (action(node)) {\n return true;\n }\n node = node.parent();\n }\n return false;\n }\n\n /**\n * Does a depth-first traversal of this node's descendants. When a descendant with a value\n * is found, action is called on it and traversal does not continue inside the node.\n * Action is *not* called on this node.\n *\n * @param {function(!Tree.)} action Action to be called for each child.\n */\n forEachImmediateDescendantWithValue(action: (tree: Tree) => void) {\n this.forEachChild(function (child) {\n if (child.getValue() !== null)\n action(child);\n else\n child.forEachImmediateDescendantWithValue(action);\n });\n }\n\n /**\n * @return {!Path} The path of this tree node, as a Path.\n */\n path(): Path {\n return new Path(this.parent_ === null ?\n this.name_ : this.parent_.path() + '/' + this.name_);\n }\n\n /**\n * @return {string} The name of the tree node.\n */\n name(): string {\n return this.name_;\n }\n\n /**\n * @return {?Tree} The parent tree node, or null if this is the root of the tree.\n */\n parent(): Tree | null {\n return this.parent_;\n }\n\n /**\n * Adds or removes this child from its parent based on whether it's empty or not.\n *\n * @private\n */\n private updateParents_() {\n if (this.parent_ !== null)\n this.parent_.updateChild_(this.name_, this);\n }\n\n /**\n * Adds or removes the passed child to this tree node, depending on whether it's empty.\n *\n * @param {string} childName The name of the child to update.\n * @param {!Tree.} child The child to update.\n * @private\n */\n private updateChild_(childName: string, child: Tree) {\n const childEmpty = child.isEmpty();\n const childExists = contains(this.node_.children, childName);\n if (childEmpty && childExists) {\n delete (this.node_.children[childName]);\n this.node_.childCount--;\n this.updateParents_();\n }\n else if (!childEmpty && !childExists) {\n this.node_.children[childName] = child.node_;\n this.node_.childCount++;\n this.updateParents_();\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/util/Tree.ts","/**\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\nimport { FirebaseApp } from \"../../app/firebase_app\";\nimport { safeGet } from \"../../utils/obj\";\nimport { Repo } from \"./Repo\";\nimport { fatal } from \"./util/util\";\nimport { parseRepoInfo } from \"./util/libs/parser\";\nimport { validateUrl } from \"./util/validation\";\nimport \"./Repo_transaction\";\nimport { Database } from '../api/Database';\nimport { RepoInfo } from './RepoInfo';\n\n/** @const {string} */\nconst DATABASE_URL_OPTION = 'databaseURL';\n\nlet _staticInstance: RepoManager;\n\n/**\n * Creates and caches Repo instances.\n */\nexport class RepoManager {\n /**\n * @private {!Object.}\n */\n private repos_: {\n [name: string]: Repo\n } = {};\n\n /**\n * If true, new Repos will be created to use ReadonlyRestClient (for testing purposes).\n * @private {boolean}\n */\n private useRestClient_: boolean = false;\n\n static getInstance(): RepoManager {\n if (!_staticInstance) {\n _staticInstance = new RepoManager();\n }\n return _staticInstance;\n }\n\n // TODO(koss): Remove these functions unless used in tests?\n interrupt() {\n for (const repo in this.repos_) {\n this.repos_[repo].interrupt();\n }\n }\n\n resume() {\n for (const repo in this.repos_) {\n this.repos_[repo].resume();\n }\n }\n\n /**\n * This function should only ever be called to CREATE a new database instance.\n *\n * @param {!FirebaseApp} app\n * @return {!Database}\n */\n databaseFromApp(app: FirebaseApp): Database {\n const dbUrl: string = app.options[DATABASE_URL_OPTION];\n if (dbUrl === undefined) {\n fatal(\"Can't determine Firebase Database URL. Be sure to include \" +\n DATABASE_URL_OPTION +\n \" option when calling firebase.intializeApp().\");\n }\n\n const parsedUrl = parseRepoInfo(dbUrl);\n const repoInfo = parsedUrl.repoInfo;\n\n validateUrl('Invalid Firebase Database URL', 1, parsedUrl);\n if (!parsedUrl.path.isEmpty()) {\n fatal(\"Database URL must point to the root of a Firebase Database \" +\n \"(not including a child path).\");\n }\n\n const repo = this.createRepo(repoInfo, app);\n\n return repo.database;\n }\n\n /**\n * Remove the repo and make sure it is disconnected.\n *\n * @param {!Repo} repo\n */\n deleteRepo(repo: Repo) {\n \n // This should never happen...\n if (safeGet(this.repos_, repo.app.name) !== repo) {\n fatal(\"Database \" + repo.app.name + \" has already been deleted.\");\n }\n repo.interrupt();\n delete this.repos_[repo.app.name];\n }\n\n /**\n * Ensures a repo doesn't already exist and then creates one using the\n * provided app.\n *\n * @param {!RepoInfo} repoInfo The metadata about the Repo\n * @param {!FirebaseApp} app\n * @return {!Repo} The Repo object for the specified server / repoName.\n */\n createRepo(repoInfo: RepoInfo, app: FirebaseApp): Repo {\n let repo = safeGet(this.repos_, app.name);\n if (repo) {\n fatal('FIREBASE INTERNAL ERROR: Database initialized multiple times.');\n }\n repo = new Repo(repoInfo, this.useRestClient_, app);\n this.repos_[app.name] = repo;\n\n return repo;\n }\n\n /**\n * Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.\n * @param {boolean} forceRestClient\n */\n forceRestClient(forceRestClient: boolean) {\n this.useRestClient_ = forceRestClient;\n }\n}\n\n\n// WEBPACK FOOTER //\n// ./src/database/core/RepoManager.ts","/**\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\nimport { fatal } from '../core/util/util';\nimport { parseRepoInfo } from '../core/util/libs/parser';\nimport { Path } from '../core/util/Path';\nimport { PromiseImpl } from '../../utils/promise';\nimport { Reference } from './Reference';\nimport { Repo } from '../core/Repo';\nimport { RepoManager } from '../core/RepoManager';\nimport { validateArgCount } from '../../utils/validation';\nimport { validateUrl } from '../core/util/validation';\nimport { FirebaseApp, FirebaseService } from '../../app/firebase_app';\nimport { RepoInfo } from '../core/RepoInfo';\n\n/**\n * Class representing a firebase database.\n * @implements {FirebaseService}\n */\nexport class Database implements FirebaseService {\n INTERNAL: DatabaseInternals;\n private root_: Reference;\n\n static readonly ServerValue = {\n 'TIMESTAMP': {\n '.sv': 'timestamp'\n }\n };\n\n /**\n * The constructor should not be called by users of our public API.\n * @param {!Repo} repo_\n */\n constructor(private repo_: Repo) {\n if (!(repo_ instanceof Repo)) {\n fatal('Don\\'t call new Database() directly - please use firebase.database().');\n }\n\n /** @type {Reference} */\n this.root_ = new Reference(repo_, Path.Empty);\n\n this.INTERNAL = new DatabaseInternals(this);\n }\n\n get app(): FirebaseApp {\n return this.repo_.app;\n }\n\n /**\n * Returns a reference to the root or the path specified in opt_pathString.\n * @param {string=} pathString\n * @return {!Reference} Firebase reference.\n */\n ref(pathString?: string): Reference {\n this.checkDeleted_('ref');\n validateArgCount('database.ref', 0, 1, arguments.length);\n\n return pathString !== undefined ? this.root_.child(pathString) : this.root_;\n }\n\n /**\n * Returns a reference to the root or the path specified in url.\n * We throw a exception if the url is not in the same domain as the\n * current repo.\n * @param {string} url\n * @return {!Reference} Firebase reference.\n */\n refFromURL(url: string): Reference {\n /** @const {string} */\n const apiName = 'database.refFromURL';\n this.checkDeleted_(apiName);\n validateArgCount(apiName, 1, 1, arguments.length);\n const parsedURL = parseRepoInfo(url);\n validateUrl(apiName, 1, parsedURL);\n\n const repoInfo = parsedURL.repoInfo;\n if (repoInfo.host !== ((this.repo_ as any).repoInfo_ as RepoInfo).host) {\n fatal(apiName + ': Host name does not match the current database: ' +\n '(found ' + repoInfo.host + ' but expected ' +\n ((this.repo_ as any).repoInfo_ as RepoInfo).host + ')');\n }\n\n return this.ref(parsedURL.path.toString());\n }\n\n /**\n * @param {string} apiName\n */\n private checkDeleted_(apiName: string) {\n if (this.repo_ === null) {\n fatal('Cannot call ' + apiName + ' on a deleted database.');\n }\n }\n\n // Make individual repo go offline.\n goOffline() {\n validateArgCount('database.goOffline', 0, 0, arguments.length);\n this.checkDeleted_('goOffline');\n this.repo_.interrupt();\n }\n\n goOnline() {\n validateArgCount('database.goOnline', 0, 0, arguments.length);\n this.checkDeleted_('goOnline');\n this.repo_.resume();\n }\n}\n\nexport class DatabaseInternals {\n /** @param {!Database} database */\n constructor(public database: Database) {\n }\n\n /** @return {Promise} */\n delete(): Promise {\n (this.database as any).checkDeleted_('delete');\n RepoManager.getInstance().deleteRepo((this.database as any).repo_ as Repo);\n\n (this.database as any).repo_ = null;\n (this.database as any).root_ = null;\n this.database.INTERNAL = null;\n this.database = null;\n return PromiseImpl.resolve();\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/Database.ts","/**\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\nimport { WebSocketConnection } from \"../realtime/WebSocketConnection\";\nimport { BrowserPollConnection } from \"../realtime/BrowserPollConnection\";\nimport { Reference } from './Reference';\n\n/**\n * INTERNAL methods for internal-use only (tests, etc.).\n *\n * Customers shouldn't use these or else should be aware that they could break at any time.\n *\n * @const\n */\n\nexport const forceLongPolling = function() {\n WebSocketConnection.forceDisallow();\n BrowserPollConnection.forceAllow();\n};\n\nexport const forceWebSockets = function() {\n BrowserPollConnection.forceDisallow();\n};\n\n/* Used by App Manager */\nexport const isWebSocketsAvailable = function(): boolean {\n return WebSocketConnection['isAvailable']();\n};\n\nexport const setSecurityDebugCallback = function(ref: Reference, callback: (a: Object) => void) {\n (ref.repo.persistentConnection_ as any).securityDebugCallback_ = callback;\n};\n\nexport const stats = function(ref: Reference, showDelta?: boolean) {\n ref.repo.stats(showDelta);\n};\n\nexport const statsIncrementCounter = function(ref: Reference, metric: string) {\n ref.repo.statsIncrementCounter(metric);\n};\n\nexport const dataUpdateCount = function(ref: Reference): number {\n return ref.repo.dataUpdateCount;\n};\n\nexport const interceptServerData = function(ref: Reference, callback: ((a: string, b: any) => void) | null) {\n return ref.repo.interceptServerData_(callback);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/internal.ts","/**\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\nimport { RepoInfo } from \"../core/RepoInfo\";\nimport { PersistentConnection } from \"../core/PersistentConnection\";\nimport { RepoManager } from \"../core/RepoManager\";\nimport { Connection } from \"../realtime/Connection\";\nimport { Query } from './Query';\n\nexport const DataConnection = PersistentConnection;\n\n/**\n * @param {!string} pathString\n * @param {function(*)} onComplete\n */\n(PersistentConnection.prototype as any).simpleListen = function(pathString: string, onComplete: (a: any) => void) {\n this.sendRequest('q', {'p': pathString}, onComplete);\n};\n\n/**\n * @param {*} data\n * @param {function(*)} onEcho\n */\n(PersistentConnection.prototype as any).echo = function(data: any, onEcho: (a: any) => void) {\n this.sendRequest('echo', {'d': data}, onEcho);\n};\n\n// RealTimeConnection properties that we use in tests.\nexport const RealTimeConnection = Connection;\n\n/**\n * @param {function(): string} newHash\n * @return {function()}\n */\nexport const hijackHash = function(newHash: () => string) {\n const oldPut = PersistentConnection.prototype.put;\n PersistentConnection.prototype.put = function(pathString, data, opt_onComplete, opt_hash) {\n if (opt_hash !== undefined) {\n opt_hash = newHash();\n }\n oldPut.call(this, pathString, data, opt_onComplete, opt_hash);\n };\n return function() {\n PersistentConnection.prototype.put = oldPut;\n }\n};\n\n/**\n * @type {function(new:RepoInfo, !string, boolean, !string, boolean): undefined}\n */\nexport const ConnectionTarget = RepoInfo;\n\n/**\n * @param {!Query} query\n * @return {!string}\n */\nexport const queryIdentifier = function(query: Query) {\n return query.queryIdentifier();\n};\n\n/**\n * @param {!Query} firebaseRef\n * @return {!Object}\n */\nexport const listens = function(firebaseRef: Query) {\n return (firebaseRef.repo.persistentConnection_ as any).listens_;\n};\n\n/**\n * Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.\n *\n * @param {boolean} forceRestClient\n */\nexport const forceRestClient = function(forceRestClient: boolean) {\n RepoManager.getInstance().forceRestClient(forceRestClient);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/database/api/test_access.ts","/**\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\nimport firebase from './app';\nimport { FirebaseApp, FirebaseNamespace } from \"./app/firebase_app\";\nimport { Database } from \"./database/api/Database\";\nimport { Query } from \"./database/api/Query\";\nimport { Reference } from \"./database/api/Reference\";\nimport { enableLogging } from \"./database/core/util/util\";\nimport { RepoManager } from \"./database/core/RepoManager\";\nimport * as INTERNAL from './database/api/internal';\nimport * as TEST_ACCESS from './database/api/test_access';\nimport { isNodeSdk } from \"./utils/environment\";\n\nexport function registerDatabase(instance: FirebaseNamespace) {\n // Register the Database Service with the 'firebase' namespace.\n const namespace = instance.INTERNAL.registerService(\n 'database',\n app => RepoManager.getInstance().databaseFromApp(app),\n // firebase.database namespace properties\n {\n Reference,\n Query,\n Database,\n enableLogging,\n INTERNAL,\n ServerValue: Database.ServerValue,\n TEST_ACCESS\n }\n );\n\n if (isNodeSdk()) {\n module.exports = namespace;\n }\n}\n\n/**\n * Extensions to the FirebaseApp and FirebaseNamespaces interfaces\n */\ndeclare module './app/firebase_app' {\n interface FirebaseApp {\n database?(): Database\n }\n}\n\ndeclare module './app/firebase_app' {\n interface FirebaseNamespace {\n database?: {\n (app?: FirebaseApp): Database,\n Database,\n enableLogging,\n INTERNAL,\n Query,\n Reference,\n ServerValue,\n }\n }\n}\n\nregisterDatabase(firebase);\n\n\n\n// WEBPACK FOOTER //\n// ./src/database.ts","module.exports = function(originalModule) {\r\n\tif(!originalModule.webpackPolyfill) {\r\n\t\tvar module = Object.create(originalModule);\r\n\t\t// module.parent = undefined by default\r\n\t\tif(!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.l;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.i;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"exports\", {\r\n\t\t\tenumerable: true,\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/harmony-module.js\n// module id = 25\n// module chunks = 0","try {\n webpackJsonpFirebase([2],{\n\n/***/ 23:\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n\n// CONCATENATED MODULE: ./src/messaging/models/errors.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\nvar CODES = {\n AVAILABLE_IN_WINDOW: 'only-available-in-window',\n AVAILABLE_IN_SW: 'only-available-in-sw',\n SHOULD_BE_INHERITED: 'should-be-overriden',\n BAD_SENDER_ID: 'bad-sender-id',\n INCORRECT_GCM_SENDER_ID: 'incorrect-gcm-sender-id',\n PERMISSION_DEFAULT: 'permission-default',\n PERMISSION_BLOCKED: 'permission-blocked',\n UNSUPPORTED_BROWSER: 'unsupported-browser',\n NOTIFICATIONS_BLOCKED: 'notifications-blocked',\n FAILED_DEFAULT_REGISTRATION: 'failed-serviceworker-registration',\n SW_REGISTRATION_EXPECTED: 'sw-registration-expected',\n GET_SUBSCRIPTION_FAILED: 'get-subscription-failed',\n INVALID_SAVED_TOKEN: 'invalid-saved-token',\n SW_REG_REDUNDANT: 'sw-reg-redundant',\n TOKEN_SUBSCRIBE_FAILED: 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN: 'token-subscribe-no-token',\n TOKEN_SUBSCRIBE_NO_PUSH_SET: 'token-subscribe-no-push-set',\n USE_SW_BEFORE_GET_TOKEN: 'use-sw-before-get-token',\n INVALID_DELETE_TOKEN: 'invalid-delete-token',\n DELETE_TOKEN_NOT_FOUND: 'delete-token-not-found',\n DELETE_SCOPE_NOT_FOUND: 'delete-scope-not-found',\n BG_HANDLER_FUNCTION_EXPECTED: 'bg-handler-function-expected',\n NO_WINDOW_CLIENT_TO_MSG: 'no-window-client-to-msg',\n UNABLE_TO_RESUBSCRIBE: 'unable-to-resubscribe',\n NO_FCM_TOKEN_FOR_RESUBSCRIBE: 'no-fcm-token-for-resubscribe',\n FAILED_TO_DELETE_TOKEN: 'failed-to-delete-token',\n NO_SW_IN_REG: 'no-sw-in-reg',\n BAD_SCOPE: 'bad-scope',\n BAD_VAPID_KEY: 'bad-vapid-key',\n BAD_SUBSCRIPTION: 'bad-subscription',\n BAD_TOKEN: 'bad-token',\n BAD_PUSH_SET: 'bad-push-set',\n FAILED_DELETE_VAPID_KEY: 'failed-delete-vapid-key'\n};\nvar ERROR_MAP = (_a = {}, _a[CODES.AVAILABLE_IN_WINDOW] = 'This method is available in a Window context.', _a[CODES.AVAILABLE_IN_SW] = 'This method is available in a service worker ' + 'context.', _a[CODES.SHOULD_BE_INHERITED] = 'This method should be overriden by ' + 'extended classes.', _a[CODES.BAD_SENDER_ID] = 'Please ensure that \\'messagingSenderId\\' is set ' + 'correctly in the options passed into firebase.initializeApp().', _a[CODES.PERMISSION_DEFAULT] = 'The required permissions were not granted and ' + 'dismissed instead.', _a[CODES.PERMISSION_BLOCKED] = 'The required permissions were not granted and ' + 'blocked instead.', _a[CODES.UNSUPPORTED_BROWSER] = 'This browser doesn\\'t support the API\\'s ' + 'required to use the firebase SDK.', _a[CODES.NOTIFICATIONS_BLOCKED] = 'Notifications have been blocked.', _a[CODES.FAILED_DEFAULT_REGISTRATION] = 'We are unable to register the ' + 'default service worker. {$browserErrorMessage}', _a[CODES.SW_REGISTRATION_EXPECTED] = 'A service worker registration was the ' + 'expected input.', _a[CODES.GET_SUBSCRIPTION_FAILED] = 'There was an error when trying to get ' + 'any existing Push Subscriptions.', _a[CODES.INVALID_SAVED_TOKEN] = 'Unable to access details of the saved token.', _a[CODES.SW_REG_REDUNDANT] = 'The service worker being used for push was made ' + 'redundant.', _a[CODES.TOKEN_SUBSCRIBE_FAILED] = 'A problem occured while subscribing the ' + 'user to FCM: {$message}', _a[CODES.TOKEN_SUBSCRIBE_NO_TOKEN] = 'FCM returned no token when subscribing ' + 'the user to push.', _a[CODES.TOKEN_SUBSCRIBE_NO_PUSH_SET] = 'FCM returned an invalid response ' + 'when getting an FCM token.', _a[CODES.USE_SW_BEFORE_GET_TOKEN] = 'You must call useServiceWorker() before ' + 'calling getToken() to ensure your service worker is used.', _a[CODES.INVALID_DELETE_TOKEN] = 'You must pass a valid token into ' + 'deleteToken(), i.e. the token from getToken().', _a[CODES.DELETE_TOKEN_NOT_FOUND] = 'The deletion attempt for token could not ' + 'be performed as the token was not found.', _a[CODES.DELETE_SCOPE_NOT_FOUND] = 'The deletion attempt for service worker ' + 'scope could not be performed as the scope was not found.', _a[CODES.BG_HANDLER_FUNCTION_EXPECTED] = 'The input to ' + 'setBackgroundMessageHandler() must be a function.', _a[CODES.NO_WINDOW_CLIENT_TO_MSG] = 'An attempt was made to message a ' + 'non-existant window client.', _a[CODES.UNABLE_TO_RESUBSCRIBE] = 'There was an error while re-subscribing ' + 'the FCM token for push messaging. Will have to resubscribe the ' + 'user on next visit. {$message}', _a[CODES.NO_FCM_TOKEN_FOR_RESUBSCRIBE] = 'Could not find an FCM token ' + 'and as a result, unable to resubscribe. Will have to resubscribe the ' + 'user on next visit.', _a[CODES.FAILED_TO_DELETE_TOKEN] = 'Unable to delete the currently saved token.', _a[CODES.NO_SW_IN_REG] = 'Even though the service worker registration was ' + 'successful, there was a problem accessing the service worker itself.', _a[CODES.INCORRECT_GCM_SENDER_ID] = 'Please change your web app manifest\\'s ' + '\\'gcm_sender_id\\' value to \\'103953800507\\' to use Firebase messaging.', _a[CODES.BAD_SCOPE] = 'The service worker scope must be a string with at ' + 'least one character.', _a[CODES.BAD_VAPID_KEY] = 'The public VAPID key must be a string with at ' + 'least one character.', _a[CODES.BAD_SUBSCRIPTION] = 'The subscription must be a valid ' + 'PushSubscription.', _a[CODES.BAD_TOKEN] = 'The FCM Token used for storage / lookup was not ' + 'a valid token string.', _a[CODES.BAD_PUSH_SET] = 'The FCM push set used for storage / lookup was not ' + 'not a valid push set string.', _a[CODES.FAILED_DELETE_VAPID_KEY] = 'The VAPID key could not be deleted.', _a);\n/* harmony default export */ var errors_defaultExport = ({\n codes: CODES,\n map: ERROR_MAP\n});\nvar _a;\n// CONCATENATED MODULE: ./src/messaging/helpers/array-buffer-to-base64.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\nfunction toBase64(arrayBuffer) {\n var uint8Version = new Uint8Array(arrayBuffer);\n return window.btoa(String.fromCharCode.apply(null, uint8Version));\n}\n/* harmony default export */ var array_buffer_to_base64_defaultExport = (function (arrayBuffer) {\n var base64String = toBase64(arrayBuffer);\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n});;\n// CONCATENATED MODULE: ./src/messaging/models/fcm-details.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\nvar FCM_APPLICATION_SERVER_KEY = [0x04, 0x33, 0x94, 0xF7, 0xDF, 0xA1, 0xEB, 0xB1, 0xDC, 0x03, 0xA2, 0x5E, 0x15, 0x71, 0xDB, 0x48, 0xD3, 0x2E, 0xED, 0xED, 0xB2, 0x34, 0xDB, 0xB7, 0x47, 0x3A, 0x0C, 0x8F, 0xC4, 0xCC, 0xE1, 0x6F, 0x3C, 0x8C, 0x84, 0xDF, 0xAB, 0xB6, 0x66, 0x3E, 0xF2, 0x0C, 0xD4, 0x8B, 0xFE, 0xE3, 0xF9, 0x76, 0x2F, 0x14, 0x1C, 0x63, 0x08, 0x6A, 0x6F, 0x2D, 0xB1, 0x1A, 0x95, 0xB0, 0xCE, 0x37, 0xC0, 0x9C, 0x6E];\nvar SUBSCRIPTION_DETAILS = {\n 'userVisibleOnly': true,\n 'applicationServerKey': new Uint8Array(FCM_APPLICATION_SERVER_KEY)\n};\n/* harmony default export */ var fcm_details_defaultExport = ({\n ENDPOINT: 'https://fcm.googleapis.com',\n APPLICATION_SERVER_KEY: FCM_APPLICATION_SERVER_KEY,\n SUBSCRIPTION_OPTIONS: SUBSCRIPTION_DETAILS\n});\n// CONCATENATED MODULE: ./src/messaging/models/token-manager.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__app_errors__ = __webpack_require__(10);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\nvar FCM_TOKEN_DETAILS_DB = 'fcm_token_details_db';\nvar FCM_TOKEN_OBJ_STORE = 'fcm_token_object_Store';\nvar FCM_TOKEN_DETAILS_DB_VERSION = 1;\nvar token_manager_TokenManager = function () {\n function TokenManager() {\n this.errorFactory_ = new __WEBPACK_IMPORTED_MODULE_0__app_errors__[\"a\" /* ErrorFactory */]('messaging', 'Messaging', errors_defaultExport.map);\n this.openDbPromise_ = null;\n }\n /**\r\n * Get the indexedDB as a promsie.\r\n * @private\r\n * @return {Promise} The IndexedDB database\r\n */\n TokenManager.prototype.openDatabase_ = function () {\n if (this.openDbPromise_) {\n return this.openDbPromise_;\n }\n this.openDbPromise_ = new Promise(function (resolve, reject) {\n var request = indexedDB.open(FCM_TOKEN_DETAILS_DB, FCM_TOKEN_DETAILS_DB_VERSION);\n request.onerror = function (event) {\n reject(event.target.error);\n };\n request.onsuccess = function (event) {\n resolve(event.target.result);\n };\n request.onupgradeneeded = function (event) {\n var db = event.target.result;\n var objectStore = db.createObjectStore(FCM_TOKEN_OBJ_STORE, {\n keyPath: 'swScope'\n });\n // Make sure the sender ID can be searched\n objectStore.createIndex('fcmSenderId', 'fcmSenderId', {\n unique: false\n });\n objectStore.createIndex('fcmToken', 'fcmToken', {\n unique: true\n });\n };\n });\n return this.openDbPromise_;\n };\n /**\r\n * Close the currently open database.\r\n * @return {Promise} Returns the result of the promise chain.\r\n */\n TokenManager.prototype.closeDatabase = function () {\n var _this = this;\n if (this.openDbPromise_) {\n return this.openDbPromise_.then(function (db) {\n db.close();\n _this.openDbPromise_ = null;\n });\n }\n return Promise.resolve();\n };\n /**\r\n * Given a token, this method will look up the details in indexedDB.\r\n * @public\r\n * @param {string} fcmToken\r\n * @return {Promise} The details associated with that token.\r\n */\n TokenManager.prototype.getTokenDetailsFromToken = function (fcmToken) {\n return this.openDatabase_().then(function (db) {\n return new Promise(function (resolve, reject) {\n var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);\n var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n var index = objectStore.index('fcmToken');\n var request = index.get(fcmToken);\n request.onerror = function (event) {\n reject(event.target.error);\n };\n request.onsuccess = function (event) {\n resolve(event.target.result);\n };\n });\n });\n };\n TokenManager.prototype.getTokenDetailsFromSWScope_ = function (swScope) {\n return this.openDatabase_().then(function (db) {\n return new Promise(function (resolve, reject) {\n var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);\n var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n var scopeRequest = objectStore.get(swScope);\n scopeRequest.onerror = function (event) {\n reject(event.target.error);\n };\n scopeRequest.onsuccess = function (event) {\n resolve(event.target.result);\n };\n });\n });\n };\n TokenManager.prototype.getAllTokenDetailsForSenderId_ = function (senderId) {\n return this.openDatabase_().then(function (db) {\n return new Promise(function (resolve, reject) {\n var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);\n var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n var senderIdTokens = [];\n var cursorRequest = objectStore.openCursor();\n cursorRequest.onerror = function (event) {\n reject(event.target.error);\n };\n cursorRequest.onsuccess = function (event) {\n var cursor = event.target.result;\n if (cursor) {\n if (cursor.value['fcmSenderId'] === senderId) {\n senderIdTokens.push(cursor.value);\n }\n cursor.continue();\n } else {\n resolve(senderIdTokens);\n }\n };\n });\n });\n };\n /**\r\n * Given a PushSubscription and messagingSenderId, get an FCM token.\r\n * @public\r\n * @param {string} senderId The 'messagingSenderId' to tie the token to.\r\n * @param {PushSubscription} subscription The PushSusbcription to \"federate\".\r\n * @param {string=} pushSet If defined this will swap the subscription for\r\n * matching FCM token.\r\n * @return {Promise} Returns the FCM token to be used in place\r\n * of the PushSubscription.\r\n */\n TokenManager.prototype.subscribeToFCM = function (senderId, subscription, pushSet) {\n var _this = this;\n var p256dh = array_buffer_to_base64_defaultExport(subscription['getKey']('p256dh'));\n var auth = array_buffer_to_base64_defaultExport(subscription['getKey']('auth'));\n var fcmSubscribeBody = \"authorized_entity=\" + senderId + \"&\" + (\"endpoint=\" + subscription.endpoint + \"&\") + (\"encryption_key=\" + p256dh + \"&\") + (\"encryption_auth=\" + auth);\n if (pushSet) {\n fcmSubscribeBody += \"&pushSet=\" + pushSet;\n }\n var headers = new Headers();\n headers.append('Content-Type', 'application/x-www-form-urlencoded');\n var subscribeOptions = {\n method: 'POST',\n headers: headers,\n body: fcmSubscribeBody\n };\n return fetch(fcm_details_defaultExport.ENDPOINT + '/fcm/connect/subscribe', subscribeOptions).then(function (response) {\n return response.json();\n }).then(function (response) {\n var fcmTokenResponse = response;\n if (fcmTokenResponse['error']) {\n var message = fcmTokenResponse['error']['message'];\n throw _this.errorFactory_.create(errors_defaultExport.codes.TOKEN_SUBSCRIBE_FAILED, { 'message': message });\n }\n if (!fcmTokenResponse['token']) {\n throw _this.errorFactory_.create(errors_defaultExport.codes.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n if (!fcmTokenResponse['pushSet']) {\n throw _this.errorFactory_.create(errors_defaultExport.codes.TOKEN_SUBSCRIBE_NO_PUSH_SET);\n }\n return {\n 'token': fcmTokenResponse['token'],\n 'pushSet': fcmTokenResponse['pushSet']\n };\n });\n };\n /**\r\n * Checks the that fields in the PushSubscription are equivalent to the\r\n * details stores in the masterTokenDetails.\r\n * @private\r\n * @param {PushSubscription} subscription The push subscription we expect\r\n * the master token to match.\r\n * @param {Object} masterTokenDetails The saved details we wish to compare\r\n * with the PushSubscription\r\n * @return {boolean} true if the subscription and token details are\r\n * equivalent.\r\n */\n TokenManager.prototype.isSameSubscription_ = function (subscription, masterTokenDetails) {\n // getKey() isn't defined in the PushSubscription externs file, hence\n // subscription['getKey']('').\n return subscription.endpoint === masterTokenDetails['endpoint'] && array_buffer_to_base64_defaultExport(subscription['getKey']('auth')) === masterTokenDetails['auth'] && array_buffer_to_base64_defaultExport(subscription['getKey']('p256dh')) === masterTokenDetails['p256dh'];\n };\n /**\r\n * Save the details for the fcm token for re-use at a later date.\r\n * @private\r\n * @param {string} senderId The 'messagingSenderId' used for this project\r\n * @param {ServiceWorkerRegistration} swRegistration The service worker\r\n * used to subscribe the user for web push\r\n * @param {PushSubscription} subscription The push subscription passed to\r\n * FCM for the current token.\r\n * @param {string} fcmToken The FCM token currently used on this\r\n * device.\r\n * @param {string} fcmPushSet The FCM push tied to the fcm token.\r\n * @return {Promise}\r\n */\n TokenManager.prototype.saveTokenDetails_ = function (senderId, swRegistration, subscription, fcmToken, fcmPushSet) {\n var details = {\n 'swScope': swRegistration.scope,\n 'endpoint': subscription.endpoint,\n 'auth': array_buffer_to_base64_defaultExport(subscription['getKey']('auth')),\n 'p256dh': array_buffer_to_base64_defaultExport(subscription['getKey']('p256dh')),\n 'fcmToken': fcmToken,\n 'fcmPushSet': fcmPushSet,\n 'fcmSenderId': senderId\n };\n return this.openDatabase_().then(function (db) {\n return new Promise(function (resolve, reject) {\n var transaction = db.transaction([FCM_TOKEN_OBJ_STORE], 'readwrite');\n var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n var request = objectStore.put(details);\n request.onerror = function (event) {\n reject(event.target.error);\n };\n request.onsuccess = function (event) {\n resolve();\n };\n });\n });\n };\n /**\r\n * Returns the saved FCM Token if one is available and still valid,\r\n * otherwise `null` is returned.\r\n * @param {string} senderId This should be the sender ID associated with the\r\n * FCM Token being retrieved.\r\n * @param {ServiceWorkerRegistration} swRegistration Registration to be used\r\n * to subscribe the user to push.\r\n * @return {Promise | Promise} Returns the saved FCM Token if\r\n * avilable and valid.\r\n * @export\r\n */\n TokenManager.prototype.getSavedToken = function (senderId, swRegistration) {\n var _this = this;\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.SW_REGISTRATION_EXPECTED));\n }\n if (typeof senderId !== 'string' || senderId.length === 0) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.BAD_SENDER_ID));\n }\n return this.getAllTokenDetailsForSenderId_(senderId).then(function (allTokenDetails) {\n if (allTokenDetails.length === 0) {\n return;\n }\n var index = allTokenDetails.findIndex(function (tokenDetails) {\n return swRegistration.scope === tokenDetails['swScope'] && senderId === tokenDetails['fcmSenderId'];\n });\n if (index === -1) {\n return;\n }\n return allTokenDetails[index];\n }).then(function (tokenDetails) {\n if (!tokenDetails) {\n return;\n }\n return swRegistration.pushManager.getSubscription().catch(function (err) {\n throw _this.errorFactory_.create(errors_defaultExport.codes.GET_SUBSCRIPTION_FAILED);\n }).then(function (subscription) {\n if (subscription && _this.isSameSubscription_(subscription, tokenDetails)) {\n return tokenDetails['fcmToken'];\n }\n });\n });\n };\n /**\r\n * Creates a new FCM token.\r\n */\n TokenManager.prototype.createToken = function (senderId, swRegistration) {\n var _this = this;\n if (typeof senderId !== 'string' || senderId.length === 0) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.BAD_SENDER_ID));\n }\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.SW_REGISTRATION_EXPECTED));\n }\n // Check for existing subscription first\n var subscription;\n var fcmTokenDetails;\n return swRegistration.pushManager.getSubscription().then(function (subscription) {\n if (subscription) {\n return subscription;\n }\n return swRegistration.pushManager.subscribe(fcm_details_defaultExport.SUBSCRIPTION_OPTIONS);\n }).then(function (sub) {\n subscription = sub;\n return _this.subscribeToFCM(senderId, subscription);\n }).then(function (tokenDetails) {\n fcmTokenDetails = tokenDetails;\n return _this.saveTokenDetails_(senderId, swRegistration, subscription, fcmTokenDetails['token'], fcmTokenDetails['pushSet']);\n }).then(function () {\n return fcmTokenDetails['token'];\n });\n };\n /**\r\n * This method deletes details of the current FCM token.\r\n * It's returning a promise in case we need to move to an async\r\n * method for deleting at a later date.\r\n * @param {string} token Token to be deleted\r\n * @return {Promise} Resolves once the FCM token details have been\r\n * deleted and returns the deleted details.\r\n */\n TokenManager.prototype.deleteToken = function (token) {\n var _this = this;\n if (typeof token !== 'string' || token.length === 0) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.INVALID_DELETE_TOKEN));\n }\n return this.getTokenDetailsFromToken(token).then(function (details) {\n if (!details) {\n throw _this.errorFactory_.create(errors_defaultExport.codes.DELETE_TOKEN_NOT_FOUND);\n }\n return _this.openDatabase_().then(function (db) {\n return new Promise(function (resolve, reject) {\n var transaction = db.transaction([FCM_TOKEN_OBJ_STORE], 'readwrite');\n var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n var request = objectStore.delete(details['swScope']);\n request.onerror = function (event) {\n reject(event.target.error);\n };\n request.onsuccess = function (event) {\n if (event.target.result === 0) {\n reject(_this.errorFactory_.create(errors_defaultExport.codes.FAILED_TO_DELETE_TOKEN));\n return;\n }\n resolve(details);\n };\n });\n });\n });\n };\n return TokenManager;\n}();\n/* harmony default export */ var token_manager_defaultExport = (token_manager_TokenManager);\n// CONCATENATED MODULE: ./src/messaging/models/notification-permission.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n/* harmony default export */ var notification_permission_defaultExport = ({\n granted: 'granted',\n default: 'default',\n denied: 'denied'\n});\n// CONCATENATED MODULE: ./src/messaging/controllers/controller-interface.ts\n/* harmony import */ var controller_interface___WEBPACK_IMPORTED_MODULE_0__app_errors__ = __webpack_require__(10);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\nvar SENDER_ID_OPTION_NAME = 'messagingSenderId';\nvar controller_interface_ControllerInterface = function () {\n /**\r\n * An interface of the Messaging Service API\r\n * @param {!firebase.app.App} app\r\n */\n function ControllerInterface(app) {\n var _this = this;\n this.errorFactory_ = new controller_interface___WEBPACK_IMPORTED_MODULE_0__app_errors__[\"a\" /* ErrorFactory */]('messaging', 'Messaging', errors_defaultExport.map);\n if (!app.options[SENDER_ID_OPTION_NAME] || typeof app.options[SENDER_ID_OPTION_NAME] !== 'string') {\n throw this.errorFactory_.create(errors_defaultExport.codes.BAD_SENDER_ID);\n }\n this.messagingSenderId_ = app.options[SENDER_ID_OPTION_NAME];\n this.tokenManager_ = new token_manager_defaultExport();\n this.app = app;\n this.INTERNAL = {};\n this.INTERNAL.delete = function () {\n return _this.delete;\n };\n }\n /**\r\n * @export\r\n * @return {Promise | Promise} Returns a promise that\r\n * resolves to an FCM token.\r\n */\n ControllerInterface.prototype.getToken = function () {\n var _this = this;\n // Check with permissions\n var currentPermission = this.getNotificationPermission_();\n if (currentPermission !== notification_permission_defaultExport.granted) {\n if (currentPermission === notification_permission_defaultExport.denied) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.NOTIFICATIONS_BLOCKED));\n }\n // We must wait for permission to be granted\n return Promise.resolve(null);\n }\n return this.getSWRegistration_().then(function (registration) {\n return _this.tokenManager_.getSavedToken(_this.messagingSenderId_, registration).then(function (token) {\n if (token) {\n return token;\n }\n return _this.tokenManager_.createToken(_this.messagingSenderId_, registration);\n });\n });\n };\n /**\r\n * This method deletes tokens that the token manager looks after and then\r\n * unregisters the push subscription if it exists.\r\n * @export\r\n * @param {string} token\r\n * @return {Promise}\r\n */\n ControllerInterface.prototype.deleteToken = function (token) {\n var _this = this;\n return this.tokenManager_.deleteToken(token).then(function () {\n return _this.getSWRegistration_().then(function (registration) {\n if (registration) {\n return registration.pushManager.getSubscription();\n }\n }).then(function (subscription) {\n if (subscription) {\n return subscription.unsubscribe();\n }\n });\n });\n };\n ControllerInterface.prototype.getSWRegistration_ = function () {\n throw this.errorFactory_.create(errors_defaultExport.codes.SHOULD_BE_INHERITED);\n };\n //\n // The following methods should only be available in the window.\n //\n ControllerInterface.prototype.requestPermission = function () {\n throw this.errorFactory_.create(errors_defaultExport.codes.AVAILABLE_IN_WINDOW);\n };\n /**\r\n * @export\r\n * @param {!ServiceWorkerRegistration} registration\r\n */\n ControllerInterface.prototype.useServiceWorker = function (registration) {\n throw this.errorFactory_.create(errors_defaultExport.codes.AVAILABLE_IN_WINDOW);\n };\n /**\r\n * @export\r\n * @param {!firebase.Observer|function(*)} nextOrObserver\r\n * @param {function(!Error)=} optError\r\n * @param {function()=} optCompleted\r\n * @return {!function()}\r\n */\n ControllerInterface.prototype.onMessage = function (nextOrObserver, optError, optCompleted) {\n throw this.errorFactory_.create(errors_defaultExport.codes.AVAILABLE_IN_WINDOW);\n };\n /**\r\n * @export\r\n * @param {!firebase.Observer|function()} nextOrObserver An observer object\r\n * or a function triggered on token refresh.\r\n * @param {function(!Error)=} optError Optional A function\r\n * triggered on token refresh error.\r\n * @param {function()=} optCompleted Optional function triggered when the\r\n * observer is removed.\r\n * @return {!function()} The unsubscribe function for the observer.\r\n */\n ControllerInterface.prototype.onTokenRefresh = function (nextOrObserver, optError, optCompleted) {\n throw this.errorFactory_.create(errors_defaultExport.codes.AVAILABLE_IN_WINDOW);\n };\n //\n // The following methods are used by the service worker only.\n //\n /**\r\n * @export\r\n * @param {function(Object)} callback\r\n */\n ControllerInterface.prototype.setBackgroundMessageHandler = function (callback) {\n throw this.errorFactory_.create(errors_defaultExport.codes.AVAILABLE_IN_SW);\n };\n //\n // The following methods are used by the service themselves and not exposed\n // publicly or not expected to be used by developers.\n //\n /**\r\n * This method is required to adhere to the Firebase interface.\r\n * It closes any currently open indexdb database connections.\r\n */\n ControllerInterface.prototype.delete = function () {\n this.tokenManager_.closeDatabase();\n };\n /**\r\n * Returns the current Notification Permission state.\r\n * @private\r\n * @return {string} The currenct permission state.\r\n */\n ControllerInterface.prototype.getNotificationPermission_ = function () {\n return Notification.permission;\n };\n /**\r\n * @protected\r\n * @returns {TokenManager}\r\n */\n ControllerInterface.prototype.getTokenManager = function () {\n return this.tokenManager_;\n };\n return ControllerInterface;\n}();\n/* harmony default export */ var controller_interface_defaultExport = (controller_interface_ControllerInterface);\n// CONCATENATED MODULE: ./src/messaging/models/worker-page-message.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n// These fields are strings to prevent closure from thinking goog.getMsg\n// should be used to initialise the values\n\nvar PARAMS = {\n TYPE_OF_MSG: 'firebase-messaging-msg-type',\n DATA: 'firebase-messaging-msg-data'\n};\n// This value isn't using the TYPE_OF_MSG short hand as closure\n// expects the variable to be defined via goog.getMsg\nvar msgType = {\n PUSH_MSG_RECEIVED: 'push-msg-received',\n NOTIFICATION_CLICKED: 'notification-clicked'\n};\nvar createNewMsg = function createNewMsg(msgType, msgData) {\n var message = (_a = {}, _a[PARAMS.TYPE_OF_MSG] = msgType, _a[PARAMS.DATA] = msgData, _a);\n return message;\n var _a;\n};\n/* harmony default export */ var worker_page_message_defaultExport = ({\n PARAMS: PARAMS,\n TYPES_OF_MSG: msgType,\n createNewMsg: createNewMsg\n});\n// CONCATENATED MODULE: ./src/messaging/models/default-sw.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n/* harmony default export */ var default_sw_defaultExport = ({\n path: '/firebase-messaging-sw.js',\n scope: '/firebase-cloud-messaging-push-scope'\n});\n// CONCATENATED MODULE: ./src/messaging/controllers/window-controller.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__app_subscribe__ = __webpack_require__(13);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\nvar __extends = this && this.__extends || function () {\n var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (b.hasOwnProperty(p)) d[p] = b[p];\n }\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\nvar window_controller_WindowController = function (_super) {\n __extends(WindowController, _super);\n /**\r\n * A service that provides a MessagingService instance.\r\n * @param {!firebase.app.App} app\r\n */\n function WindowController(app) {\n var _this = _super.call(this, app) || this;\n /**\r\n * @private\r\n * @type {ServiceWorkerRegistration}\r\n */\n _this.registrationToUse_;\n /**\r\n * @private\r\n * @type {Promise}\r\n */\n _this.manifestCheckPromise_;\n /**\r\n * @private\r\n * @type {firebase.Observer}\r\n */\n _this.messageObserver_ = null;\n /**\r\n * @private {!firebase.Subscribe} The subscribe function to the onMessage\r\n * observer.\r\n */\n _this.onMessage_ = __WEBPACK_IMPORTED_MODULE_5__app_subscribe__[\"a\" /* createSubscribe */](function (observer) {\n _this.messageObserver_ = observer;\n });\n /**\r\n * @private\r\n * @type {firebase.Observer}\r\n */\n _this.tokenRefreshObserver_ = null;\n _this.onTokenRefresh_ = __WEBPACK_IMPORTED_MODULE_5__app_subscribe__[\"a\" /* createSubscribe */](function (observer) {\n _this.tokenRefreshObserver_ = observer;\n });\n _this.setupSWMessageListener_();\n return _this;\n }\n /**\r\n * This method returns an FCM token if it can be generated.\r\n * The return promise will reject if the browser doesn't support\r\n * FCM, if permission is denied for notifications or it's not\r\n * possible to generate a token.\r\n * @export\r\n * @return {Promise | Promise} Returns a promise the\r\n * resolves to an FCM token or null if permission isn't granted.\r\n */\n WindowController.prototype.getToken = function () {\n var _this = this;\n // Check that the required API's are available\n if (!this.isSupported_()) {\n return Promise.reject(this.errorFactory_.create(errors_defaultExport.codes.UNSUPPORTED_BROWSER));\n }\n return this.manifestCheck_().then(function () {\n return _super.prototype.getToken.call(_this);\n });\n };\n /**\r\n * The method checks that a manifest is defined and has the correct GCM\r\n * sender ID.\r\n * @private\r\n * @return {Promise} Returns a promise that resolves if the manifest matches\r\n * our required sender ID\r\n */\n WindowController.prototype.manifestCheck_ = function () {\n var _this = this;\n if (this.manifestCheckPromise_) {\n return this.manifestCheckPromise_;\n }\n var manifestTag = document.querySelector('link[rel=\"manifest\"]');\n if (!manifestTag) {\n this.manifestCheckPromise_ = Promise.resolve();\n } else {\n this.manifestCheckPromise_ = fetch(manifestTag.href).then(function (response) {\n return response.json();\n }).catch(function () {\n // If the download or parsing fails allow check.\n // We only want to error if we KNOW that the gcm_sender_id is incorrect.\n return Promise.resolve();\n }).then(function (manifestContent) {\n if (!manifestContent) {\n return;\n }\n if (!manifestContent['gcm_sender_id']) {\n return;\n }\n if (manifestContent['gcm_sender_id'] !== '103953800507') {\n throw _this.errorFactory_.create(errors_defaultExport.codes.INCORRECT_GCM_SENDER_ID);\n }\n });\n }\n return this.manifestCheckPromise_;\n };\n /**\r\n * Request permission if it is not currently granted\r\n * @export\r\n * @returns {Promise} Resolves if the permission was granted, otherwise\r\n * rejects\r\n */\n WindowController.prototype.requestPermission = function () {\n var _this = this;\n if (Notification.permission === notification_permission_defaultExport.granted) {\n return Promise.resolve();\n }\n return new Promise(function (resolve, reject) {\n var managePermissionResult = function managePermissionResult(result) {\n if (result === notification_permission_defaultExport.granted) {\n return resolve();\n } else if (result === notification_permission_defaultExport.denied) {\n return reject(_this.errorFactory_.create(errors_defaultExport.codes.PERMISSION_BLOCKED));\n } else {\n return reject(_this.errorFactory_.create(errors_defaultExport.codes.PERMISSION_DEFAULT));\n }\n };\n // The Notification.requestPermission API was changed to\n // return a promise so now have to handle both in case\n // browsers stop support callbacks for promised version\n var permissionPromise = Notification.requestPermission(function (result) {\n if (permissionPromise) {\n // Let the promise manage this\n return;\n }\n managePermissionResult(result);\n });\n if (permissionPromise) {\n // Prefer the promise version as it's the future API.\n permissionPromise.then(managePermissionResult);\n }\n });\n };\n /**\r\n * This method allows a developer to override the default service worker and\r\n * instead use a custom service worker.\r\n * @export\r\n * @param {!ServiceWorkerRegistration} registration The service worker\r\n * registration that should be used to receive the push messages.\r\n */\n WindowController.prototype.useServiceWorker = function (registration) {\n if (!(registration instanceof ServiceWorkerRegistration)) {\n throw this.errorFactory_.create(errors_defaultExport.codes.SW_REGISTRATION_EXPECTED);\n }\n if (typeof this.registrationToUse_ !== 'undefined') {\n throw this.errorFactory_.create(errors_defaultExport.codes.USE_SW_BEFORE_GET_TOKEN);\n }\n this.registrationToUse_ = registration;\n };\n /**\r\n * @export\r\n * @param {!firebase.Observer|function(*)} nextOrObserver An observer object\r\n * or a function triggered on message.\r\n * @param {function(!Error)=} optError Optional A function triggered on\r\n * message error.\r\n * @param {function()=} optCompleted Optional function triggered when the\r\n * observer is removed.\r\n * @return {!function()} The unsubscribe function for the observer.\r\n */\n WindowController.prototype.onMessage = function (nextOrObserver, optError, optCompleted) {\n return this.onMessage_(nextOrObserver, optError, optCompleted);\n };\n /**\r\n * @export\r\n * @param {!firebase.Observer|function()} nextOrObserver An observer object\r\n * or a function triggered on token refresh.\r\n * @param {function(!Error)=} optError Optional A function\r\n * triggered on token refresh error.\r\n * @param {function()=} optCompleted Optional function triggered when the\r\n * observer is removed.\r\n * @return {!function()} The unsubscribe function for the observer.\r\n */\n WindowController.prototype.onTokenRefresh = function (nextOrObserver, optError, optCompleted) {\n return this.onTokenRefresh_(nextOrObserver, optError, optCompleted);\n };\n /**\r\n * Given a registration, wait for the service worker it relates to\r\n * become activer\r\n * @private\r\n * @param {ServiceWorkerRegistration} registration Registration to wait\r\n * for service worker to become active\r\n * @return {Promise} Wait for service worker\r\n * registration to become active\r\n */\n WindowController.prototype.waitForRegistrationToActivate_ = function (registration) {\n var _this = this;\n var serviceWorker = registration.installing || registration.waiting || registration.active;\n return new Promise(function (resolve, reject) {\n if (!serviceWorker) {\n // This is a rare scenario but has occured in firefox\n reject(_this.errorFactory_.create(errors_defaultExport.codes.NO_SW_IN_REG));\n return;\n }\n // Because the Promise function is called on next tick there is a\n // small chance that the worker became active or redundant already.\n if (serviceWorker.state === 'activated') {\n resolve(registration);\n return;\n }\n if (serviceWorker.state === 'redundant') {\n reject(_this.errorFactory_.create(errors_defaultExport.codes.SW_REG_REDUNDANT));\n return;\n }\n var stateChangeListener = function stateChangeListener() {\n if (serviceWorker.state === 'activated') {\n resolve(registration);\n } else if (serviceWorker.state === 'redundant') {\n reject(_this.errorFactory_.create(errors_defaultExport.codes.SW_REG_REDUNDANT));\n } else {\n // Return early and wait to next state change\n return;\n }\n serviceWorker.removeEventListener('statechange', stateChangeListener);\n };\n serviceWorker.addEventListener('statechange', stateChangeListener);\n });\n };\n /**\r\n * This will regiater the default service worker and return the registration\r\n * @private\r\n * @return {Promise} The service worker\r\n * registration to be used for the push service.\r\n */\n WindowController.prototype.getSWRegistration_ = function () {\n var _this = this;\n if (this.registrationToUse_) {\n return this.waitForRegistrationToActivate_(this.registrationToUse_);\n }\n // Make the registration null so we know useServiceWorker will not\n // use a new service worker as registrationToUse_ is no longer undefined\n this.registrationToUse_ = null;\n return navigator.serviceWorker.register(default_sw_defaultExport.path, {\n scope: default_sw_defaultExport.scope\n }).catch(function (err) {\n throw _this.errorFactory_.create(errors_defaultExport.codes.FAILED_DEFAULT_REGISTRATION, {\n 'browserErrorMessage': err.message\n });\n }).then(function (registration) {\n return _this.waitForRegistrationToActivate_(registration).then(function () {\n _this.registrationToUse_ = registration;\n // We update after activation due to an issue with Firefox v49 where\n // a race condition occassionally causes the service work to not\n // install\n registration.update();\n return registration;\n });\n });\n };\n /**\r\n * This method will set up a message listener to handle\r\n * events from the service worker that should trigger\r\n * events in the page.\r\n *\r\n * @private\r\n */\n WindowController.prototype.setupSWMessageListener_ = function () {\n var _this = this;\n if (!('serviceWorker' in navigator)) {\n return;\n }\n navigator.serviceWorker.addEventListener('message', function (event) {\n if (!event.data || !event.data[worker_page_message_defaultExport.PARAMS.TYPE_OF_MSG]) {\n // Not a message from FCM\n return;\n }\n var workerPageMessage = event.data;\n switch (workerPageMessage[worker_page_message_defaultExport.PARAMS.TYPE_OF_MSG]) {\n case worker_page_message_defaultExport.TYPES_OF_MSG.PUSH_MSG_RECEIVED:\n case worker_page_message_defaultExport.TYPES_OF_MSG.NOTIFICATION_CLICKED:\n var pushMessage = workerPageMessage[worker_page_message_defaultExport.PARAMS.DATA];\n _this.messageObserver_.next(pushMessage);\n break;\n default:\n // Noop.\n break;\n }\n }, false);\n };\n /**\r\n * Checks to see if the required API's are valid or not.\r\n * @private\r\n * @return {boolean} Returns true if the desired APIs are available.\r\n */\n WindowController.prototype.isSupported_ = function () {\n return 'serviceWorker' in navigator && 'PushManager' in window && 'Notification' in window && 'fetch' in window && ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') && PushSubscription.prototype.hasOwnProperty('getKey');\n };\n return WindowController;\n}(controller_interface_defaultExport);\n/* harmony default export */ var window_controller_defaultExport = (window_controller_WindowController);\n// CONCATENATED MODULE: ./src/messaging/controllers/sw-controller.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar sw_controller___extends = this && this.__extends || function () {\n var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (b.hasOwnProperty(p)) d[p] = b[p];\n }\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\nvar FCM_MSG = 'FCM_MSG';\nvar sw_controller_SWController = function (_super) {\n sw_controller___extends(SWController, _super);\n function SWController(app) {\n var _this = _super.call(this, app) || this;\n self.addEventListener('push', function (e) {\n return _this.onPush_(e);\n }, false);\n self.addEventListener('pushsubscriptionchange', function (e) {\n return _this.onSubChange_(e);\n }, false);\n self.addEventListener('notificationclick', function (e) {\n return _this.onNotificationClick_(e);\n }, false);\n /**\r\n * @private\r\n * @type {function(Object)|null}\r\n */\n _this.bgMessageHandler_ = null;\n return _this;\n }\n /**\r\n * A handler for push events that shows notifications based on the content of\r\n * the payload.\r\n *\r\n * The payload must be a JSON-encoded Object with a `notification` key. The\r\n * value of the `notification` property will be used as the NotificationOptions\r\n * object passed to showNotification. Additionally, the `title` property of the\r\n * notification object will be used as the title.\r\n *\r\n * If there is no notification data in the payload then no notification will be\r\n * shown.\r\n * @private\r\n */\n SWController.prototype.onPush_ = function (event) {\n var _this = this;\n var msgPayload;\n try {\n msgPayload = event.data.json();\n } catch (err) {\n // Not JSON so not an FCM message\n return;\n }\n var handleMsgPromise = this.hasVisibleClients_().then(function (hasVisibleClients) {\n if (hasVisibleClients) {\n // Do not need to show a notification.\n if (msgPayload.notification || _this.bgMessageHandler_) {\n // Send to page\n return _this.sendMessageToWindowClients_(msgPayload);\n }\n return;\n }\n var notificationDetails = _this.getNotificationData_(msgPayload);\n if (notificationDetails) {\n var notificationTitle = notificationDetails.title || '';\n return self.registration.showNotification(notificationTitle, notificationDetails);\n } else if (_this.bgMessageHandler_) {\n return _this.bgMessageHandler_(msgPayload);\n }\n });\n event.waitUntil(handleMsgPromise);\n };\n /**\r\n * @private\r\n */\n SWController.prototype.onSubChange_ = function (event) {\n var _this = this;\n var promiseChain = this.getToken().then(function (token) {\n if (!token) {\n // We can't resubscribe if we don't have an FCM token for this scope.\n throw _this.errorFactory_.create(errors_defaultExport.codes.NO_FCM_TOKEN_FOR_RESUBSCRIBE);\n }\n var tokenDetails = null;\n var tokenManager = _this.getTokenManager();\n return tokenManager.getTokenDetailsFromToken(token).then(function (details) {\n tokenDetails = details;\n if (!tokenDetails) {\n throw _this.errorFactory_.create(errors_defaultExport.codes.INVALID_SAVED_TOKEN);\n }\n // Attempt to get a new subscription\n return self.registration.pushManager.subscribe(fcm_details_defaultExport.SUBSCRIPTION_OPTIONS);\n }).then(function (newSubscription) {\n // Send new subscription to FCM.\n return tokenManager.subscribeToFCM(tokenDetails.fcmSenderId, newSubscription, tokenDetails.fcmPushSet);\n }).catch(function (err) {\n // The best thing we can do is log this to the terminal so\n // developers might notice the error.\n return tokenManager.deleteToken(tokenDetails.fcmToken).then(function () {\n throw _this.errorFactory_.create(errors_defaultExport.codes.UNABLE_TO_RESUBSCRIBE, {\n 'message': err\n });\n });\n });\n });\n event.waitUntil(promiseChain);\n };\n /**\r\n * @private\r\n */\n SWController.prototype.onNotificationClick_ = function (event) {\n var _this = this;\n if (!(event.notification && event.notification.data && event.notification.data[FCM_MSG])) {\n // Not an FCM notification, do nothing.\n return;\n }\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n var msgPayload = event.notification.data[FCM_MSG];\n var clickAction = msgPayload['notification']['click_action'];\n if (!clickAction) {\n // Nothing to do.\n return;\n }\n var promiseChain = this.getWindowClient_(clickAction).then(function (windowClient) {\n if (!windowClient) {\n // Unable to find window client so need to open one.\n return self.clients.openWindow(clickAction);\n }\n return windowClient;\n }).then(function (windowClient) {\n if (!windowClient) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n // Delete notification data from payload before sending to the page.\n var notificationData = msgPayload['notification'];\n delete msgPayload['notification'];\n var internalMsg = worker_page_message_defaultExport.createNewMsg(worker_page_message_defaultExport.TYPES_OF_MSG.NOTIFICATION_CLICKED, msgPayload);\n // Attempt to send a message to the client to handle the data\n // Is affected by: https://github.com/slightlyoff/ServiceWorker/issues/728\n return _this.attemptToMessageClient_(windowClient, internalMsg);\n });\n event.waitUntil(promiseChain);\n };\n /**\r\n * @private\r\n * @param {Object} msgPayload\r\n * @return {NotificationOptions|undefined}\r\n */\n SWController.prototype.getNotificationData_ = function (msgPayload) {\n if (!msgPayload) {\n return;\n }\n if (_typeof(msgPayload.notification) !== 'object') {\n return;\n }\n var notificationInformation = Object.assign({}, msgPayload.notification);\n // Put the message payload under FCM_MSG name so we can identify the\n // notification as being an FCM notification vs a notification from\n // somewhere else (i.e. normal web push or developer generated\n // notification).\n notificationInformation['data'] = (_a = {}, _a[FCM_MSG] = msgPayload, _a);\n return notificationInformation;\n var _a;\n };\n /**\r\n * Calling setBackgroundMessageHandler will opt in to some specific\r\n * behaviours.\r\n * 1.) If a notification doesn't need to be shown due to a window already\r\n * being visible, then push messages will be sent to the page.\r\n * 2.) If a notification needs to be shown, and the message contains no\r\n * notification data this method will be called\r\n * and the promise it returns will be passed to event.waitUntil.\r\n * If you do not set this callback then all push messages will let and the\r\n * developer can handle them in a their own 'push' event callback\r\n * @export\r\n * @param {function(Object)} callback The callback to be called when a push\r\n * message is received and a notification must be shown. The callback will\r\n * be given the data from the push message.\r\n */\n SWController.prototype.setBackgroundMessageHandler = function (callback) {\n if (callback && typeof callback !== 'function') {\n throw this.errorFactory_.create(errors_defaultExport.codes.BG_HANDLER_FUNCTION_EXPECTED);\n }\n this.bgMessageHandler_ = callback;\n };\n /**\r\n * @private\r\n * @param {string} url The URL to look for when focusing a client.\r\n * @return {Object} Returns an existing window client or a newly opened\r\n * WindowClient.\r\n */\n SWController.prototype.getWindowClient_ = function (url) {\n // Use URL to normalize the URL when comparing to windowClients.\n // This at least handles whether to include trailing slashes or not\n var parsedURL = new URL(url).href;\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n }).then(function (clientList) {\n var suitableClient = null;\n for (var i = 0; i < clientList.length; i++) {\n var parsedClientUrl = new URL(clientList[i].url).href;\n if (parsedClientUrl === parsedURL) {\n suitableClient = clientList[i];\n break;\n }\n }\n if (suitableClient) {\n suitableClient.focus();\n return suitableClient;\n }\n });\n };\n /**\r\n * This message will attempt to send the message to a window client.\r\n * @private\r\n * @param {Object} client The WindowClient to send the message to.\r\n * @param {Object} message The message to send to the client.\r\n * @returns {Promise} Returns a promise that resolves after sending the\r\n * message. This does not guarantee that the message was successfully\r\n * received.\r\n */\n SWController.prototype.attemptToMessageClient_ = function (client, message) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n if (!client) {\n return reject(_this.errorFactory_.create(errors_defaultExport.codes.NO_WINDOW_CLIENT_TO_MSG));\n }\n client.postMessage(message);\n resolve();\n });\n };\n /**\r\n * @private\r\n * @returns {Promise} If there is currently a visible WindowClient,\r\n * this method will resolve to true, otherwise false.\r\n */\n SWController.prototype.hasVisibleClients_ = function () {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n }).then(function (clientList) {\n return clientList.some(function (client) {\n return client.visibilityState === 'visible';\n });\n });\n };\n /**\r\n * @private\r\n * @param {Object} msgPayload The data from the push event that should be sent\r\n * to all available pages.\r\n * @returns {Promise} Returns a promise that resolves once the message\r\n * has been sent to all WindowClients.\r\n */\n SWController.prototype.sendMessageToWindowClients_ = function (msgPayload) {\n var _this = this;\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n }).then(function (clientList) {\n var internalMsg = worker_page_message_defaultExport.createNewMsg(worker_page_message_defaultExport.TYPES_OF_MSG.PUSH_MSG_RECEIVED, msgPayload);\n return Promise.all(clientList.map(function (client) {\n return _this.attemptToMessageClient_(client, internalMsg);\n }));\n });\n };\n /**\r\n * This will register the default service worker and return the registration.\r\n * @private\r\n * @return {Promise} The service worker\r\n * registration to be used for the push service.\r\n */\n SWController.prototype.getSWRegistration_ = function () {\n return Promise.resolve(self.registration);\n };\n return SWController;\n}(controller_interface_defaultExport);\n/* harmony default export */ var sw_controller_defaultExport = (sw_controller_SWController);\n// CONCATENATED MODULE: ./src/messaging.ts\n/* harmony export (immutable) */ __webpack_exports__[\"registerMessaging\"] = registerMessaging;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__app__ = __webpack_require__(5);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\nfunction registerMessaging(instance) {\n var messagingName = 'messaging';\n var factoryMethod = function factoryMethod(app) {\n if (self && 'ServiceWorkerGlobalScope' in self) {\n return new sw_controller_defaultExport(app);\n }\n // Assume we are in the window context.\n return new window_controller_defaultExport(app);\n };\n var namespaceExports = {\n // no-inline\n 'Messaging': window_controller_defaultExport\n };\n instance.INTERNAL.registerService(messagingName, factoryMethod, namespaceExports);\n}\nregisterMessaging(__WEBPACK_IMPORTED_MODULE_2__app__[\"default\"]);\n\n/***/ })\n\n},[23]);\n } catch(error) {\n throw new Error(\n 'Cannot instantiate firebase-messaging.js - ' +\n 'be sure to load firebase-app.js first.'\n )\n }\n\n\n// WEBPACK FOOTER //\n// firebase-messaging.js","/**\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*/\nfunction toBase64(arrayBuffer) {\n const uint8Version = new Uint8Array(arrayBuffer);\n return window.btoa(String.fromCharCode.apply(null, uint8Version));\n}\n\nexport default (arrayBuffer) => {\n const base64String = toBase64(arrayBuffer);\n return base64String.replace(/=/g, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/helpers/array-buffer-to-base64.ts","/**\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'use strict';\n\nimport WindowController from './messaging/controllers/window-controller';\nimport SWController from './messaging/controllers/sw-controller';\nimport firebase from './app';\n\nexport function registerMessaging(instance) {\n const messagingName = 'messaging';\n const factoryMethod = app => {\n if (self && 'ServiceWorkerGlobalScope' in self) {\n return new SWController(app);\n }\n\n // Assume we are in the window context.\n return new WindowController(app);\n };\n\n const namespaceExports = {\n // no-inline\n 'Messaging': WindowController\n };\n\n instance.INTERNAL.registerService(messagingName, factoryMethod, namespaceExports);\n}\n\nregisterMessaging(firebase);\n\n\n// WEBPACK FOOTER //\n// ./src/messaging.ts","/**\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'use strict';\n\nconst CODES = {\n AVAILABLE_IN_WINDOW: 'only-available-in-window',\n AVAILABLE_IN_SW: 'only-available-in-sw',\n SHOULD_BE_INHERITED: 'should-be-overriden',\n BAD_SENDER_ID: 'bad-sender-id',\n INCORRECT_GCM_SENDER_ID: 'incorrect-gcm-sender-id',\n PERMISSION_DEFAULT: 'permission-default',\n PERMISSION_BLOCKED: 'permission-blocked',\n UNSUPPORTED_BROWSER: 'unsupported-browser',\n NOTIFICATIONS_BLOCKED: 'notifications-blocked',\n FAILED_DEFAULT_REGISTRATION: 'failed-serviceworker-registration',\n SW_REGISTRATION_EXPECTED: 'sw-registration-expected',\n GET_SUBSCRIPTION_FAILED: 'get-subscription-failed',\n INVALID_SAVED_TOKEN: 'invalid-saved-token',\n SW_REG_REDUNDANT: 'sw-reg-redundant',\n TOKEN_SUBSCRIBE_FAILED: 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN: 'token-subscribe-no-token',\n TOKEN_SUBSCRIBE_NO_PUSH_SET: 'token-subscribe-no-push-set',\n USE_SW_BEFORE_GET_TOKEN: 'use-sw-before-get-token',\n INVALID_DELETE_TOKEN: 'invalid-delete-token',\n DELETE_TOKEN_NOT_FOUND: 'delete-token-not-found',\n DELETE_SCOPE_NOT_FOUND: 'delete-scope-not-found',\n BG_HANDLER_FUNCTION_EXPECTED: 'bg-handler-function-expected',\n NO_WINDOW_CLIENT_TO_MSG: 'no-window-client-to-msg',\n UNABLE_TO_RESUBSCRIBE: 'unable-to-resubscribe',\n NO_FCM_TOKEN_FOR_RESUBSCRIBE: 'no-fcm-token-for-resubscribe',\n FAILED_TO_DELETE_TOKEN: 'failed-to-delete-token',\n NO_SW_IN_REG: 'no-sw-in-reg',\n BAD_SCOPE: 'bad-scope',\n BAD_VAPID_KEY: 'bad-vapid-key',\n BAD_SUBSCRIPTION: 'bad-subscription',\n BAD_TOKEN: 'bad-token',\n BAD_PUSH_SET: 'bad-push-set',\n FAILED_DELETE_VAPID_KEY: 'failed-delete-vapid-key'\n};\n\nconst ERROR_MAP = {\n [CODES.AVAILABLE_IN_WINDOW]: 'This method is available in a Window context.',\n [CODES.AVAILABLE_IN_SW]: 'This method is available in a service worker ' +\n 'context.',\n [CODES.SHOULD_BE_INHERITED]: 'This method should be overriden by ' +\n 'extended classes.',\n [CODES.BAD_SENDER_ID]: 'Please ensure that \\'messagingSenderId\\' is set ' +\n 'correctly in the options passed into firebase.initializeApp().',\n [CODES.PERMISSION_DEFAULT]: 'The required permissions were not granted and ' +\n 'dismissed instead.',\n [CODES.PERMISSION_BLOCKED]: 'The required permissions were not granted and ' +\n 'blocked instead.',\n [CODES.UNSUPPORTED_BROWSER]: 'This browser doesn\\'t support the API\\'s ' +\n 'required to use the firebase SDK.',\n [CODES.NOTIFICATIONS_BLOCKED]: 'Notifications have been blocked.',\n [CODES.FAILED_DEFAULT_REGISTRATION]: 'We are unable to register the ' +\n 'default service worker. {$browserErrorMessage}',\n [CODES.SW_REGISTRATION_EXPECTED]: 'A service worker registration was the ' +\n 'expected input.',\n [CODES.GET_SUBSCRIPTION_FAILED]: 'There was an error when trying to get ' +\n 'any existing Push Subscriptions.',\n [CODES.INVALID_SAVED_TOKEN]: 'Unable to access details of the saved token.',\n [CODES.SW_REG_REDUNDANT]: 'The service worker being used for push was made ' +\n 'redundant.',\n [CODES.TOKEN_SUBSCRIBE_FAILED]: 'A problem occured while subscribing the ' +\n 'user to FCM: {$message}',\n [CODES.TOKEN_SUBSCRIBE_NO_TOKEN]: 'FCM returned no token when subscribing ' +\n 'the user to push.',\n [CODES.TOKEN_SUBSCRIBE_NO_PUSH_SET]: 'FCM returned an invalid response ' +\n 'when getting an FCM token.',\n [CODES.USE_SW_BEFORE_GET_TOKEN]: 'You must call useServiceWorker() before ' +\n 'calling getToken() to ensure your service worker is used.',\n [CODES.INVALID_DELETE_TOKEN]: 'You must pass a valid token into ' +\n 'deleteToken(), i.e. the token from getToken().',\n [CODES.DELETE_TOKEN_NOT_FOUND]: 'The deletion attempt for token could not ' +\n 'be performed as the token was not found.',\n [CODES.DELETE_SCOPE_NOT_FOUND]: 'The deletion attempt for service worker ' +\n 'scope could not be performed as the scope was not found.',\n [CODES.BG_HANDLER_FUNCTION_EXPECTED]: 'The input to ' +\n 'setBackgroundMessageHandler() must be a function.',\n [CODES.NO_WINDOW_CLIENT_TO_MSG]: 'An attempt was made to message a ' +\n 'non-existant window client.',\n [CODES.UNABLE_TO_RESUBSCRIBE]: 'There was an error while re-subscribing ' +\n 'the FCM token for push messaging. Will have to resubscribe the ' +\n 'user on next visit. {$message}',\n [CODES.NO_FCM_TOKEN_FOR_RESUBSCRIBE]: 'Could not find an FCM token ' +\n 'and as a result, unable to resubscribe. Will have to resubscribe the ' +\n 'user on next visit.',\n [CODES.FAILED_TO_DELETE_TOKEN]: 'Unable to delete the currently saved token.',\n [CODES.NO_SW_IN_REG]: 'Even though the service worker registration was ' +\n 'successful, there was a problem accessing the service worker itself.',\n [CODES.INCORRECT_GCM_SENDER_ID]: 'Please change your web app manifest\\'s ' +\n '\\'gcm_sender_id\\' value to \\'103953800507\\' to use Firebase messaging.',\n [CODES.BAD_SCOPE]: 'The service worker scope must be a string with at ' +\n 'least one character.',\n [CODES.BAD_VAPID_KEY]: 'The public VAPID key must be a string with at ' +\n 'least one character.',\n [CODES.BAD_SUBSCRIPTION]: 'The subscription must be a valid ' +\n 'PushSubscription.',\n [CODES.BAD_TOKEN]: 'The FCM Token used for storage / lookup was not ' +\n 'a valid token string.',\n [CODES.BAD_PUSH_SET]: 'The FCM push set used for storage / lookup was not ' +\n 'not a valid push set string.',\n [CODES.FAILED_DELETE_VAPID_KEY]: 'The VAPID key could not be deleted.'\n};\n\nexport default {\n codes: CODES,\n map: ERROR_MAP\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/models/errors.ts","/**\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'use strict';\n\nconst FCM_APPLICATION_SERVER_KEY = [0x04, 0x33, 0x94, 0xF7, 0xDF,\n 0xA1, 0xEB, 0xB1, 0xDC, 0x03, 0xA2, 0x5E, 0x15, 0x71, 0xDB, 0x48,\n 0xD3, 0x2E, 0xED, 0xED, 0xB2, 0x34, 0xDB, 0xB7, 0x47, 0x3A, 0x0C,\n 0x8F, 0xC4, 0xCC, 0xE1, 0x6F, 0x3C, 0x8C, 0x84, 0xDF, 0xAB, 0xB6,\n 0x66, 0x3E, 0xF2, 0x0C, 0xD4, 0x8B, 0xFE, 0xE3, 0xF9, 0x76, 0x2F,\n 0x14, 0x1C, 0x63, 0x08, 0x6A, 0x6F, 0x2D, 0xB1, 0x1A, 0x95, 0xB0,\n 0xCE, 0x37, 0xC0, 0x9C, 0x6E];\n\nconst SUBSCRIPTION_DETAILS = {\n 'userVisibleOnly': true,\n 'applicationServerKey': new Uint8Array(FCM_APPLICATION_SERVER_KEY)\n};\n\nexport default {\n ENDPOINT: 'https://fcm.googleapis.com',\n APPLICATION_SERVER_KEY: FCM_APPLICATION_SERVER_KEY,\n SUBSCRIPTION_OPTIONS: SUBSCRIPTION_DETAILS\n};\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/models/fcm-details.ts","/**\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'use strict';\n\nimport {ErrorFactory} from '../../app/errors';\n\nimport Errors from './errors';\nimport arrayBufferToBase64 from '../helpers/array-buffer-to-base64';\nimport FCMDetails from './fcm-details';\n\nconst FCM_TOKEN_DETAILS_DB = 'fcm_token_details_db';\nconst FCM_TOKEN_OBJ_STORE = 'fcm_token_object_Store';\nconst FCM_TOKEN_DETAILS_DB_VERSION = 1;\n\nexport default class TokenManager {\n\n private errorFactory_: ErrorFactory;\n private openDbPromise_: Promise;\n\n constructor() {\n this.errorFactory_ = new ErrorFactory('messaging', 'Messaging', Errors.map);\n this.openDbPromise_ = null;\n }\n\n /**\n * Get the indexedDB as a promsie.\n * @private\n * @return {Promise} The IndexedDB database\n */\n openDatabase_() {\n if (this.openDbPromise_) {\n return this.openDbPromise_;\n }\n\n this.openDbPromise_ = new Promise((resolve, reject) => {\n const request = indexedDB.open(FCM_TOKEN_DETAILS_DB,\n FCM_TOKEN_DETAILS_DB_VERSION);\n request.onerror = event => {\n reject(( event.target).error);\n };\n request.onsuccess = event => {\n resolve(( event.target).result);\n };\n request.onupgradeneeded = event => {\n var db = ( event.target).result;\n\n var objectStore = db.createObjectStore(FCM_TOKEN_OBJ_STORE, {\n keyPath: 'swScope'\n });\n\n // Make sure the sender ID can be searched\n objectStore.createIndex('fcmSenderId', 'fcmSenderId', {\n unique: false\n });\n\n objectStore.createIndex('fcmToken', 'fcmToken', {\n unique: true\n });\n };\n });\n\n return this.openDbPromise_;\n }\n\n /**\n * Close the currently open database.\n * @return {Promise} Returns the result of the promise chain.\n */\n closeDatabase() {\n if (this.openDbPromise_) {\n return this.openDbPromise_.then(db => {\n db.close();\n this.openDbPromise_ = null;\n });\n }\n\n return Promise.resolve();\n }\n\n /**\n * Given a token, this method will look up the details in indexedDB.\n * @public\n * @param {string} fcmToken\n * @return {Promise} The details associated with that token.\n */\n getTokenDetailsFromToken(fcmToken) {\n return this.openDatabase_()\n .then(db => {\n return new Promise((resolve, reject) => {\n const transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);\n const objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n const index = objectStore.index('fcmToken');\n const request = index.get(fcmToken);\n request.onerror = function(event) {\n reject(( event.target).error);\n };\n request.onsuccess = function(event) {\n resolve(( event.target).result);\n };\n });\n });\n }\n\n getTokenDetailsFromSWScope_(swScope) {\n return this.openDatabase_()\n .then(db => {\n return new Promise((resolve, reject) => {\n const transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);\n const objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n const scopeRequest = objectStore.get(swScope);\n scopeRequest.onerror = event => {\n reject(( event.target).error);\n };\n\n scopeRequest.onsuccess = event => {\n resolve(( event.target).result);\n };\n });\n });\n }\n\n getAllTokenDetailsForSenderId_(senderId): Promise> {\n return this.openDatabase_()\n .then(db => {\n return new Promise>((resolve, reject) => {\n const transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);\n const objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n\n const senderIdTokens = [];\n\n const cursorRequest = objectStore.openCursor();\n cursorRequest.onerror = event => {\n reject(( event.target).error);\n };\n\n cursorRequest.onsuccess = event => {\n const cursor = ( event.target).result;\n if (cursor) {\n if (cursor.value['fcmSenderId'] === senderId) {\n senderIdTokens.push(cursor.value);\n }\n cursor.continue();\n } else {\n resolve(senderIdTokens);\n }\n };\n });\n });\n }\n\n /**\n * Given a PushSubscription and messagingSenderId, get an FCM token.\n * @public\n * @param {string} senderId The 'messagingSenderId' to tie the token to.\n * @param {PushSubscription} subscription The PushSusbcription to \"federate\".\n * @param {string=} pushSet If defined this will swap the subscription for\n * matching FCM token.\n * @return {Promise} Returns the FCM token to be used in place\n * of the PushSubscription.\n */\n subscribeToFCM(senderId, subscription, pushSet?): Promise {\n const p256dh = arrayBufferToBase64(subscription['getKey']('p256dh'));\n const auth = arrayBufferToBase64(subscription['getKey']('auth'));\n\n let fcmSubscribeBody = `authorized_entity=${senderId}&` +\n `endpoint=${subscription.endpoint}&` +\n `encryption_key=${p256dh}&` +\n `encryption_auth=${auth}`;\n\n if (pushSet) {\n fcmSubscribeBody += `&pushSet=${pushSet}`;\n }\n\n const headers = new Headers();\n headers.append('Content-Type', 'application/x-www-form-urlencoded');\n\n const subscribeOptions = {\n method: 'POST',\n headers: headers,\n body: fcmSubscribeBody\n };\n\n return fetch(FCMDetails.ENDPOINT + '/fcm/connect/subscribe',\n subscribeOptions)\n .then(response => response.json())\n .then(response => {\n const fcmTokenResponse = response;\n if (fcmTokenResponse['error']) {\n const message = fcmTokenResponse['error']['message'];\n throw this.errorFactory_.create(Errors.codes.TOKEN_SUBSCRIBE_FAILED,\n {'message': message});\n }\n\n if (!fcmTokenResponse['token']) {\n throw this.errorFactory_.create(Errors.codes.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n if (!fcmTokenResponse['pushSet']) {\n throw this.errorFactory_.create(Errors.codes.TOKEN_SUBSCRIBE_NO_PUSH_SET);\n }\n\n return {\n 'token': fcmTokenResponse['token'],\n 'pushSet': fcmTokenResponse['pushSet']\n };\n });\n }\n\n /**\n * Checks the that fields in the PushSubscription are equivalent to the\n * details stores in the masterTokenDetails.\n * @private\n * @param {PushSubscription} subscription The push subscription we expect\n * the master token to match.\n * @param {Object} masterTokenDetails The saved details we wish to compare\n * with the PushSubscription\n * @return {boolean} true if the subscription and token details are\n * equivalent.\n */\n isSameSubscription_(subscription, masterTokenDetails) {\n // getKey() isn't defined in the PushSubscription externs file, hence\n // subscription['getKey']('').\n return (subscription.endpoint === masterTokenDetails['endpoint'] &&\n arrayBufferToBase64(subscription['getKey']('auth')) ===\n masterTokenDetails['auth'] &&\n arrayBufferToBase64(subscription['getKey']('p256dh')) ===\n masterTokenDetails['p256dh']);\n }\n\n /**\n * Save the details for the fcm token for re-use at a later date.\n * @private\n * @param {string} senderId The 'messagingSenderId' used for this project\n * @param {ServiceWorkerRegistration} swRegistration The service worker\n * used to subscribe the user for web push\n * @param {PushSubscription} subscription The push subscription passed to\n * FCM for the current token.\n * @param {string} fcmToken The FCM token currently used on this\n * device.\n * @param {string} fcmPushSet The FCM push tied to the fcm token.\n * @return {Promise}\n */\n saveTokenDetails_(senderId, swRegistration,\n subscription, fcmToken, fcmPushSet) {\n const details = {\n 'swScope': swRegistration.scope,\n 'endpoint': subscription.endpoint,\n 'auth': arrayBufferToBase64(subscription['getKey']('auth')),\n 'p256dh': arrayBufferToBase64(subscription['getKey']('p256dh')),\n 'fcmToken': fcmToken,\n 'fcmPushSet': fcmPushSet,\n 'fcmSenderId': senderId\n };\n\n return this.openDatabase_()\n .then(db => {\n return new Promise((resolve, reject) => {\n const transaction = db.transaction([FCM_TOKEN_OBJ_STORE], 'readwrite');\n const objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n const request = objectStore.put(details);\n request.onerror = event => {\n reject(( event.target).error);\n };\n request.onsuccess = event => {\n resolve();\n };\n });\n });\n }\n\n /**\n * Returns the saved FCM Token if one is available and still valid,\n * otherwise `null` is returned.\n * @param {string} senderId This should be the sender ID associated with the\n * FCM Token being retrieved.\n * @param {ServiceWorkerRegistration} swRegistration Registration to be used\n * to subscribe the user to push.\n * @return {Promise | Promise} Returns the saved FCM Token if\n * avilable and valid.\n * @export\n */\n getSavedToken(senderId, swRegistration) {\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n return Promise.reject(this.errorFactory_.create(\n Errors.codes.SW_REGISTRATION_EXPECTED));\n }\n\n if (typeof senderId !== 'string' || senderId.length === 0) {\n return Promise.reject(this.errorFactory_.create(\n Errors.codes.BAD_SENDER_ID));\n }\n\n return this.getAllTokenDetailsForSenderId_(senderId)\n .then(allTokenDetails => {\n if (allTokenDetails.length === 0) {\n return;\n }\n\n const index = allTokenDetails.findIndex(tokenDetails => {\n return (swRegistration.scope === tokenDetails['swScope'] &&\n senderId === tokenDetails['fcmSenderId']);\n });\n\n if (index === -1) {\n return;\n }\n\n return allTokenDetails[index];\n })\n .then(tokenDetails => {\n if (!tokenDetails) {\n return;\n }\n\n return swRegistration.pushManager.getSubscription()\n .catch(err => {\n throw this.errorFactory_.create(Errors.codes.GET_SUBSCRIPTION_FAILED);\n })\n .then(subscription => {\n if (subscription &&\n this.isSameSubscription_(subscription, tokenDetails)) {\n return tokenDetails['fcmToken'];\n }\n });\n });\n }\n\n /**\n * Creates a new FCM token.\n */\n createToken(senderId, swRegistration): Promise {\n if (typeof senderId !== 'string' || senderId.length === 0) {\n return Promise.reject(this.errorFactory_.create(\n Errors.codes.BAD_SENDER_ID));\n }\n\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n return Promise.reject(this.errorFactory_.create(\n Errors.codes.SW_REGISTRATION_EXPECTED));\n }\n\n // Check for existing subscription first\n let subscription;\n let fcmTokenDetails;\n return swRegistration.pushManager.getSubscription()\n .then(subscription => {\n if (subscription) {\n return subscription;\n }\n\n return swRegistration.pushManager.subscribe(\n FCMDetails.SUBSCRIPTION_OPTIONS);\n })\n .then(sub => {\n subscription = sub;\n return this.subscribeToFCM(senderId, subscription)\n })\n .then(tokenDetails => {\n fcmTokenDetails = tokenDetails;\n return this.saveTokenDetails_(senderId, swRegistration, subscription,\n fcmTokenDetails['token'], fcmTokenDetails['pushSet']);\n })\n .then(() => fcmTokenDetails['token']);\n }\n\n /**\n * This method deletes details of the current FCM token.\n * It's returning a promise in case we need to move to an async\n * method for deleting at a later date.\n * @param {string} token Token to be deleted\n * @return {Promise} Resolves once the FCM token details have been\n * deleted and returns the deleted details.\n */\n deleteToken(token) {\n if (typeof token !== 'string' || token.length === 0) {\n return Promise.reject(\n this.errorFactory_.create(Errors.codes.INVALID_DELETE_TOKEN));\n }\n\n return this.getTokenDetailsFromToken(token)\n .then(details => {\n if (!details) {\n throw this.errorFactory_.create(Errors.codes.DELETE_TOKEN_NOT_FOUND);\n }\n\n return this.openDatabase_()\n .then(db => {\n return new Promise((resolve, reject) => {\n const transaction = db.transaction([FCM_TOKEN_OBJ_STORE],\n 'readwrite');\n const objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);\n const request = objectStore.delete(details['swScope']);\n request.onerror = event => {\n reject(( event.target).error);\n };\n request.onsuccess = event => {\n if (( event.target).result === 0) {\n reject(this.errorFactory_.create(Errors.codes.FAILED_TO_DELETE_TOKEN));\n return;\n }\n\n resolve(details);\n };\n });\n });\n });\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/models/token-manager.ts","/**\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'use strict';\n\nimport {ErrorFactory} from '../../app/errors';\nimport Errors from '../models/errors';\nimport TokenManager from '../models/token-manager';\nimport NOTIFICATION_PERMISSION from '../models/notification-permission';\n\nconst SENDER_ID_OPTION_NAME = 'messagingSenderId';\n\nexport default class ControllerInterface {\n\n public app;\n public INTERNAL;\n protected errorFactory_;\n private messagingSenderId_: string;\n private tokenManager_: TokenManager;\n\n /**\n * An interface of the Messaging Service API\n * @param {!firebase.app.App} app\n */\n constructor(app) {\n this.errorFactory_ = new ErrorFactory('messaging', 'Messaging', Errors.map);\n\n if (!app.options[SENDER_ID_OPTION_NAME] ||\n typeof app.options[SENDER_ID_OPTION_NAME] !== 'string') {\n throw this.errorFactory_.create(Errors.codes.BAD_SENDER_ID);\n }\n\n this.messagingSenderId_ = app.options[SENDER_ID_OPTION_NAME];\n\n this.tokenManager_ = new TokenManager();\n\n this.app = app;\n this.INTERNAL = {};\n this.INTERNAL.delete = () => this.delete;\n }\n\n /**\n * @export\n * @return {Promise | Promise} Returns a promise that\n * resolves to an FCM token.\n */\n getToken() {\n // Check with permissions\n const currentPermission = this.getNotificationPermission_();\n if (currentPermission !== NOTIFICATION_PERMISSION.granted) {\n if (currentPermission === NOTIFICATION_PERMISSION.denied) {\n return Promise.reject(\n this.errorFactory_.create(Errors.codes.NOTIFICATIONS_BLOCKED)\n );\n }\n\n // We must wait for permission to be granted\n return Promise.resolve(null);\n }\n\n return this.getSWRegistration_()\n .then(registration => {\n return this.tokenManager_.getSavedToken(\n this.messagingSenderId_, registration)\n .then(token => {\n if (token) {\n return token;\n }\n\n return this.tokenManager_.createToken(this.messagingSenderId_,\n registration);\n });\n });\n }\n\n /**\n * This method deletes tokens that the token manager looks after and then\n * unregisters the push subscription if it exists.\n * @export\n * @param {string} token\n * @return {Promise}\n */\n deleteToken(token) {\n return this.tokenManager_.deleteToken(token)\n .then(() => {\n return this.getSWRegistration_()\n .then((registration) => {\n if (registration) {\n return registration.pushManager.getSubscription();\n }\n })\n .then(subscription => {\n if (subscription) {\n return subscription.unsubscribe();\n }\n });\n });\n }\n\n getSWRegistration_(): Promise {\n throw this.errorFactory_.create(Errors.codes.SHOULD_BE_INHERITED);\n }\n\n //\n // The following methods should only be available in the window.\n //\n\n requestPermission() {\n throw this.errorFactory_.create(Errors.codes.AVAILABLE_IN_WINDOW);\n }\n\n /**\n * @export\n * @param {!ServiceWorkerRegistration} registration\n */\n useServiceWorker(registration) {\n throw this.errorFactory_.create(Errors.codes.AVAILABLE_IN_WINDOW);\n }\n\n /**\n * @export\n * @param {!firebase.Observer|function(*)} nextOrObserver\n * @param {function(!Error)=} optError\n * @param {function()=} optCompleted\n * @return {!function()}\n */\n onMessage(nextOrObserver, optError, optCompleted) {\n throw this.errorFactory_.create(Errors.codes.AVAILABLE_IN_WINDOW);\n }\n\n /**\n * @export\n * @param {!firebase.Observer|function()} nextOrObserver An observer object\n * or a function triggered on token refresh.\n * @param {function(!Error)=} optError Optional A function\n * triggered on token refresh error.\n * @param {function()=} optCompleted Optional function triggered when the\n * observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\n onTokenRefresh(nextOrObserver, optError, optCompleted) {\n throw this.errorFactory_.create(Errors.codes.AVAILABLE_IN_WINDOW);\n }\n\n //\n // The following methods are used by the service worker only.\n //\n\n /**\n * @export\n * @param {function(Object)} callback\n */\n setBackgroundMessageHandler(callback) {\n throw this.errorFactory_.create(Errors.codes.AVAILABLE_IN_SW);\n }\n\n //\n // The following methods are used by the service themselves and not exposed\n // publicly or not expected to be used by developers.\n //\n\n /**\n * This method is required to adhere to the Firebase interface.\n * It closes any currently open indexdb database connections.\n */\n delete() {\n this.tokenManager_.closeDatabase();\n }\n\n /**\n * Returns the current Notification Permission state.\n * @private\n * @return {string} The currenct permission state.\n */\n getNotificationPermission_() {\n return (Notification as any).permission;\n }\n\n /**\n * @protected\n * @returns {TokenManager}\n */\n getTokenManager() {\n return this.tokenManager_;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/controllers/controller-interface.ts","/**\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'use strict';\n\n// These fields are strings to prevent closure from thinking goog.getMsg\n// should be used to initialise the values\nconst PARAMS = {\n TYPE_OF_MSG: 'firebase-messaging-msg-type',\n DATA: 'firebase-messaging-msg-data'\n};\n\n// This value isn't using the TYPE_OF_MSG short hand as closure\n// expects the variable to be defined via goog.getMsg\nconst msgType = {\n PUSH_MSG_RECEIVED: 'push-msg-received',\n NOTIFICATION_CLICKED: 'notification-clicked'\n};\n\nconst createNewMsg = (msgType, msgData) => {\n const message = {\n [PARAMS.TYPE_OF_MSG]: msgType,\n [PARAMS.DATA]: msgData\n };\n return message;\n};\n\nexport default {\n PARAMS,\n TYPES_OF_MSG: msgType,\n createNewMsg\n};\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/models/worker-page-message.ts","/**\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'use strict';\n\nexport default {\n path: '/firebase-messaging-sw.js',\n scope: '/firebase-cloud-messaging-push-scope'\n};\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/models/default-sw.ts","/**\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'use strict';\n\nimport ControllerInterface from './controller-interface';\nimport Errors from '../models/errors';\nimport WorkerPageMessage from '../models/worker-page-message';\nimport DefaultSW from '../models/default-sw';\nimport NOTIFICATION_PERMISSION from '../models/notification-permission';\nimport {createSubscribe} from '../../app/subscribe';\n\ndeclare const firebase: any;\n\nexport default class WindowController extends ControllerInterface {\n\n private registrationToUse_;\n private manifestCheckPromise_;\n private messageObserver_;\n private onMessage_;\n private tokenRefreshObserver_;\n private onTokenRefresh_;\n\n /**\n * A service that provides a MessagingService instance.\n * @param {!firebase.app.App} app\n */\n constructor(app) {\n super(app);\n\n /**\n * @private\n * @type {ServiceWorkerRegistration}\n */\n this.registrationToUse_;\n\n /**\n * @private\n * @type {Promise}\n */\n this.manifestCheckPromise_;\n\n /**\n * @private\n * @type {firebase.Observer}\n */\n this.messageObserver_ = null;\n /**\n * @private {!firebase.Subscribe} The subscribe function to the onMessage\n * observer.\n */\n this.onMessage_ = createSubscribe(observer => {\n this.messageObserver_ = observer;\n });\n\n /**\n * @private\n * @type {firebase.Observer}\n */\n this.tokenRefreshObserver_ = null;\n this.onTokenRefresh_ = createSubscribe(observer => {\n this.tokenRefreshObserver_ = observer;\n });\n\n this.setupSWMessageListener_();\n }\n\n /**\n * This method returns an FCM token if it can be generated.\n * The return promise will reject if the browser doesn't support\n * FCM, if permission is denied for notifications or it's not\n * possible to generate a token.\n * @export\n * @return {Promise | Promise} Returns a promise the\n * resolves to an FCM token or null if permission isn't granted.\n */\n getToken() {\n // Check that the required API's are available\n if (!this.isSupported_()) {\n return Promise.reject(\n this.errorFactory_.create(Errors.codes.UNSUPPORTED_BROWSER)\n );\n }\n\n return this.manifestCheck_()\n .then(() => {\n return super.getToken();\n });\n }\n\n /**\n * The method checks that a manifest is defined and has the correct GCM\n * sender ID.\n * @private\n * @return {Promise} Returns a promise that resolves if the manifest matches\n * our required sender ID\n */\n manifestCheck_() {\n if (this.manifestCheckPromise_) {\n return this.manifestCheckPromise_;\n }\n\n const manifestTag = ( document.querySelector('link[rel=\"manifest\"]'));\n if (!manifestTag) {\n this.manifestCheckPromise_ = Promise.resolve();\n } else {\n this.manifestCheckPromise_ = fetch(manifestTag.href)\n .then(response => {\n return response.json();\n })\n .catch(() => {\n // If the download or parsing fails allow check.\n // We only want to error if we KNOW that the gcm_sender_id is incorrect.\n return Promise.resolve();\n })\n .then(manifestContent => {\n if (!manifestContent) {\n return;\n }\n\n if (!manifestContent['gcm_sender_id']) {\n return;\n }\n\n if (manifestContent['gcm_sender_id'] !== '103953800507') {\n throw this.errorFactory_.create(\n Errors.codes.INCORRECT_GCM_SENDER_ID);\n }\n });\n }\n\n return this.manifestCheckPromise_;\n }\n\n /**\n * Request permission if it is not currently granted\n * @export\n * @returns {Promise} Resolves if the permission was granted, otherwise\n * rejects\n */\n requestPermission() {\n if ((Notification as any).permission === NOTIFICATION_PERMISSION.granted) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n const managePermissionResult = result => {\n if (result === NOTIFICATION_PERMISSION.granted) {\n return resolve();\n } else if (result === NOTIFICATION_PERMISSION.denied) {\n return reject(this.errorFactory_.create(\n Errors.codes.PERMISSION_BLOCKED));\n } else {\n return reject(this.errorFactory_.create(\n Errors.codes.PERMISSION_DEFAULT));\n }\n };\n\n // The Notification.requestPermission API was changed to\n // return a promise so now have to handle both in case\n // browsers stop support callbacks for promised version\n const permissionPromise = Notification.requestPermission(result => {\n if (permissionPromise) {\n // Let the promise manage this\n return;\n }\n\n managePermissionResult(result);\n });\n\n if (permissionPromise) {\n // Prefer the promise version as it's the future API.\n permissionPromise.then(managePermissionResult);\n }\n });\n }\n\n /**\n * This method allows a developer to override the default service worker and\n * instead use a custom service worker.\n * @export\n * @param {!ServiceWorkerRegistration} registration The service worker\n * registration that should be used to receive the push messages.\n */\n useServiceWorker(registration) {\n if (!(registration instanceof ServiceWorkerRegistration)) {\n throw this.errorFactory_.create(Errors.codes.SW_REGISTRATION_EXPECTED);\n }\n\n if (typeof this.registrationToUse_ !== 'undefined') {\n throw this.errorFactory_.create(Errors.codes.USE_SW_BEFORE_GET_TOKEN);\n }\n\n this.registrationToUse_ = registration;\n }\n\n /**\n * @export\n * @param {!firebase.Observer|function(*)} nextOrObserver An observer object\n * or a function triggered on message.\n * @param {function(!Error)=} optError Optional A function triggered on\n * message error.\n * @param {function()=} optCompleted Optional function triggered when the\n * observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\n onMessage(nextOrObserver, optError, optCompleted) {\n return this.onMessage_(nextOrObserver, optError, optCompleted);\n }\n\n /**\n * @export\n * @param {!firebase.Observer|function()} nextOrObserver An observer object\n * or a function triggered on token refresh.\n * @param {function(!Error)=} optError Optional A function\n * triggered on token refresh error.\n * @param {function()=} optCompleted Optional function triggered when the\n * observer is removed.\n * @return {!function()} The unsubscribe function for the observer.\n */\n onTokenRefresh(nextOrObserver, optError, optCompleted) {\n return this.onTokenRefresh_(nextOrObserver, optError, optCompleted);\n }\n\n /**\n * Given a registration, wait for the service worker it relates to\n * become activer\n * @private\n * @param {ServiceWorkerRegistration} registration Registration to wait\n * for service worker to become active\n * @return {Promise} Wait for service worker\n * registration to become active\n */\n waitForRegistrationToActivate_(registration) {\n const serviceWorker = registration.installing || registration.waiting ||\n registration.active;\n\n return new Promise((resolve, reject) => {\n if (!serviceWorker) {\n // This is a rare scenario but has occured in firefox\n reject(this.errorFactory_.create(Errors.codes.NO_SW_IN_REG));\n return;\n }\n // Because the Promise function is called on next tick there is a\n // small chance that the worker became active or redundant already.\n if (serviceWorker.state === 'activated') {\n resolve(registration);\n return;\n }\n\n if (serviceWorker.state === 'redundant') {\n reject(this.errorFactory_.create(Errors.codes.SW_REG_REDUNDANT));\n return;\n }\n\n let stateChangeListener = () => {\n if (serviceWorker.state === 'activated') {\n resolve(registration);\n } else if (serviceWorker.state === 'redundant') {\n reject(this.errorFactory_.create(Errors.codes.SW_REG_REDUNDANT));\n } else {\n // Return early and wait to next state change\n return;\n }\n serviceWorker.removeEventListener('statechange', stateChangeListener);\n };\n serviceWorker.addEventListener('statechange', stateChangeListener);\n });\n }\n\n /**\n * This will regiater the default service worker and return the registration\n * @private\n * @return {Promise} The service worker\n * registration to be used for the push service.\n */\n getSWRegistration_() {\n if (this.registrationToUse_) {\n return this.waitForRegistrationToActivate_(this.registrationToUse_);\n }\n\n // Make the registration null so we know useServiceWorker will not\n // use a new service worker as registrationToUse_ is no longer undefined\n this.registrationToUse_ = null;\n\n return navigator.serviceWorker.register(DefaultSW.path, {\n scope: DefaultSW.scope\n })\n .catch(err => {\n throw this.errorFactory_.create(\n Errors.codes.FAILED_DEFAULT_REGISTRATION, {\n 'browserErrorMessage': err.message\n }\n );\n })\n .then(registration => {\n return this.waitForRegistrationToActivate_(registration)\n .then(() => {\n this.registrationToUse_ = registration;\n\n // We update after activation due to an issue with Firefox v49 where\n // a race condition occassionally causes the service work to not\n // install\n registration.update();\n\n return registration;\n });\n });\n }\n\n /**\n * This method will set up a message listener to handle\n * events from the service worker that should trigger\n * events in the page.\n *\n * @private\n */\n setupSWMessageListener_() {\n if (!('serviceWorker' in navigator)) {\n return;\n }\n\n navigator.serviceWorker.addEventListener('message', event => {\n if (!event.data || !event.data[WorkerPageMessage.PARAMS.TYPE_OF_MSG]) {\n // Not a message from FCM\n return;\n }\n\n const workerPageMessage = event.data;\n switch (workerPageMessage[WorkerPageMessage.PARAMS.TYPE_OF_MSG]) {\n case WorkerPageMessage.TYPES_OF_MSG.PUSH_MSG_RECEIVED:\n case WorkerPageMessage.TYPES_OF_MSG.NOTIFICATION_CLICKED:\n const pushMessage = workerPageMessage[WorkerPageMessage.PARAMS.DATA];\n this.messageObserver_.next(pushMessage);\n break;\n default:\n // Noop.\n break;\n }\n }, false);\n }\n\n /**\n * Checks to see if the required API's are valid or not.\n * @private\n * @return {boolean} Returns true if the desired APIs are available.\n */\n isSupported_() {\n return 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype\n .hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey');\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/controllers/window-controller.ts","/**\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'use strict';\n\nimport ControllerInterface from './controller-interface';\nimport Errors from '../models/errors';\nimport WorkerPageMessage from '../models/worker-page-message';\nimport FCMDetails from '../models/fcm-details';\n\nconst FCM_MSG = 'FCM_MSG';\n\nexport default class SWController extends ControllerInterface {\n\n private bgMessageHandler_: (input: Object) => Promise;\n\n constructor(app) {\n super(app);\n\n self.addEventListener('push', e => this.onPush_(e), false);\n self.addEventListener(\n 'pushsubscriptionchange', e => this.onSubChange_(e), false);\n self.addEventListener(\n 'notificationclick', e => this.onNotificationClick_(e), false);\n\n /**\n * @private\n * @type {function(Object)|null}\n */\n this.bgMessageHandler_ = null;\n }\n\n /**\n * A handler for push events that shows notifications based on the content of\n * the payload.\n *\n * The payload must be a JSON-encoded Object with a `notification` key. The\n * value of the `notification` property will be used as the NotificationOptions\n * object passed to showNotification. Additionally, the `title` property of the\n * notification object will be used as the title.\n *\n * If there is no notification data in the payload then no notification will be\n * shown.\n * @private\n */\n onPush_(event) {\n let msgPayload;\n try {\n msgPayload = event.data.json();\n } catch (err) {\n // Not JSON so not an FCM message\n return;\n }\n\n const handleMsgPromise = this.hasVisibleClients_()\n .then(hasVisibleClients => {\n if (hasVisibleClients) {\n // Do not need to show a notification.\n if (msgPayload.notification || this.bgMessageHandler_) {\n // Send to page\n return this.sendMessageToWindowClients_(msgPayload);\n }\n return;\n }\n\n const notificationDetails = this.getNotificationData_(msgPayload);\n if (notificationDetails) {\n const notificationTitle = notificationDetails.title || '';\n return (self as any).registration\n .showNotification(notificationTitle, notificationDetails);\n } else if (this.bgMessageHandler_) {\n return this.bgMessageHandler_(msgPayload);\n }\n });\n\n event.waitUntil(handleMsgPromise);\n }\n\n /**\n * @private\n */\n onSubChange_(event) {\n const promiseChain = this.getToken()\n .then(token => {\n if (!token) {\n // We can't resubscribe if we don't have an FCM token for this scope.\n throw this.errorFactory_.create(\n Errors.codes.NO_FCM_TOKEN_FOR_RESUBSCRIBE);\n }\n\n let tokenDetails = null;\n const tokenManager = this.getTokenManager();\n return tokenManager.getTokenDetailsFromToken(token)\n .then(details => {\n tokenDetails = details;\n if (!tokenDetails) {\n throw this.errorFactory_.create(Errors.codes.INVALID_SAVED_TOKEN);\n }\n\n // Attempt to get a new subscription\n return (self as any).registration.pushManager.subscribe(FCMDetails.SUBSCRIPTION_OPTIONS);\n })\n .then(newSubscription => {\n // Send new subscription to FCM.\n return tokenManager.subscribeToFCM(\n tokenDetails.fcmSenderId,\n newSubscription,\n tokenDetails.fcmPushSet\n );\n })\n .catch(err => {\n // The best thing we can do is log this to the terminal so\n // developers might notice the error.\n return tokenManager.deleteToken(tokenDetails.fcmToken)\n .then(() => {\n throw this.errorFactory_.create(\n Errors.codes.UNABLE_TO_RESUBSCRIBE, {\n 'message': err\n }\n );\n });\n });\n });\n\n event.waitUntil(promiseChain);\n }\n\n /**\n * @private\n */\n onNotificationClick_(event) {\n if (!(event.notification && event.notification.data &&\n event.notification.data[FCM_MSG])) {\n // Not an FCM notification, do nothing.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n\n event.notification.close();\n\n const msgPayload = event.notification.data[FCM_MSG];\n const clickAction = msgPayload['notification']['click_action'];\n if (!clickAction) {\n // Nothing to do.\n return;\n }\n\n const promiseChain = this.getWindowClient_(clickAction)\n .then(windowClient => {\n if (!windowClient) {\n // Unable to find window client so need to open one.\n return (self as any).clients.openWindow(clickAction);\n }\n return windowClient;\n })\n .then(windowClient => {\n if (!windowClient) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n // Delete notification data from payload before sending to the page.\n const notificationData = msgPayload['notification'];\n delete msgPayload['notification'];\n\n const internalMsg = WorkerPageMessage.createNewMsg(\n WorkerPageMessage.TYPES_OF_MSG.NOTIFICATION_CLICKED,\n msgPayload);\n // Attempt to send a message to the client to handle the data\n // Is affected by: https://github.com/slightlyoff/ServiceWorker/issues/728\n return this.attemptToMessageClient_(windowClient, internalMsg);\n });\n\n event.waitUntil(promiseChain);\n }\n\n /**\n * @private\n * @param {Object} msgPayload\n * @return {NotificationOptions|undefined}\n */\n getNotificationData_(msgPayload) {\n if (!msgPayload) {\n return;\n }\n\n if (typeof msgPayload.notification !== 'object') {\n return;\n }\n\n const notificationInformation = Object.assign({}, msgPayload.notification);\n // Put the message payload under FCM_MSG name so we can identify the\n // notification as being an FCM notification vs a notification from\n // somewhere else (i.e. normal web push or developer generated\n // notification).\n notificationInformation['data'] = {\n [FCM_MSG]: msgPayload\n };\n\n return notificationInformation;\n }\n\n /**\n * Calling setBackgroundMessageHandler will opt in to some specific\n * behaviours.\n * 1.) If a notification doesn't need to be shown due to a window already\n * being visible, then push messages will be sent to the page.\n * 2.) If a notification needs to be shown, and the message contains no\n * notification data this method will be called\n * and the promise it returns will be passed to event.waitUntil.\n * If you do not set this callback then all push messages will let and the\n * developer can handle them in a their own 'push' event callback\n * @export\n * @param {function(Object)} callback The callback to be called when a push\n * message is received and a notification must be shown. The callback will\n * be given the data from the push message.\n */\n setBackgroundMessageHandler(callback) {\n if (callback && typeof callback !== 'function') {\n throw this.errorFactory_.create(\n Errors.codes.BG_HANDLER_FUNCTION_EXPECTED);\n }\n\n this.bgMessageHandler_ = callback;\n }\n\n /**\n * @private\n * @param {string} url The URL to look for when focusing a client.\n * @return {Object} Returns an existing window client or a newly opened\n * WindowClient.\n */\n getWindowClient_(url) {\n // Use URL to normalize the URL when comparing to windowClients.\n // This at least handles whether to include trailing slashes or not\n const parsedURL = new URL(url).href;\n\n return (self as any).clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n })\n .then(clientList => {\n let suitableClient = null;\n for (let i = 0; i < clientList.length; i++) {\n const parsedClientUrl = new URL(clientList[i].url).href;\n if (parsedClientUrl === parsedURL) {\n suitableClient = clientList[i];\n break;\n }\n }\n\n if (suitableClient) {\n suitableClient.focus();\n return suitableClient;\n }\n });\n }\n\n /**\n * This message will attempt to send the message to a window client.\n * @private\n * @param {Object} client The WindowClient to send the message to.\n * @param {Object} message The message to send to the client.\n * @returns {Promise} Returns a promise that resolves after sending the\n * message. This does not guarantee that the message was successfully\n * received.\n */\n attemptToMessageClient_(client, message) {\n return new Promise((resolve, reject) => {\n if (!client) {\n return reject(this.errorFactory_.create(\n Errors.codes.NO_WINDOW_CLIENT_TO_MSG));\n }\n\n client.postMessage(message);\n resolve();\n });\n }\n\n /**\n * @private\n * @returns {Promise} If there is currently a visible WindowClient,\n * this method will resolve to true, otherwise false.\n */\n hasVisibleClients_() {\n return (self as any).clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n })\n .then(clientList => {\n return clientList.some(client => client.visibilityState === 'visible');\n });\n }\n\n /**\n * @private\n * @param {Object} msgPayload The data from the push event that should be sent\n * to all available pages.\n * @returns {Promise} Returns a promise that resolves once the message\n * has been sent to all WindowClients.\n */\n sendMessageToWindowClients_(msgPayload) {\n return (self as any).clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n })\n .then(clientList => {\n const internalMsg = WorkerPageMessage.createNewMsg(\n WorkerPageMessage.TYPES_OF_MSG.PUSH_MSG_RECEIVED,\n msgPayload);\n\n return Promise.all(\n clientList.map(client => {\n return this.attemptToMessageClient_(client, internalMsg);\n })\n );\n });\n }\n\n /**\n * This will register the default service worker and return the registration.\n * @private\n * @return {Promise} The service worker\n * registration to be used for the push service.\n */\n getSWRegistration_() {\n return Promise.resolve((self as any).registration);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/messaging/controllers/sw-controller.ts","try {\n webpackJsonpFirebase([1],{\n\n/***/ 22:\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n\n// CONCATENATED MODULE: ./src/storage/implementation/constants.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Constants used in the Firebase Storage library.\r\n */\n/**\r\n * Domain and scheme for API calls.\r\n */\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/var domainBase = 'https://firebasestorage.googleapis.com';\n/**\r\n * Domain and scheme for object downloads.\r\n */\nvar downloadBase = 'https://firebasestorage.googleapis.com';\n/**\r\n * Base URL for non-upload calls to the API.\r\n */\nvar apiBaseUrl = '/v0';\n/**\r\n * Base URL for upload calls to the API.\r\n */\nvar apiUploadBaseUrl = '/v0';\nfunction setDomainBase(domainBase) {\n domainBase = domainBase;\n}\nvar configOption = 'storageBucket';\n/**\r\n * 1 minute\r\n */\nvar shortMaxOperationRetryTime = 1 * 60 * 1000;\n/**\r\n * 2 minutes\r\n */\nvar defaultMaxOperationRetryTime = 2 * 60 * 1000;\n/**\r\n * 10 minutes\r\n */\nvar defaultMaxUploadRetryTime = 10 * 60 * 100;\n/**\r\n * This is the value of Number.MIN_SAFE_INTEGER, which is not well supported\r\n * enough for us to use it directly.\r\n */\nvar minSafeInteger = -9007199254740991;\n// CONCATENATED MODULE: ./src/storage/implementation/error.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\nvar FirebaseStorageError = function () {\n function FirebaseStorageError(code, message) {\n this.code_ = prependCode(code);\n this.message_ = 'Firebase Storage: ' + message;\n this.serverResponse_ = null;\n this.name_ = 'FirebaseError';\n }\n FirebaseStorageError.prototype.codeProp = function () {\n return this.code;\n };\n FirebaseStorageError.prototype.codeEquals = function (code) {\n return prependCode(code) === this.codeProp();\n };\n FirebaseStorageError.prototype.serverResponseProp = function () {\n return this.serverResponse_;\n };\n FirebaseStorageError.prototype.setServerResponseProp = function (serverResponse) {\n this.serverResponse_ = serverResponse;\n };\n Object.defineProperty(FirebaseStorageError.prototype, \"name\", {\n get: function get() {\n return this.name_;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(FirebaseStorageError.prototype, \"code\", {\n get: function get() {\n return this.code_;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(FirebaseStorageError.prototype, \"message\", {\n get: function get() {\n return this.message_;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(FirebaseStorageError.prototype, \"serverResponse\", {\n get: function get() {\n return this.serverResponse_;\n },\n enumerable: true,\n configurable: true\n });\n return FirebaseStorageError;\n}();\n\nvar errors = {};\nvar Code = {\n // Shared between all platforms\n UNKNOWN: 'unknown',\n OBJECT_NOT_FOUND: 'object-not-found',\n BUCKET_NOT_FOUND: 'bucket-not-found',\n PROJECT_NOT_FOUND: 'project-not-found',\n QUOTA_EXCEEDED: 'quota-exceeded',\n UNAUTHENTICATED: 'unauthenticated',\n UNAUTHORIZED: 'unauthorized',\n RETRY_LIMIT_EXCEEDED: 'retry-limit-exceeded',\n INVALID_CHECKSUM: 'invalid-checksum',\n CANCELED: 'canceled',\n // JS specific\n INVALID_EVENT_NAME: 'invalid-event-name',\n INVALID_URL: 'invalid-url',\n INVALID_DEFAULT_BUCKET: 'invalid-default-bucket',\n NO_DEFAULT_BUCKET: 'no-default-bucket',\n CANNOT_SLICE_BLOB: 'cannot-slice-blob',\n SERVER_FILE_WRONG_SIZE: 'server-file-wrong-size',\n NO_DOWNLOAD_URL: 'no-download-url',\n INVALID_ARGUMENT: 'invalid-argument',\n INVALID_ARGUMENT_COUNT: 'invalid-argument-count',\n APP_DELETED: 'app-deleted',\n INVALID_ROOT_OPERATION: 'invalid-root-operation',\n INVALID_FORMAT: 'invalid-format',\n INTERNAL_ERROR: 'internal-error'\n};\nfunction prependCode(code) {\n return 'storage/' + code;\n}\nfunction unknown() {\n var message = 'An unknown error occurred, please check the error payload for ' + 'server response.';\n return new FirebaseStorageError(Code.UNKNOWN, message);\n}\nfunction objectNotFound(path) {\n return new FirebaseStorageError(Code.OBJECT_NOT_FOUND, 'Object \\'' + path + '\\' does not exist.');\n}\nfunction bucketNotFound(bucket) {\n return new FirebaseStorageError(Code.BUCKET_NOT_FOUND, 'Bucket \\'' + bucket + '\\' does not exist.');\n}\nfunction projectNotFound(project) {\n return new FirebaseStorageError(Code.PROJECT_NOT_FOUND, 'Project \\'' + project + '\\' does not exist.');\n}\nfunction quotaExceeded(bucket) {\n return new FirebaseStorageError(Code.QUOTA_EXCEEDED, 'Quota for bucket \\'' + bucket + '\\' exceeded, please view quota on ' + 'https://firebase.google.com/pricing/.');\n}\nfunction unauthenticated() {\n var message = 'User is not authenticated, please authenticate using Firebase ' + 'Authentication and try again.';\n return new FirebaseStorageError(Code.UNAUTHENTICATED, message);\n}\nfunction unauthorized(path) {\n return new FirebaseStorageError(Code.UNAUTHORIZED, 'User does not have permission to access \\'' + path + '\\'.');\n}\nfunction retryLimitExceeded() {\n return new FirebaseStorageError(Code.RETRY_LIMIT_EXCEEDED, 'Max retry time for operation exceeded, please try again.');\n}\nfunction invalidChecksum(path, checksum, calculated) {\n return new FirebaseStorageError(Code.INVALID_CHECKSUM, 'Uploaded/downloaded object \\'' + path + '\\' has checksum \\'' + checksum + '\\' which does not match \\'' + calculated + '\\'. Please retry the upload/download.');\n}\nfunction error_canceled() {\n return new FirebaseStorageError(Code.CANCELED, 'User canceled the upload/download.');\n}\nfunction invalidEventName(name) {\n return new FirebaseStorageError(Code.INVALID_EVENT_NAME, 'Invalid event name \\'' + name + '\\'.');\n}\nfunction invalidUrl(url) {\n return new FirebaseStorageError(Code.INVALID_URL, 'Invalid URL \\'' + url + '\\'.');\n}\nfunction invalidDefaultBucket(bucket) {\n return new FirebaseStorageError(Code.INVALID_DEFAULT_BUCKET, 'Invalid default bucket \\'' + bucket + '\\'.');\n}\nfunction noDefaultBucket() {\n return new FirebaseStorageError(Code.NO_DEFAULT_BUCKET, 'No default bucket ' + 'found. Did you set the \\'' + configOption + '\\' property when initializing the app?');\n}\nfunction cannotSliceBlob() {\n return new FirebaseStorageError(Code.CANNOT_SLICE_BLOB, 'Cannot slice blob for upload. Please retry the upload.');\n}\nfunction serverFileWrongSize() {\n return new FirebaseStorageError(Code.SERVER_FILE_WRONG_SIZE, 'Server recorded incorrect upload file size, please retry the upload.');\n}\nfunction noDownloadURL() {\n return new FirebaseStorageError(Code.NO_DOWNLOAD_URL, 'The given file does not have any download URLs.');\n}\nfunction invalidArgument(index, fnName, message) {\n return new FirebaseStorageError(Code.INVALID_ARGUMENT, 'Invalid argument in `' + fnName + '` at index ' + index + ': ' + message);\n}\nfunction invalidArgumentCount(argMin, argMax, fnName, real) {\n var countPart;\n var plural;\n if (argMin === argMax) {\n countPart = argMin;\n plural = argMin === 1 ? 'argument' : 'arguments';\n } else {\n countPart = 'between ' + argMin + ' and ' + argMax;\n plural = 'arguments';\n }\n return new FirebaseStorageError(Code.INVALID_ARGUMENT_COUNT, 'Invalid argument count in `' + fnName + '`: Expected ' + countPart + ' ' + plural + ', received ' + real + '.');\n}\nfunction appDeleted() {\n return new FirebaseStorageError(Code.APP_DELETED, 'The Firebase app was deleted.');\n}\n/**\r\n * @param name The name of the operation that was invalid.\r\n */\nfunction invalidRootOperation(name) {\n return new FirebaseStorageError(Code.INVALID_ROOT_OPERATION, 'The operation \\'' + name + '\\' cannot be performed on a root reference, create a non-root ' + 'reference using child, such as .child(\\'file.png\\').');\n}\n/**\r\n * @param format The format that was not valid.\r\n * @param message A message describing the format violation.\r\n */\nfunction invalidFormat(format, message) {\n return new FirebaseStorageError(Code.INVALID_FORMAT, 'String does not match format \\'' + format + '\\': ' + message);\n}\n/**\r\n * @param message A message describing the internal error.\r\n */\nfunction internalError(message) {\n throw new FirebaseStorageError(Code.INTERNAL_ERROR, 'Internal error: ' + message);\n}\n// CONCATENATED MODULE: ./src/storage/implementation/string.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\nvar StringFormat = {\n RAW: 'raw',\n BASE64: 'base64',\n BASE64URL: 'base64url',\n DATA_URL: 'data_url'\n};\nfunction formatValidator(stringFormat) {\n switch (stringFormat) {\n case StringFormat.RAW:\n case StringFormat.BASE64:\n case StringFormat.BASE64URL:\n case StringFormat.DATA_URL:\n return;\n default:\n throw 'Expected one of the event types: [' + StringFormat.RAW + ', ' + StringFormat.BASE64 + ', ' + StringFormat.BASE64URL + ', ' + StringFormat.DATA_URL + '].';\n }\n}\n/**\r\n * @struct\r\n */\nvar StringData = function () {\n function StringData(data, opt_contentType) {\n this.data = data;\n this.contentType = opt_contentType || null;\n }\n return StringData;\n}();\n\nfunction dataFromString(format, string) {\n switch (format) {\n case StringFormat.RAW:\n return new StringData(utf8Bytes_(string));\n case StringFormat.BASE64:\n case StringFormat.BASE64URL:\n return new StringData(base64Bytes_(format, string));\n case StringFormat.DATA_URL:\n return new StringData(dataURLBytes_(string), dataURLContentType_(string));\n }\n // assert(false);\n throw unknown();\n}\nfunction utf8Bytes_(string) {\n var b = [];\n for (var i = 0; i < string.length; i++) {\n var c = string.charCodeAt(i);\n if (c <= 127) {\n b.push(c);\n } else {\n if (c <= 2047) {\n b.push(192 | c >> 6, 128 | c & 63);\n } else {\n if ((c & 64512) == 55296) {\n // The start of a surrogate pair.\n var valid = i < string.length - 1 && (string.charCodeAt(i + 1) & 64512) == 56320;\n if (!valid) {\n // The second surrogate wasn't there.\n b.push(239, 191, 189);\n } else {\n var hi = c;\n var lo = string.charCodeAt(++i);\n c = 65536 | (hi & 1023) << 10 | lo & 1023;\n b.push(240 | c >> 18, 128 | c >> 12 & 63, 128 | c >> 6 & 63, 128 | c & 63);\n }\n } else {\n if ((c & 64512) == 56320) {\n // Invalid low surrogate.\n b.push(239, 191, 189);\n } else {\n b.push(224 | c >> 12, 128 | c >> 6 & 63, 128 | c & 63);\n }\n }\n }\n }\n }\n return new Uint8Array(b);\n}\nfunction percentEncodedBytes_(string) {\n var decoded;\n try {\n decoded = decodeURIComponent(string);\n } catch (e) {\n throw invalidFormat(StringFormat.DATA_URL, 'Malformed data URL.');\n }\n return utf8Bytes_(decoded);\n}\nfunction base64Bytes_(format, string) {\n switch (format) {\n case StringFormat.BASE64:\n {\n var hasMinus = string.indexOf('-') !== -1;\n var hasUnder = string.indexOf('_') !== -1;\n if (hasMinus || hasUnder) {\n var invalidChar = hasMinus ? '-' : '_';\n throw invalidFormat(format, 'Invalid character \\'' + invalidChar + '\\' found: is it base64url encoded?');\n }\n break;\n }\n case StringFormat.BASE64URL:\n {\n var hasPlus = string.indexOf('+') !== -1;\n var hasSlash = string.indexOf('/') !== -1;\n if (hasPlus || hasSlash) {\n var invalidChar = hasPlus ? '+' : '/';\n throw invalidFormat(format, 'Invalid character \\'' + invalidChar + '\\' found: is it base64 encoded?');\n }\n string = string.replace(/-/g, '+').replace(/_/g, '/');\n break;\n }\n }\n var bytes;\n try {\n bytes = atob(string);\n } catch (e) {\n throw invalidFormat(format, 'Invalid character found');\n }\n var array = new Uint8Array(bytes.length);\n for (var i = 0; i < bytes.length; i++) {\n array[i] = bytes.charCodeAt(i);\n }\n return array;\n}\n/**\r\n * @struct\r\n */\nvar string_DataURLParts = function () {\n function DataURLParts(dataURL) {\n this.base64 = false;\n this.contentType = null;\n var matches = dataURL.match(/^data:([^,]+)?,/);\n if (matches === null) {\n throw invalidFormat(StringFormat.DATA_URL, 'Must be formatted \\'data:[][;base64],');\n }\n var middle = matches[1] || null;\n if (middle != null) {\n this.base64 = endsWith(middle, ';base64');\n this.contentType = this.base64 ? middle.substring(0, middle.length - ';base64'.length) : middle;\n }\n this.rest = dataURL.substring(dataURL.indexOf(',') + 1);\n }\n return DataURLParts;\n}();\nfunction dataURLBytes_(string) {\n var parts = new string_DataURLParts(string);\n if (parts.base64) {\n return base64Bytes_(StringFormat.BASE64, parts.rest);\n } else {\n return percentEncodedBytes_(parts.rest);\n }\n}\nfunction dataURLContentType_(string) {\n var parts = new string_DataURLParts(string);\n return parts.contentType;\n}\nfunction endsWith(s, end) {\n var longEnough = s.length >= end.length;\n if (!longEnough) {\n return false;\n }\n return s.substring(s.length - end.length) === end;\n}\n// CONCATENATED MODULE: ./src/storage/implementation/taskenums.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\nvar TaskEvent = {\n /** Triggered whenever the task changes or progress is updated. */\n STATE_CHANGED: 'state_changed'\n};\nvar InternalTaskState = {\n RUNNING: 'running',\n PAUSING: 'pausing',\n PAUSED: 'paused',\n SUCCESS: 'success',\n CANCELING: 'canceling',\n CANCELED: 'canceled',\n ERROR: 'error'\n};\nvar TaskState = {\n /** The task is currently transferring data. */\n RUNNING: 'running',\n /** The task was paused by the user. */\n PAUSED: 'paused',\n /** The task completed successfully. */\n SUCCESS: 'success',\n /** The task was canceled. */\n CANCELED: 'canceled',\n /** The task failed with an error. */\n ERROR: 'error'\n};\nfunction taskStateFromInternalTaskState(state) {\n switch (state) {\n case InternalTaskState.RUNNING:\n case InternalTaskState.PAUSING:\n case InternalTaskState.CANCELING:\n return TaskState.RUNNING;\n case InternalTaskState.PAUSED:\n return TaskState.PAUSED;\n case InternalTaskState.SUCCESS:\n return TaskState.SUCCESS;\n case InternalTaskState.CANCELED:\n return TaskState.CANCELED;\n case InternalTaskState.ERROR:\n return TaskState.ERROR;\n default:\n // TODO(andysoto): assert(false);\n return TaskState.ERROR;\n }\n}\n// CONCATENATED MODULE: ./src/storage/implementation/object.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Contains methods for working with objects.\r\n */\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/function contains(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\nfunction forEach(obj, f) {\n for (var key in obj) {\n if (contains(obj, key)) {\n f(key, obj[key]);\n }\n }\n}\nfunction clone(obj) {\n if (obj == null) {\n return {};\n }\n var c = {};\n forEach(obj, function (key, val) {\n c[key] = val;\n });\n return c;\n}\n// CONCATENATED MODULE: ./src/storage/implementation/promise_external.ts\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_promise__ = __webpack_require__(4);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Implements the promise abstraction interface for external\r\n * (public SDK) packaging, which just passes through to the firebase-app impl.\r\n */\n/**\r\n * @template T\r\n * @param {function((function(T): void),\r\n * (function(!Error): void))} resolver\r\n */\n\nfunction make(resolver) {\n return new __WEBPACK_IMPORTED_MODULE_0__utils_promise__[\"b\" /* PromiseImpl */](resolver);\n}\n/**\r\n * @template T\r\n */\nfunction promise_external_resolve(value) {\n return __WEBPACK_IMPORTED_MODULE_0__utils_promise__[\"b\" /* PromiseImpl */].resolve(value);\n}\nfunction promise_external_reject(error) {\n return __WEBPACK_IMPORTED_MODULE_0__utils_promise__[\"b\" /* PromiseImpl */].reject(error);\n}\n// CONCATENATED MODULE: ./src/storage/implementation/type.ts\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @return False if the object is undefined or null, true otherwise.\r\n */\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/function isDef(p) {\n return p != null;\n}\nfunction isJustDef(p) {\n return p !== void 0;\n}\nfunction isFunction(p) {\n return typeof p === 'function';\n}\nfunction isObject(p) {\n return (typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object';\n}\nfunction isNonNullObject(p) {\n return isObject(p) && p !== null;\n}\nfunction isNonArrayObject(p) {\n return isObject(p) && !Array.isArray(p);\n}\nfunction isString(p) {\n return typeof p === 'string' || p instanceof String;\n}\nfunction isNumber(p) {\n return typeof p === 'number' || p instanceof Number;\n}\nfunction isNativeBlob(p) {\n return isNativeBlobDefined() && p instanceof Blob;\n}\nfunction isNativeBlobDefined() {\n return typeof Blob !== 'undefined';\n}\n// CONCATENATED MODULE: ./src/storage/implementation/xhrio.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @enum{number}\r\n */\nvar ErrorCode;\n(function (ErrorCode) {\n ErrorCode[ErrorCode[\"NO_ERROR\"] = 0] = \"NO_ERROR\";\n ErrorCode[ErrorCode[\"NETWORK_ERROR\"] = 1] = \"NETWORK_ERROR\";\n ErrorCode[ErrorCode[\"ABORT\"] = 2] = \"ABORT\";\n})(ErrorCode || (ErrorCode = {}));\n// CONCATENATED MODULE: ./src/storage/implementation/xhrio_network.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n/**\r\n * We use this instead of goog.net.XhrIo because goog.net.XhrIo is hyuuuuge and\r\n * doesn't work in React Native on Android.\r\n */\nvar xhrio_network_NetworkXhrIo = function () {\n function NetworkXhrIo() {\n var _this = this;\n this.sent_ = false;\n this.xhr_ = new XMLHttpRequest();\n this.errorCode_ = ErrorCode.NO_ERROR;\n this.sendPromise_ = make(function (resolve, reject) {\n _this.xhr_.addEventListener('abort', function (event) {\n _this.errorCode_ = ErrorCode.ABORT;\n resolve(_this);\n });\n _this.xhr_.addEventListener('error', function (event) {\n _this.errorCode_ = ErrorCode.NETWORK_ERROR;\n resolve(_this);\n });\n _this.xhr_.addEventListener('load', function (event) {\n resolve(_this);\n });\n });\n }\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.send = function (url, method, opt_body, opt_headers) {\n var _this = this;\n if (this.sent_) {\n throw internalError('cannot .send() more than once');\n }\n this.sent_ = true;\n this.xhr_.open(method, url, true);\n if (isDef(opt_headers)) {\n var headers = opt_headers;\n forEach(headers, function (key, val) {\n _this.xhr_.setRequestHeader(key, val.toString());\n });\n }\n if (isDef(opt_body)) {\n this.xhr_.send(opt_body);\n } else {\n this.xhr_.send();\n }\n return this.sendPromise_;\n };\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.getErrorCode = function () {\n if (!this.sent_) {\n throw internalError('cannot .getErrorCode() before sending');\n }\n return this.errorCode_;\n };\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.getStatus = function () {\n if (!this.sent_) {\n throw internalError('cannot .getStatus() before sending');\n }\n try {\n return this.xhr_.status;\n } catch (e) {\n return -1;\n }\n };\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.getResponseText = function () {\n if (!this.sent_) {\n throw internalError('cannot .getResponseText() before sending');\n }\n return this.xhr_.responseText;\n };\n /**\r\n * Aborts the request.\r\n * @override\r\n */\n NetworkXhrIo.prototype.abort = function () {\n this.xhr_.abort();\n };\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.getResponseHeader = function (header) {\n return this.xhr_.getResponseHeader(header);\n };\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.addUploadProgressListener = function (listener) {\n if (isDef(this.xhr_.upload)) {\n this.xhr_.upload.addEventListener('progress', listener);\n }\n };\n /**\r\n * @override\r\n */\n NetworkXhrIo.prototype.removeUploadProgressListener = function (listener) {\n if (isDef(this.xhr_.upload)) {\n this.xhr_.upload.removeEventListener('progress', listener);\n }\n };\n return NetworkXhrIo;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/xhriopool.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n/**\r\n * Factory-like class for creating XhrIo instances.\r\n */\nvar xhriopool_XhrIoPool = function () {\n function XhrIoPool() {}\n XhrIoPool.prototype.createXhrIo = function () {\n return new xhrio_network_NetworkXhrIo();\n };\n return XhrIoPool;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/json.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n/**\r\n * Returns the Object resulting from parsing the given JSON, or null if the\r\n * given string does not represent a JSON object.\r\n */\nfunction jsonObjectOrNull(s) {\n var obj;\n try {\n obj = JSON.parse(s);\n } catch (e) {\n return null;\n }\n if (isNonArrayObject(obj)) {\n return obj;\n } else {\n return null;\n }\n}\n// CONCATENATED MODULE: ./src/storage/implementation/location.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Functionality related to the parsing/composition of bucket/\r\n * object location.\r\n */\n\n/**\r\n * @struct\r\n */\nvar location_Location = function () {\n function Location(bucket, path) {\n this.bucket = bucket;\n this.path_ = path;\n }\n Object.defineProperty(Location.prototype, \"path\", {\n get: function get() {\n return this.path_;\n },\n enumerable: true,\n configurable: true\n });\n Location.prototype.fullServerUrl = function () {\n var encode = encodeURIComponent;\n return '/b/' + encode(this.bucket) + '/o/' + encode(this.path);\n };\n Location.prototype.bucketOnlyServerUrl = function () {\n var encode = encodeURIComponent;\n return '/b/' + encode(this.bucket) + '/o';\n };\n Location.makeFromBucketSpec = function (bucketString) {\n var bucketLocation;\n try {\n bucketLocation = Location.makeFromUrl(bucketString);\n } catch (e) {\n // Not valid URL, use as-is. This lets you put bare bucket names in\n // config.\n return new Location(bucketString, '');\n }\n if (bucketLocation.path === '') {\n return bucketLocation;\n } else {\n throw invalidDefaultBucket(bucketString);\n }\n };\n Location.makeFromUrl = function (url) {\n var location = null;\n var bucketDomain = '([A-Za-z0-9.\\\\-]+)';\n function gsModify(loc) {\n if (loc.path.charAt(loc.path.length - 1) === '/') {\n loc.path_ = loc.path_.slice(0, -1);\n }\n }\n var gsPath = '(/(.*))?$';\n var path = '(/([^?#]*).*)?$';\n var gsRegex = new RegExp('^gs://' + bucketDomain + gsPath, 'i');\n var gsIndices = { bucket: 1, path: 3 };\n function httpModify(loc) {\n loc.path_ = decodeURIComponent(loc.path);\n }\n var version = 'v[A-Za-z0-9_]+';\n var httpRegex = new RegExp('^https?://firebasestorage\\\\.googleapis\\\\.com/' + version + '/b/' + bucketDomain + '/o' + path, 'i');\n var httpIndices = { bucket: 1, path: 3 };\n var groups = [{ regex: gsRegex, indices: gsIndices, postModify: gsModify }, { regex: httpRegex, indices: httpIndices, postModify: httpModify }];\n for (var i = 0; i < groups.length; i++) {\n var group = groups[i];\n var captures = group.regex.exec(url);\n if (captures) {\n var bucketValue = captures[group.indices.bucket];\n var pathValue = captures[group.indices.path];\n if (!pathValue) {\n pathValue = '';\n }\n location = new Location(bucketValue, pathValue);\n group.postModify(location);\n break;\n }\n }\n if (location == null) {\n throw invalidUrl(url);\n }\n return location;\n };\n return Location;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/path.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Contains helper methods for manipulating paths.\r\n */\n/**\r\n * @return Null if the path is already at the root.\r\n */\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/function parent(path) {\n if (path.length == 0) {\n return null;\n }\n var index = path.lastIndexOf('/');\n if (index === -1) {\n return '';\n }\n var newPath = path.slice(0, index);\n return newPath;\n}\nfunction child(path, childPath) {\n var canonicalChildPath = childPath.split('/').filter(function (component) {\n return component.length > 0;\n }).join('/');\n if (path.length === 0) {\n return canonicalChildPath;\n } else {\n return path + '/' + canonicalChildPath;\n }\n}\n/**\r\n * Returns the last component of a path.\r\n * '/foo/bar' -> 'bar'\r\n * '/foo/bar/baz/' -> 'baz/'\r\n * '/a' -> 'a'\r\n */\nfunction lastComponent(path) {\n var index = path.lastIndexOf('/', path.length - 2);\n if (index === -1) {\n return path;\n } else {\n return path.slice(index + 1);\n }\n}\n// CONCATENATED MODULE: ./src/storage/implementation/url.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Functions to create and manipulate URLs for the server API.\r\n */\n\n\nfunction makeNormalUrl(urlPart) {\n return domainBase + apiBaseUrl + urlPart;\n}\nfunction makeDownloadUrl(urlPart) {\n return downloadBase + apiBaseUrl + urlPart;\n}\nfunction makeUploadUrl(urlPart) {\n return domainBase + apiUploadBaseUrl + urlPart;\n}\nfunction makeQueryString(params) {\n var encode = encodeURIComponent;\n var queryPart = '?';\n forEach(params, function (key, val) {\n var nextPart = encode(key) + '=' + encode(val);\n queryPart = queryPart + nextPart + '&';\n });\n // Chop off the extra '&' or '?' on the end\n queryPart = queryPart.slice(0, -1);\n return queryPart;\n}\n// CONCATENATED MODULE: ./src/storage/implementation/metadata.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\nfunction noXform_(metadata, value) {\n return value;\n}\n/**\r\n * @struct\r\n */\nvar Mapping = function () {\n function Mapping(server, opt_local, opt_writable, opt_xform) {\n this.server = server;\n this.local = opt_local || server;\n this.writable = !!opt_writable;\n this.xform = opt_xform || noXform_;\n }\n return Mapping;\n}();\n\nvar mappings_ = null;\nfunction xformPath(fullPath) {\n var valid = isString(fullPath);\n if (!valid || fullPath.length < 2) {\n return fullPath;\n } else {\n fullPath = fullPath;\n return lastComponent(fullPath);\n }\n}\nfunction getMappings() {\n if (mappings_) {\n return mappings_;\n }\n var mappings = [];\n mappings.push(new Mapping('bucket'));\n mappings.push(new Mapping('generation'));\n mappings.push(new Mapping('metageneration'));\n mappings.push(new Mapping('name', 'fullPath', true));\n function mappingsXformPath(metadata, fullPath) {\n return xformPath(fullPath);\n }\n var nameMapping = new Mapping('name');\n nameMapping.xform = mappingsXformPath;\n mappings.push(nameMapping);\n /**\r\n * Coerces the second param to a number, if it is defined.\r\n */\n function xformSize(metadata, size) {\n if (isDef(size)) {\n return +size;\n } else {\n return size;\n }\n }\n var sizeMapping = new Mapping('size');\n sizeMapping.xform = xformSize;\n mappings.push(sizeMapping);\n mappings.push(new Mapping('timeCreated'));\n mappings.push(new Mapping('updated'));\n mappings.push(new Mapping('md5Hash', null, true));\n mappings.push(new Mapping('cacheControl', null, true));\n mappings.push(new Mapping('contentDisposition', null, true));\n mappings.push(new Mapping('contentEncoding', null, true));\n mappings.push(new Mapping('contentLanguage', null, true));\n mappings.push(new Mapping('contentType', null, true));\n mappings.push(new Mapping('metadata', 'customMetadata', true));\n /**\r\n * Transforms a comma-separated string of tokens into a list of download\r\n * URLs.\r\n */\n function xformTokens(metadata, tokens) {\n var valid = isString(tokens) && tokens.length > 0;\n if (!valid) {\n // This can happen if objects are uploaded through GCS and retrieved\n // through list, so we don't want to throw an Error.\n return [];\n }\n var encode = encodeURIComponent;\n var tokensList = tokens.split(',');\n var urls = tokensList.map(function (token) {\n var bucket = metadata['bucket'];\n var path = metadata['fullPath'];\n var urlPart = '/b/' + encode(bucket) + '/o/' + encode(path);\n var base = makeDownloadUrl(urlPart);\n var queryString = makeQueryString({ 'alt': 'media', 'token': token });\n return base + queryString;\n });\n return urls;\n }\n mappings.push(new Mapping('downloadTokens', 'downloadURLs', false, xformTokens));\n mappings_ = mappings;\n return mappings_;\n}\nfunction addRef(metadata, authWrapper) {\n function generateRef() {\n var bucket = metadata['bucket'];\n var path = metadata['fullPath'];\n var loc = new location_Location(bucket, path);\n return authWrapper.makeStorageReference(loc);\n }\n Object.defineProperty(metadata, 'ref', { get: generateRef });\n}\nfunction fromResource(authWrapper, resource, mappings) {\n var metadata = {};\n metadata['type'] = 'file';\n var len = mappings.length;\n for (var i = 0; i < len; i++) {\n var mapping = mappings[i];\n metadata[mapping.local] = mapping.xform(metadata, resource[mapping.server]);\n }\n addRef(metadata, authWrapper);\n return metadata;\n}\nfunction fromResourceString(authWrapper, resourceString, mappings) {\n var obj = jsonObjectOrNull(resourceString);\n if (obj === null) {\n return null;\n }\n var resource = obj;\n return fromResource(authWrapper, resource, mappings);\n}\nfunction toResourceString(metadata, mappings) {\n var resource = {};\n var len = mappings.length;\n for (var i = 0; i < len; i++) {\n var mapping = mappings[i];\n if (mapping.writable) {\n resource[mapping.server] = metadata[mapping.local];\n }\n }\n return JSON.stringify(resource);\n}\nfunction metadataValidator(p) {\n var validType = p && isObject(p);\n if (!validType) {\n throw 'Expected Metadata object.';\n }\n for (var key in p) {\n var val = p[key];\n if (key === 'customMetadata') {\n if (!isObject(val)) {\n throw 'Expected object for \\'customMetadata\\' mapping.';\n }\n } else {\n if (isNonNullObject(val)) {\n throw 'Mapping for \\'' + key + '\\' cannot be an object.';\n }\n }\n }\n}\n// CONCATENATED MODULE: ./src/storage/implementation/args.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n/**\r\n * @param name Name of the function.\r\n * @param specs Argument specs.\r\n * @param passed The actual arguments passed to the function.\r\n * @throws {fbs.Error} If the arguments are invalid.\r\n */\nfunction validate(name, specs, passed) {\n var minArgs = specs.length;\n var maxArgs = specs.length;\n for (var i = 0; i < specs.length; i++) {\n if (specs[i].optional) {\n minArgs = i;\n break;\n }\n }\n var validLength = minArgs <= passed.length && passed.length <= maxArgs;\n if (!validLength) {\n throw invalidArgumentCount(minArgs, maxArgs, name, passed.length);\n }\n for (var i = 0; i < passed.length; i++) {\n try {\n specs[i].validator(passed[i]);\n } catch (e) {\n if (e instanceof Error) {\n throw invalidArgument(i, name, e.message);\n } else {\n throw invalidArgument(i, name, e);\n }\n }\n }\n}\n/**\r\n * @struct\r\n */\nvar args_ArgSpec = function () {\n function ArgSpec(validator, opt_optional) {\n var self = this;\n this.validator = function (p) {\n if (self.optional && !isJustDef(p)) {\n return;\n }\n validator(p);\n };\n this.optional = !!opt_optional;\n }\n return ArgSpec;\n}();\n\nfunction and_(v1, v2) {\n return function (p) {\n v1(p);\n v2(p);\n };\n}\nfunction stringSpec(opt_validator, opt_optional) {\n function stringValidator(p) {\n if (!isString(p)) {\n throw 'Expected string.';\n }\n }\n var validator;\n if (opt_validator) {\n validator = and_(stringValidator, opt_validator);\n } else {\n validator = stringValidator;\n }\n return new args_ArgSpec(validator, opt_optional);\n}\nfunction uploadDataSpec() {\n function validator(p) {\n var valid = p instanceof Uint8Array || p instanceof ArrayBuffer || isNativeBlobDefined() && p instanceof Blob;\n if (!valid) {\n throw 'Expected Blob or File.';\n }\n }\n return new args_ArgSpec(validator);\n}\nfunction metadataSpec(opt_optional) {\n return new args_ArgSpec(metadataValidator, opt_optional);\n}\nfunction nonNegativeNumberSpec() {\n function validator(p) {\n var valid = isNumber(p) && p >= 0;\n if (!valid) {\n throw 'Expected a number 0 or greater.';\n }\n }\n return new args_ArgSpec(validator);\n}\nfunction looseObjectSpec(opt_validator, opt_optional) {\n function validator(p) {\n var isLooseObject = p === null || isDef(p) && p instanceof Object;\n if (!isLooseObject) {\n throw 'Expected an Object.';\n }\n if (opt_validator !== undefined && opt_validator !== null) {\n opt_validator(p);\n }\n }\n return new args_ArgSpec(validator, opt_optional);\n}\nfunction nullFunctionSpec(opt_optional) {\n function validator(p) {\n var valid = p === null || isFunction(p);\n if (!valid) {\n throw 'Expected a Function.';\n }\n }\n return new args_ArgSpec(validator, opt_optional);\n}\n// CONCATENATED MODULE: ./src/storage/implementation/fs.ts\n\nfunction getBlobBuilder() {\n if (typeof BlobBuilder !== 'undefined') {\n return BlobBuilder;\n } else if (typeof WebKitBlobBuilder !== 'undefined') {\n return WebKitBlobBuilder;\n } else {\n return undefined;\n }\n}\n/**\r\n * Concatenates one or more values together and converts them to a Blob.\r\n *\r\n * @param var_args The values that will make up the resulting blob.\r\n * @return The blob.\r\n */\nfunction getBlob() {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n var BlobBuilder = getBlobBuilder();\n if (BlobBuilder !== undefined) {\n var bb = new BlobBuilder();\n for (var i = 0; i < var_args.length; i++) {\n bb.append(var_args[i]);\n }\n return bb.getBlob();\n } else {\n if (isNativeBlobDefined()) {\n return new Blob(var_args);\n } else {\n throw Error('This browser doesn\\'t seem to support creating Blobs');\n }\n }\n}\n/**\r\n * Slices the blob. The returned blob contains data from the start byte\r\n * (inclusive) till the end byte (exclusive). Negative indices cannot be used.\r\n *\r\n * @param blob The blob to be sliced.\r\n * @param start Index of the starting byte.\r\n * @param end Index of the ending byte.\r\n * @return The blob slice or null if not supported.\r\n */\nfunction sliceBlob(blob, start, end) {\n if (blob.webkitSlice) {\n return blob.webkitSlice(start, end);\n } else if (blob.mozSlice) {\n return blob.mozSlice(start, end);\n } else if (blob.slice) {\n return blob.slice(start, end);\n }\n return null;\n}\n// CONCATENATED MODULE: ./src/storage/implementation/blob.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @file Provides a Blob-like wrapper for various binary types (including the\r\n * native Blob type). This makes it possible to upload types like ArrayBuffers,\r\n * making uploads possible in environments without the native Blob type.\r\n */\n\n\n\n\n/**\r\n * @param opt_elideCopy If true, doesn't copy mutable input data\r\n * (e.g. Uint8Arrays). Pass true only if you know the objects will not be\r\n * modified after this blob's construction.\r\n */\nvar blob_FbsBlob = function () {\n function FbsBlob(data, opt_elideCopy) {\n var size = 0;\n var blobType = '';\n if (isNativeBlob(data)) {\n this.data_ = data;\n size = data.size;\n blobType = data.type;\n } else if (data instanceof ArrayBuffer) {\n if (opt_elideCopy) {\n this.data_ = new Uint8Array(data);\n } else {\n this.data_ = new Uint8Array(data.byteLength);\n this.data_.set(new Uint8Array(data));\n }\n size = this.data_.length;\n } else if (data instanceof Uint8Array) {\n if (opt_elideCopy) {\n this.data_ = data;\n } else {\n this.data_ = new Uint8Array(data.length);\n this.data_.set(data);\n }\n size = data.length;\n }\n this.size_ = size;\n this.type_ = blobType;\n }\n FbsBlob.prototype.size = function () {\n return this.size_;\n };\n FbsBlob.prototype.type = function () {\n return this.type_;\n };\n FbsBlob.prototype.slice = function (startByte, endByte) {\n if (isNativeBlob(this.data_)) {\n var realBlob = this.data_;\n var sliced = sliceBlob(realBlob, startByte, endByte);\n if (sliced === null) {\n return null;\n }\n return new FbsBlob(sliced);\n } else {\n var slice = new Uint8Array(this.data_.buffer, startByte, endByte - startByte);\n return new FbsBlob(slice, true);\n }\n };\n FbsBlob.getBlob = function () {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n if (isNativeBlobDefined()) {\n var blobby = var_args.map(function (val) {\n if (val instanceof FbsBlob) {\n return val.data_;\n } else {\n return val;\n }\n });\n return new FbsBlob(getBlob.apply(null, blobby));\n } else {\n var uint8Arrays = var_args.map(function (val) {\n if (isString(val)) {\n return dataFromString(StringFormat.RAW, val).data;\n } else {\n // Blobs don't exist, so this has to be a Uint8Array.\n return val.data_;\n }\n });\n var finalLength_1 = 0;\n uint8Arrays.forEach(function (array) {\n finalLength_1 += array.byteLength;\n });\n var merged_1 = new Uint8Array(finalLength_1);\n var index_1 = 0;\n uint8Arrays.forEach(function (array) {\n for (var i = 0; i < array.length; i++) {\n merged_1[index_1++] = array[i];\n }\n });\n return new FbsBlob(merged_1, true);\n }\n };\n FbsBlob.prototype.uploadData = function () {\n return this.data_;\n };\n return FbsBlob;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/array.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * Returns true if the object is contained in the array (compared with ===).\r\n * @template T\r\n */\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/function array_contains(array, elem) {\n return array.indexOf(elem) !== -1;\n}\n/**\r\n * Returns a shallow copy of the array or array-like object (e.g. arguments).\r\n * @template T\r\n */\nfunction array_clone(arraylike) {\n return Array.prototype.slice.call(arraylike);\n}\n/**\r\n * Removes the given element from the given array, if it is contained.\r\n * Directly modifies the passed-in array.\r\n * @template T\r\n */\nfunction remove(array, elem) {\n var i = array.indexOf(elem);\n if (i !== -1) {\n array.splice(i, 1);\n }\n}\n// CONCATENATED MODULE: ./src/storage/implementation/requestinfo.ts\nvar RequestInfo = function () {\n function RequestInfo(url, method,\n /**\r\n * Returns the value with which to resolve the request's promise. Only called\r\n * if the request is successful. Throw from this function to reject the\r\n * returned Request's promise with the thrown error.\r\n * Note: The XhrIo passed to this function may be reused after this callback\r\n * returns. Do not keep a reference to it in any way.\r\n */\n handler, timeout) {\n this.url = url;\n this.method = method;\n this.handler = handler;\n this.timeout = timeout;\n this.urlParams = {};\n this.headers = {};\n this.body = null;\n this.errorHandler = null;\n /**\r\n * Called with the current number of bytes uploaded and total size (-1 if not\r\n * computable) of the request body (i.e. used to report upload progress).\r\n */\n this.progressCallback = null;\n this.successCodes = [200];\n this.additionalRetryCodes = [];\n }\n return RequestInfo;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/requests.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n\n\n/**\r\n * Throws the UNKNOWN FirebaseStorageError if cndn is false.\r\n */\nfunction handlerCheck(cndn) {\n if (!cndn) {\n throw unknown();\n }\n}\nfunction metadataHandler(authWrapper, mappings) {\n function handler(xhr, text) {\n var metadata = fromResourceString(authWrapper, text, mappings);\n handlerCheck(metadata !== null);\n return metadata;\n }\n return handler;\n}\nfunction sharedErrorHandler(location) {\n function errorHandler(xhr, err) {\n var newErr;\n if (xhr.getStatus() === 401) {\n newErr = unauthenticated();\n } else {\n if (xhr.getStatus() === 402) {\n newErr = quotaExceeded(location.bucket);\n } else {\n if (xhr.getStatus() === 403) {\n newErr = unauthorized(location.path);\n } else {\n newErr = err;\n }\n }\n }\n newErr.setServerResponseProp(err.serverResponseProp());\n return newErr;\n }\n return errorHandler;\n}\nfunction objectErrorHandler(location) {\n var shared = sharedErrorHandler(location);\n function errorHandler(xhr, err) {\n var newErr = shared(xhr, err);\n if (xhr.getStatus() === 404) {\n newErr = objectNotFound(location.path);\n }\n newErr.setServerResponseProp(err.serverResponseProp());\n return newErr;\n }\n return errorHandler;\n}\nfunction getMetadata(authWrapper, location, mappings) {\n var urlPart = location.fullServerUrl();\n var url = makeNormalUrl(urlPart);\n var method = 'GET';\n var timeout = authWrapper.maxOperationRetryTime();\n var requestInfo = new RequestInfo(url, method, metadataHandler(authWrapper, mappings), timeout);\n requestInfo.errorHandler = objectErrorHandler(location);\n return requestInfo;\n}\nfunction updateMetadata(authWrapper, location, metadata, mappings) {\n var urlPart = location.fullServerUrl();\n var url = makeNormalUrl(urlPart);\n var method = 'PATCH';\n var body = toResourceString(metadata, mappings);\n var headers = { 'Content-Type': 'application/json; charset=utf-8' };\n var timeout = authWrapper.maxOperationRetryTime();\n var requestInfo = new RequestInfo(url, method, metadataHandler(authWrapper, mappings), timeout);\n requestInfo.headers = headers;\n requestInfo.body = body;\n requestInfo.errorHandler = objectErrorHandler(location);\n return requestInfo;\n}\nfunction deleteObject(authWrapper, location) {\n var urlPart = location.fullServerUrl();\n var url = makeNormalUrl(urlPart);\n var method = 'DELETE';\n var timeout = authWrapper.maxOperationRetryTime();\n function handler(xhr, text) {}\n var requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.successCodes = [200, 204];\n requestInfo.errorHandler = objectErrorHandler(location);\n return requestInfo;\n}\nfunction determineContentType_(metadata, blob) {\n return metadata && metadata['contentType'] || blob && blob.type() || 'application/octet-stream';\n}\nfunction metadataForUpload_(location, blob, opt_metadata) {\n var metadata = clone(opt_metadata);\n metadata['fullPath'] = location.path;\n metadata['size'] = blob.size();\n if (!metadata['contentType']) {\n metadata['contentType'] = determineContentType_(null, blob);\n }\n return metadata;\n}\nfunction multipartUpload(authWrapper, location, mappings, blob, opt_metadata) {\n var urlPart = location.bucketOnlyServerUrl();\n var headers = { 'X-Goog-Upload-Protocol': 'multipart' };\n function genBoundary() {\n var str = '';\n for (var i = 0; i < 2; i++) {\n str = str + Math.random().toString().slice(2);\n }\n return str;\n }\n var boundary = genBoundary();\n headers['Content-Type'] = 'multipart/related; boundary=' + boundary;\n var metadata = metadataForUpload_(location, blob, opt_metadata);\n var metadataString = toResourceString(metadata, mappings);\n var preBlobPart = '--' + boundary + '\\r\\n' + 'Content-Type: application/json; charset=utf-8\\r\\n\\r\\n' + metadataString + '\\r\\n--' + boundary + '\\r\\n' + 'Content-Type: ' + metadata['contentType'] + '\\r\\n\\r\\n';\n var postBlobPart = '\\r\\n--' + boundary + '--';\n var body = blob_FbsBlob.getBlob(preBlobPart, blob, postBlobPart);\n if (body === null) {\n throw cannotSliceBlob();\n }\n var urlParams = { 'name': metadata['fullPath'] };\n var url = makeUploadUrl(urlPart);\n var method = 'POST';\n var timeout = authWrapper.maxUploadRetryTime();\n var requestInfo = new RequestInfo(url, method, metadataHandler(authWrapper, mappings), timeout);\n requestInfo.urlParams = urlParams;\n requestInfo.headers = headers;\n requestInfo.body = body.uploadData();\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n/**\r\n * @param current The number of bytes that have been uploaded so far.\r\n * @param total The total number of bytes in the upload.\r\n * @param opt_finalized True if the server has finished the upload.\r\n * @param opt_metadata The upload metadata, should\r\n * only be passed if opt_finalized is true.\r\n * @struct\r\n */\nvar ResumableUploadStatus = function () {\n function ResumableUploadStatus(current, total, finalized, metadata) {\n this.current = current;\n this.total = total;\n this.finalized = !!finalized;\n this.metadata = metadata || null;\n }\n return ResumableUploadStatus;\n}();\n\nfunction checkResumeHeader_(xhr, opt_allowed) {\n var status;\n try {\n status = xhr.getResponseHeader('X-Goog-Upload-Status');\n } catch (e) {\n handlerCheck(false);\n }\n var allowed = opt_allowed || ['active'];\n handlerCheck(array_contains(allowed, status));\n return status;\n}\nfunction createResumableUpload(authWrapper, location, mappings, blob, opt_metadata) {\n var urlPart = location.bucketOnlyServerUrl();\n var metadata = metadataForUpload_(location, blob, opt_metadata);\n var urlParams = { 'name': metadata['fullPath'] };\n var url = makeUploadUrl(urlPart);\n var method = 'POST';\n var headers = {\n 'X-Goog-Upload-Protocol': 'resumable',\n 'X-Goog-Upload-Command': 'start',\n 'X-Goog-Upload-Header-Content-Length': blob.size(),\n 'X-Goog-Upload-Header-Content-Type': metadata['contentType'],\n 'Content-Type': 'application/json; charset=utf-8'\n };\n var body = toResourceString(metadata, mappings);\n var timeout = authWrapper.maxUploadRetryTime();\n function handler(xhr, text) {\n checkResumeHeader_(xhr);\n var url;\n try {\n url = xhr.getResponseHeader('X-Goog-Upload-URL');\n } catch (e) {\n handlerCheck(false);\n }\n handlerCheck(isString(url));\n return url;\n }\n var requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.urlParams = urlParams;\n requestInfo.headers = headers;\n requestInfo.body = body;\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n/**\r\n * @param url From a call to fbs.requests.createResumableUpload.\r\n */\nfunction getResumableUploadStatus(authWrapper, location, url, blob) {\n var headers = { 'X-Goog-Upload-Command': 'query' };\n function handler(xhr, text) {\n var status = checkResumeHeader_(xhr, ['active', 'final']);\n var sizeString;\n try {\n sizeString = xhr.getResponseHeader('X-Goog-Upload-Size-Received');\n } catch (e) {\n handlerCheck(false);\n }\n var size = parseInt(sizeString, 10);\n handlerCheck(!isNaN(size));\n return new ResumableUploadStatus(size, blob.size(), status === 'final');\n }\n var method = 'POST';\n var timeout = authWrapper.maxUploadRetryTime();\n var requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.headers = headers;\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n/**\r\n * Any uploads via the resumable upload API must transfer a number of bytes\r\n * that is a multiple of this number.\r\n */\nvar resumableUploadChunkSize = 256 * 1024;\n/**\r\n * @param url From a call to fbs.requests.createResumableUpload.\r\n * @param chunkSize Number of bytes to upload.\r\n * @param opt_status The previous status.\r\n * If not passed or null, we start from the beginning.\r\n * @throws fbs.Error If the upload is already complete, the passed in status\r\n * has a final size inconsistent with the blob, or the blob cannot be sliced\r\n * for upload.\r\n */\nfunction continueResumableUpload(location, authWrapper, url, blob, chunkSize, mappings, opt_status, opt_progressCallback) {\n // TODO(andysoto): standardize on internal asserts\n // assert(!(opt_status && opt_status.finalized));\n var status = new ResumableUploadStatus(0, 0);\n if (opt_status) {\n status.current = opt_status.current;\n status.total = opt_status.total;\n } else {\n status.current = 0;\n status.total = blob.size();\n }\n if (blob.size() !== status.total) {\n throw serverFileWrongSize();\n }\n var bytesLeft = status.total - status.current;\n var bytesToUpload = bytesLeft;\n if (chunkSize > 0) {\n bytesToUpload = Math.min(bytesToUpload, chunkSize);\n }\n var startByte = status.current;\n var endByte = startByte + bytesToUpload;\n var uploadCommand = bytesToUpload === bytesLeft ? 'upload, finalize' : 'upload';\n var headers = {\n 'X-Goog-Upload-Command': uploadCommand,\n 'X-Goog-Upload-Offset': status.current\n };\n var body = blob.slice(startByte, endByte);\n if (body === null) {\n throw cannotSliceBlob();\n }\n function handler(xhr, text) {\n // TODO(andysoto): Verify the MD5 of each uploaded range:\n // the 'x-range-md5' header comes back with status code 308 responses.\n // We'll only be able to bail out though, because you can't re-upload a\n // range that you previously uploaded.\n var uploadStatus = checkResumeHeader_(xhr, ['active', 'final']);\n var newCurrent = status.current + bytesToUpload;\n var size = blob.size();\n var metadata;\n if (uploadStatus === 'final') {\n metadata = metadataHandler(authWrapper, mappings)(xhr, text);\n } else {\n metadata = null;\n }\n return new ResumableUploadStatus(newCurrent, size, uploadStatus === 'final', metadata);\n }\n var method = 'POST';\n var timeout = authWrapper.maxUploadRetryTime();\n var requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.headers = headers;\n requestInfo.body = body.uploadData();\n requestInfo.progressCallback = opt_progressCallback || null;\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n// CONCATENATED MODULE: ./src/storage/implementation/observer.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n/**\r\n * @struct\r\n */\nvar observer_Observer = function () {\n function Observer(nextOrObserver, opt_error, opt_complete) {\n var asFunctions = isFunction(nextOrObserver) || isDef(opt_error) || isDef(opt_complete);\n if (asFunctions) {\n this.next = nextOrObserver;\n this.error = opt_error || null;\n this.complete = opt_complete || null;\n } else {\n var observer = nextOrObserver;\n this.next = observer.next || null;\n this.error = observer.error || null;\n this.complete = observer.complete || null;\n }\n }\n return Observer;\n}();\n\n// CONCATENATED MODULE: ./src/storage/tasksnapshot.ts\nvar UploadTaskSnapshot = function () {\n function UploadTaskSnapshot(bytesTransferred, totalBytes, state, metadata, task, ref) {\n this.bytesTransferred = bytesTransferred;\n this.totalBytes = totalBytes;\n this.state = state;\n this.metadata = metadata;\n this.task = task;\n this.ref = ref;\n }\n Object.defineProperty(UploadTaskSnapshot.prototype, \"downloadURL\", {\n get: function get() {\n if (this.metadata !== null) {\n var urls = this.metadata['downloadURLs'];\n if (urls != null && urls[0] != null) {\n return urls[0];\n } else {\n return null;\n }\n } else {\n return null;\n }\n },\n enumerable: true,\n configurable: true\n });\n return UploadTaskSnapshot;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/async.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Method for invoking a callback asynchronously.\r\n */\n\n/**\r\n * Returns a function that invokes f with its arguments asynchronously as a\r\n * microtask, i.e. as soon as possible after the current script returns back\r\n * into browser code.\r\n */\nfunction async(f) {\n return function () {\n var argsToForward = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n argsToForward[_i] = arguments[_i];\n }\n promise_external_resolve(true).then(function () {\n f.apply(null, argsToForward);\n });\n };\n}\n// CONCATENATED MODULE: ./src/storage/task.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Defines types for interacting with blob transfer tasks.\r\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\r\n * Represents a blob being uploaded. Can be used to pause/resume/cancel the\r\n * upload and manage callbacks for various events.\r\n */\nvar task_UploadTask = function () {\n /**\r\n * @param ref The firebaseStorage.Reference object this task came\r\n * from, untyped to avoid cyclic dependencies.\r\n * @param blob The blob to upload.\r\n */\n function UploadTask(ref, authWrapper, location, mappings, blob, metadata) {\n if (metadata === void 0) {\n metadata = null;\n }\n var _this = this;\n this.transferred_ = 0;\n this.needToFetchStatus_ = false;\n this.needToFetchMetadata_ = false;\n this.observers_ = [];\n this.error_ = null;\n this.uploadUrl_ = null;\n this.request_ = null;\n this.chunkMultiplier_ = 1;\n this.resolve_ = null;\n this.reject_ = null;\n this.ref_ = ref;\n this.authWrapper_ = authWrapper;\n this.location_ = location;\n this.blob_ = blob;\n this.metadata_ = metadata;\n this.mappings_ = mappings;\n this.resumable_ = this.shouldDoResumable_(this.blob_);\n this.state_ = InternalTaskState.RUNNING;\n this.errorHandler_ = function (error) {\n _this.request_ = null;\n _this.chunkMultiplier_ = 1;\n if (error.codeEquals(Code.CANCELED)) {\n _this.needToFetchStatus_ = true;\n _this.completeTransitions_();\n } else {\n _this.error_ = error;\n _this.transition_(InternalTaskState.ERROR);\n }\n };\n this.metadataErrorHandler_ = function (error) {\n _this.request_ = null;\n if (error.codeEquals(Code.CANCELED)) {\n _this.completeTransitions_();\n } else {\n _this.error_ = error;\n _this.transition_(InternalTaskState.ERROR);\n }\n };\n this.promise_ = make(function (resolve, reject) {\n _this.resolve_ = resolve;\n _this.reject_ = reject;\n _this.start_();\n });\n // Prevent uncaught rejections on the internal promise from bubbling out\n // to the top level with a dummy handler.\n this.promise_.then(null, function () {});\n }\n UploadTask.prototype.makeProgressCallback_ = function () {\n var _this = this;\n var sizeBefore = this.transferred_;\n return function (loaded, total) {\n _this.updateProgress_(sizeBefore + loaded);\n };\n };\n UploadTask.prototype.shouldDoResumable_ = function (blob) {\n return blob.size() > 256 * 1024;\n };\n UploadTask.prototype.start_ = function () {\n if (this.state_ !== InternalTaskState.RUNNING) {\n // This can happen if someone pauses us in a resume callback, for example.\n return;\n }\n if (this.request_ !== null) {\n return;\n }\n if (this.resumable_) {\n if (this.uploadUrl_ === null) {\n this.createResumable_();\n } else {\n if (this.needToFetchStatus_) {\n this.fetchStatus_();\n } else {\n if (this.needToFetchMetadata_) {\n // Happens if we miss the metadata on upload completion.\n this.fetchMetadata_();\n } else {\n this.continueUpload_();\n }\n }\n }\n } else {\n this.oneShotUpload_();\n }\n };\n UploadTask.prototype.resolveToken_ = function (callback) {\n var _this = this;\n this.authWrapper_.getAuthToken().then(function (authToken) {\n switch (_this.state_) {\n case InternalTaskState.RUNNING:\n callback(authToken);\n break;\n case InternalTaskState.CANCELING:\n _this.transition_(InternalTaskState.CANCELED);\n break;\n case InternalTaskState.PAUSING:\n _this.transition_(InternalTaskState.PAUSED);\n break;\n default:\n }\n });\n };\n // TODO(andysoto): assert false\n UploadTask.prototype.createResumable_ = function () {\n var _this = this;\n this.resolveToken_(function (authToken) {\n var requestInfo = createResumableUpload(_this.authWrapper_, _this.location_, _this.mappings_, _this.blob_, _this.metadata_);\n var createRequest = _this.authWrapper_.makeRequest(requestInfo, authToken);\n _this.request_ = createRequest;\n createRequest.getPromise().then(function (url) {\n _this.request_ = null;\n _this.uploadUrl_ = url;\n _this.needToFetchStatus_ = false;\n _this.completeTransitions_();\n }, _this.errorHandler_);\n });\n };\n UploadTask.prototype.fetchStatus_ = function () {\n var _this = this;\n // TODO(andysoto): assert(this.uploadUrl_ !== null);\n var url = this.uploadUrl_;\n this.resolveToken_(function (authToken) {\n var requestInfo = getResumableUploadStatus(_this.authWrapper_, _this.location_, url, _this.blob_);\n var statusRequest = _this.authWrapper_.makeRequest(requestInfo, authToken);\n _this.request_ = statusRequest;\n statusRequest.getPromise().then(function (status) {\n status = status;\n _this.request_ = null;\n _this.updateProgress_(status.current);\n _this.needToFetchStatus_ = false;\n if (status.finalized) {\n _this.needToFetchMetadata_ = true;\n }\n _this.completeTransitions_();\n }, _this.errorHandler_);\n });\n };\n UploadTask.prototype.continueUpload_ = function () {\n var _this = this;\n var chunkSize = resumableUploadChunkSize * this.chunkMultiplier_;\n var status = new ResumableUploadStatus(this.transferred_, this.blob_.size());\n // TODO(andysoto): assert(this.uploadUrl_ !== null);\n var url = this.uploadUrl_;\n this.resolveToken_(function (authToken) {\n var requestInfo;\n try {\n requestInfo = continueResumableUpload(_this.location_, _this.authWrapper_, url, _this.blob_, chunkSize, _this.mappings_, status, _this.makeProgressCallback_());\n } catch (e) {\n _this.error_ = e;\n _this.transition_(InternalTaskState.ERROR);\n return;\n }\n var uploadRequest = _this.authWrapper_.makeRequest(requestInfo, authToken);\n _this.request_ = uploadRequest;\n uploadRequest.getPromise().then(function (newStatus) {\n _this.increaseMultiplier_();\n _this.request_ = null;\n _this.updateProgress_(newStatus.current);\n if (newStatus.finalized) {\n _this.metadata_ = newStatus.metadata;\n _this.transition_(InternalTaskState.SUCCESS);\n } else {\n _this.completeTransitions_();\n }\n }, _this.errorHandler_);\n });\n };\n UploadTask.prototype.increaseMultiplier_ = function () {\n var currentSize = resumableUploadChunkSize * this.chunkMultiplier_;\n // Max chunk size is 32M.\n if (currentSize < 32 * 1024 * 1024) {\n this.chunkMultiplier_ *= 2;\n }\n };\n UploadTask.prototype.fetchMetadata_ = function () {\n var _this = this;\n this.resolveToken_(function (authToken) {\n var requestInfo = getMetadata(_this.authWrapper_, _this.location_, _this.mappings_);\n var metadataRequest = _this.authWrapper_.makeRequest(requestInfo, authToken);\n _this.request_ = metadataRequest;\n metadataRequest.getPromise().then(function (metadata) {\n _this.request_ = null;\n _this.metadata_ = metadata;\n _this.transition_(InternalTaskState.SUCCESS);\n }, _this.metadataErrorHandler_);\n });\n };\n UploadTask.prototype.oneShotUpload_ = function () {\n var _this = this;\n this.resolveToken_(function (authToken) {\n var requestInfo = multipartUpload(_this.authWrapper_, _this.location_, _this.mappings_, _this.blob_, _this.metadata_);\n var multipartRequest = _this.authWrapper_.makeRequest(requestInfo, authToken);\n _this.request_ = multipartRequest;\n multipartRequest.getPromise().then(function (metadata) {\n _this.request_ = null;\n _this.metadata_ = metadata;\n _this.updateProgress_(_this.blob_.size());\n _this.transition_(InternalTaskState.SUCCESS);\n }, _this.errorHandler_);\n });\n };\n UploadTask.prototype.updateProgress_ = function (transferred) {\n var old = this.transferred_;\n this.transferred_ = transferred;\n // A progress update can make the \"transferred\" value smaller (e.g. a\n // partial upload not completed by server, after which the \"transferred\"\n // value may reset to the value at the beginning of the request).\n if (this.transferred_ !== old) {\n this.notifyObservers_();\n }\n };\n UploadTask.prototype.transition_ = function (state) {\n if (this.state_ === state) {\n return;\n }\n switch (state) {\n case InternalTaskState.CANCELING:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING ||\n // this.state_ === InternalTaskState.PAUSING);\n this.state_ = state;\n if (this.request_ !== null) {\n this.request_.cancel();\n }\n break;\n case InternalTaskState.PAUSING:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING);\n this.state_ = state;\n if (this.request_ !== null) {\n this.request_.cancel();\n }\n break;\n case InternalTaskState.RUNNING:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.PAUSED ||\n // this.state_ === InternalTaskState.PAUSING);\n var wasPaused = this.state_ === InternalTaskState.PAUSED;\n this.state_ = state;\n if (wasPaused) {\n this.notifyObservers_();\n this.start_();\n }\n break;\n case InternalTaskState.PAUSED:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.PAUSING);\n this.state_ = state;\n this.notifyObservers_();\n break;\n case InternalTaskState.CANCELED:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.PAUSED ||\n // this.state_ === InternalTaskState.CANCELING);\n this.error_ = error_canceled();\n this.state_ = state;\n this.notifyObservers_();\n break;\n case InternalTaskState.ERROR:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING ||\n // this.state_ === InternalTaskState.PAUSING ||\n // this.state_ === InternalTaskState.CANCELING);\n this.state_ = state;\n this.notifyObservers_();\n break;\n case InternalTaskState.SUCCESS:\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING ||\n // this.state_ === InternalTaskState.PAUSING ||\n // this.state_ === InternalTaskState.CANCELING);\n this.state_ = state;\n this.notifyObservers_();\n break;\n }\n };\n UploadTask.prototype.completeTransitions_ = function () {\n switch (this.state_) {\n case InternalTaskState.PAUSING:\n this.transition_(InternalTaskState.PAUSED);\n break;\n case InternalTaskState.CANCELING:\n this.transition_(InternalTaskState.CANCELED);\n break;\n case InternalTaskState.RUNNING:\n this.start_();\n break;\n default:\n // TODO(andysoto): assert(false);\n break;\n }\n };\n Object.defineProperty(UploadTask.prototype, \"snapshot\", {\n get: function get() {\n var externalState = taskStateFromInternalTaskState(this.state_);\n return new UploadTaskSnapshot(this.transferred_, this.blob_.size(), externalState, this.metadata_, this, this.ref_);\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * Adds a callback for an event.\r\n * @param type The type of event to listen for.\r\n */\n UploadTask.prototype.on = function (type, nextOrObserver, error, completed) {\n if (nextOrObserver === void 0) {\n nextOrObserver = undefined;\n }\n if (error === void 0) {\n error = undefined;\n }\n if (completed === void 0) {\n completed = undefined;\n }\n function typeValidator(_p) {\n if (type !== TaskEvent.STATE_CHANGED) {\n throw \"Expected one of the event types: [\" + TaskEvent.STATE_CHANGED + \"].\";\n }\n }\n var nextOrObserverMessage = 'Expected a function or an Object with one of ' + '`next`, `error`, `complete` properties.';\n var nextValidator = nullFunctionSpec(true).validator;\n var observerValidator = looseObjectSpec(null, true).validator;\n function nextOrObserverValidator(p) {\n try {\n nextValidator(p);\n return;\n } catch (e) {}\n try {\n observerValidator(p);\n var anyDefined = isJustDef(p['next']) || isJustDef(p['error']) || isJustDef(p['complete']);\n if (!anyDefined) {\n throw '';\n }\n return;\n } catch (e) {\n throw nextOrObserverMessage;\n }\n }\n var specs = [stringSpec(typeValidator), looseObjectSpec(nextOrObserverValidator, true), nullFunctionSpec(true), nullFunctionSpec(true)];\n validate('on', specs, arguments);\n var self = this;\n function makeBinder(specs) {\n function binder(nextOrObserver, error, opt_complete) {\n if (specs !== null) {\n validate('on', specs, arguments);\n }\n var observer = new observer_Observer(nextOrObserver, error, completed);\n self.addObserver_(observer);\n return function () {\n self.removeObserver_(observer);\n };\n }\n return binder;\n }\n function binderNextOrObserverValidator(p) {\n if (p === null) {\n throw nextOrObserverMessage;\n }\n nextOrObserverValidator(p);\n }\n var binderSpecs = [looseObjectSpec(binderNextOrObserverValidator), nullFunctionSpec(true), nullFunctionSpec(true)];\n var typeOnly = !(isJustDef(nextOrObserver) || isJustDef(error) || isJustDef(completed));\n if (typeOnly) {\n return makeBinder(binderSpecs);\n } else {\n return makeBinder(null)(nextOrObserver, error, completed);\n }\n };\n /**\r\n * This object behaves like a Promise, and resolves with its snapshot data\r\n * when the upload completes.\r\n * The fulfillment callback. Promise chaining works as normal.\r\n * @param onRejected The rejection callback.\r\n */\n UploadTask.prototype.then = function (onFulfilled, onRejected) {\n return this.promise_.then(onFulfilled, onRejected);\n };\n /**\r\n * Equivalent to calling `then(null, onRejected)`.\r\n */\n UploadTask.prototype.catch = function (onRejected) {\n return this.then(null, onRejected);\n };\n /**\r\n * Adds the given observer.\r\n */\n UploadTask.prototype.addObserver_ = function (observer) {\n this.observers_.push(observer);\n this.notifyObserver_(observer);\n };\n /**\r\n * Removes the given observer.\r\n */\n UploadTask.prototype.removeObserver_ = function (observer) {\n remove(this.observers_, observer);\n };\n UploadTask.prototype.notifyObservers_ = function () {\n var _this = this;\n this.finishPromise_();\n var observers = array_clone(this.observers_);\n observers.forEach(function (observer) {\n _this.notifyObserver_(observer);\n });\n };\n UploadTask.prototype.finishPromise_ = function () {\n if (this.resolve_ !== null) {\n var triggered = true;\n switch (taskStateFromInternalTaskState(this.state_)) {\n case TaskState.SUCCESS:\n async(this.resolve_.bind(null, this.snapshot))();\n break;\n case TaskState.CANCELED:\n case TaskState.ERROR:\n var toCall = this.reject_;\n async(toCall.bind(null, this.error_))();\n break;\n default:\n triggered = false;\n break;\n }\n if (triggered) {\n this.resolve_ = null;\n this.reject_ = null;\n }\n }\n };\n UploadTask.prototype.notifyObserver_ = function (observer) {\n var externalState = taskStateFromInternalTaskState(this.state_);\n switch (externalState) {\n case TaskState.RUNNING:\n case TaskState.PAUSED:\n if (observer.next !== null) {\n async(observer.next.bind(observer, this.snapshot))();\n }\n break;\n case TaskState.SUCCESS:\n if (observer.complete !== null) {\n async(observer.complete.bind(observer))();\n }\n break;\n case TaskState.CANCELED:\n case TaskState.ERROR:\n if (observer.error !== null) {\n async(observer.error.bind(observer, this.error_))();\n }\n break;\n default:\n // TODO(andysoto): assert(false);\n if (observer.error !== null) {\n async(observer.error.bind(observer, this.error_))();\n }\n }\n };\n /**\r\n * Resumes a paused task. Has no effect on a currently running or failed task.\r\n * @return True if the operation took effect, false if ignored.\r\n */\n UploadTask.prototype.resume = function () {\n validate('resume', [], arguments);\n var valid = this.state_ === InternalTaskState.PAUSED || this.state_ === InternalTaskState.PAUSING;\n if (valid) {\n this.transition_(InternalTaskState.RUNNING);\n }\n return valid;\n };\n /**\r\n * Pauses a currently running task. Has no effect on a paused or failed task.\r\n * @return True if the operation took effect, false if ignored.\r\n */\n UploadTask.prototype.pause = function () {\n validate('pause', [], arguments);\n var valid = this.state_ === InternalTaskState.RUNNING;\n if (valid) {\n this.transition_(InternalTaskState.PAUSING);\n }\n return valid;\n };\n /**\r\n * Cancels a currently running or paused task. Has no effect on a complete or\r\n * failed task.\r\n * @return True if the operation took effect, false if ignored.\r\n */\n UploadTask.prototype.cancel = function () {\n validate('cancel', [], arguments);\n var valid = this.state_ === InternalTaskState.RUNNING || this.state_ === InternalTaskState.PAUSING;\n if (valid) {\n this.transition_(InternalTaskState.CANCELING);\n }\n return valid;\n };\n return UploadTask;\n}();\n\n// CONCATENATED MODULE: ./src/storage/reference.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Defines the Firebase Storage Reference class.\r\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\r\n * Provides methods to interact with a bucket in the Firebase Storage service.\r\n * @param location An fbs.location, or the URL at\r\n * which to base this object, in one of the following forms:\r\n * gs:///\r\n * http[s]://firebasestorage.googleapis.com/\r\n * /b//o/\r\n * Any query or fragment strings will be ignored in the http[s]\r\n * format. If no value is passed, the storage object will use a URL based on\r\n * the project ID of the base firebase.App instance.\r\n */\nvar reference_Reference = function () {\n function Reference(authWrapper, location) {\n this.authWrapper = authWrapper;\n if (location instanceof location_Location) {\n this.location = location;\n } else {\n this.location = location_Location.makeFromUrl(location);\n }\n }\n /**\r\n * @return The URL for the bucket and path this object references,\r\n * in the form gs:///\r\n * @override\r\n */\n Reference.prototype.toString = function () {\n validate('toString', [], arguments);\n return 'gs://' + this.location.bucket + '/' + this.location.path;\n };\n Reference.prototype.newRef = function (authWrapper, location) {\n return new Reference(authWrapper, location);\n };\n Reference.prototype.mappings = function () {\n return getMappings();\n };\n /**\r\n * @return A reference to the object obtained by\r\n * appending childPath, removing any duplicate, beginning, or trailing\r\n * slashes.\r\n */\n Reference.prototype.child = function (childPath) {\n validate('child', [stringSpec()], arguments);\n var newPath = child(this.location.path, childPath);\n var location = new location_Location(this.location.bucket, newPath);\n return this.newRef(this.authWrapper, location);\n };\n Object.defineProperty(Reference.prototype, \"parent\", {\n /**\r\n * @return A reference to the parent of the\r\n * current object, or null if the current object is the root.\r\n */\n get: function get() {\n var newPath = parent(this.location.path);\n if (newPath === null) {\n return null;\n }\n var location = new location_Location(this.location.bucket, newPath);\n return this.newRef(this.authWrapper, location);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"root\", {\n /**\r\n * @return An reference to the root of this\r\n * object's bucket.\r\n */\n get: function get() {\n var location = new location_Location(this.location.bucket, '');\n return this.newRef(this.authWrapper, location);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"bucket\", {\n get: function get() {\n return this.location.bucket;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"fullPath\", {\n get: function get() {\n return this.location.path;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"name\", {\n get: function get() {\n return lastComponent(this.location.path);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Reference.prototype, \"storage\", {\n get: function get() {\n return this.authWrapper.service();\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * Uploads a blob to this object's location.\r\n * @param data The blob to upload.\r\n * @return An UploadTask that lets you control and\r\n * observe the upload.\r\n */\n Reference.prototype.put = function (data, metadata) {\n if (metadata === void 0) {\n metadata = null;\n }\n validate('put', [uploadDataSpec(), metadataSpec(true)], arguments);\n this.throwIfRoot_('put');\n return new task_UploadTask(this, this.authWrapper, this.location, this.mappings(), new blob_FbsBlob(data), metadata);\n };\n /**\r\n * Uploads a string to this object's location.\r\n * @param string The string to upload.\r\n * @param opt_format The format of the string to upload.\r\n * @return An UploadTask that lets you control and\r\n * observe the upload.\r\n */\n Reference.prototype.putString = function (string, format, opt_metadata) {\n if (format === void 0) {\n format = StringFormat.RAW;\n }\n validate('putString', [stringSpec(), stringSpec(formatValidator, true), metadataSpec(true)], arguments);\n this.throwIfRoot_('putString');\n var data = dataFromString(format, string);\n var metadata = clone(opt_metadata);\n if (!isDef(metadata['contentType']) && isDef(data.contentType)) {\n metadata['contentType'] = data.contentType;\n }\n return new task_UploadTask(this, this.authWrapper, this.location, this.mappings(), new blob_FbsBlob(data.data, true), metadata);\n };\n /**\r\n * Deletes the object at this location.\r\n * @return A promise that resolves if the deletion succeeds.\r\n */\n Reference.prototype.delete = function () {\n validate('delete', [], arguments);\n this.throwIfRoot_('delete');\n var self = this;\n return this.authWrapper.getAuthToken().then(function (authToken) {\n var requestInfo = deleteObject(self.authWrapper, self.location);\n return self.authWrapper.makeRequest(requestInfo, authToken).getPromise();\n });\n };\n /**\r\n * A promise that resolves with the metadata for this object. If this\r\n * object doesn't exist or metadata cannot be retreived, the promise is\r\n * rejected.\r\n */\n Reference.prototype.getMetadata = function () {\n validate('getMetadata', [], arguments);\n this.throwIfRoot_('getMetadata');\n var self = this;\n return this.authWrapper.getAuthToken().then(function (authToken) {\n var requestInfo = getMetadata(self.authWrapper, self.location, self.mappings());\n return self.authWrapper.makeRequest(requestInfo, authToken).getPromise();\n });\n };\n /**\r\n * Updates the metadata for this object.\r\n * @param metadata The new metadata for the object.\r\n * Only values that have been explicitly set will be changed. Explicitly\r\n * setting a value to null will remove the metadata.\r\n * @return A promise that resolves\r\n * with the new metadata for this object.\r\n * @see firebaseStorage.Reference.prototype.getMetadata\r\n */\n Reference.prototype.updateMetadata = function (metadata) {\n validate('updateMetadata', [metadataSpec()], arguments);\n this.throwIfRoot_('updateMetadata');\n var self = this;\n return this.authWrapper.getAuthToken().then(function (authToken) {\n var requestInfo = updateMetadata(self.authWrapper, self.location, metadata, self.mappings());\n return self.authWrapper.makeRequest(requestInfo, authToken).getPromise();\n });\n };\n /**\r\n * @return A promise that resolves with the download\r\n * URL for this object.\r\n */\n Reference.prototype.getDownloadURL = function () {\n validate('getDownloadURL', [], arguments);\n this.throwIfRoot_('getDownloadURL');\n return this.getMetadata().then(function (metadata) {\n var url = metadata['downloadURLs'][0];\n if (isDef(url)) {\n return url;\n } else {\n throw noDownloadURL();\n }\n });\n };\n Reference.prototype.throwIfRoot_ = function (name) {\n if (this.location.path === '') {\n throw invalidRootOperation(name);\n }\n };\n return Reference;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/failrequest.ts\n\n/**\r\n * A request whose promise always fails.\r\n * @struct\r\n * @template T\r\n */\nvar failrequest_FailRequest = function () {\n function FailRequest(error) {\n this.promise_ = promise_external_reject(error);\n }\n /** @inheritDoc */\n FailRequest.prototype.getPromise = function () {\n return this.promise_;\n };\n /** @inheritDoc */\n FailRequest.prototype.cancel = function (appDelete) {\n if (appDelete === void 0) {\n appDelete = false;\n }\n };\n return FailRequest;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/requestmap.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n/**\r\n * @struct\r\n */\nvar requestmap_RequestMap = function () {\n function RequestMap() {\n this.map_ = {};\n this.id_ = minSafeInteger;\n }\n /**\r\n * Registers the given request with this map.\r\n * The request is unregistered when it completes.\r\n * @param r The request to register.\r\n */\n RequestMap.prototype.addRequest = function (r) {\n var id = this.id_;\n this.id_++;\n this.map_[id] = r;\n var self = this;\n function unmap() {\n delete self.map_[id];\n }\n r.getPromise().then(unmap, unmap);\n };\n /**\r\n * Cancels all registered requests.\r\n */\n RequestMap.prototype.clear = function () {\n forEach(this.map_, function (key, val) {\n if (val) {\n val.cancel(true);\n }\n });\n this.map_ = {};\n };\n return RequestMap;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/authwrapper.ts\n\n\n\n\n\n\n\n/**\r\n * @param app If null, getAuthToken always resolves with null.\r\n * @param service The storage service associated with this auth wrapper.\r\n * Untyped to avoid circular type dependencies.\r\n * @struct\r\n */\nvar authwrapper_AuthWrapper = function () {\n function AuthWrapper(app, maker, requestMaker, service, pool) {\n this.bucket_ = null;\n this.deleted_ = false;\n this.app_ = app;\n if (this.app_ !== null) {\n var options = this.app_.options;\n if (isDef(options)) {\n this.bucket_ = AuthWrapper.extractBucket_(options);\n }\n }\n this.storageRefMaker_ = maker;\n this.requestMaker_ = requestMaker;\n this.pool_ = pool;\n this.service_ = service;\n this.maxOperationRetryTime_ = defaultMaxOperationRetryTime;\n this.maxUploadRetryTime_ = defaultMaxUploadRetryTime;\n this.requestMap_ = new requestmap_RequestMap();\n }\n AuthWrapper.extractBucket_ = function (config) {\n var bucketString = config[configOption] || null;\n if (bucketString == null) {\n return null;\n }\n var loc = location_Location.makeFromBucketSpec(bucketString);\n return loc.bucket;\n };\n AuthWrapper.prototype.getAuthToken = function () {\n // TODO(andysoto): remove ifDef checks after firebase-app implements stubs\n // (b/28673818).\n if (this.app_ !== null && isDef(this.app_.INTERNAL) && isDef(this.app_.INTERNAL.getToken)) {\n return this.app_.INTERNAL.getToken().then(function (response) {\n if (response !== null) {\n return response.accessToken;\n } else {\n return null;\n }\n }, function (_error) {\n return null;\n });\n } else {\n return promise_external_resolve(null);\n }\n };\n AuthWrapper.prototype.bucket = function () {\n if (this.deleted_) {\n throw appDeleted();\n } else {\n return this.bucket_;\n }\n };\n /**\r\n * The service associated with this auth wrapper. Untyped to avoid circular\r\n * type dependencies.\r\n */\n AuthWrapper.prototype.service = function () {\n return this.service_;\n };\n /**\r\n * Returns a new firebaseStorage.Reference object referencing this AuthWrapper\r\n * at the given Location.\r\n * @param loc The Location.\r\n * @return Actually a firebaseStorage.Reference, typing not allowed\r\n * because of circular dependency problems.\r\n */\n AuthWrapper.prototype.makeStorageReference = function (loc) {\n return this.storageRefMaker_(this, loc);\n };\n AuthWrapper.prototype.makeRequest = function (requestInfo, authToken) {\n if (!this.deleted_) {\n var request = this.requestMaker_(requestInfo, authToken, this.pool_);\n this.requestMap_.addRequest(request);\n return request;\n } else {\n return new failrequest_FailRequest(appDeleted());\n }\n };\n /**\r\n * Stop running requests and prevent more from being created.\r\n */\n AuthWrapper.prototype.deleteApp = function () {\n this.deleted_ = true;\n this.app_ = null;\n this.requestMap_.clear();\n };\n AuthWrapper.prototype.maxUploadRetryTime = function () {\n return this.maxUploadRetryTime_;\n };\n AuthWrapper.prototype.setMaxUploadRetryTime = function (time) {\n this.maxUploadRetryTime_ = time;\n };\n AuthWrapper.prototype.maxOperationRetryTime = function () {\n return this.maxOperationRetryTime_;\n };\n AuthWrapper.prototype.setMaxOperationRetryTime = function (time) {\n this.maxOperationRetryTime_ = time;\n };\n return AuthWrapper;\n}();\n\n// CONCATENATED MODULE: ./src/storage/implementation/backoff.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @param f May be invoked\r\n * before the function returns.\r\n * @param callback Get all the arguments passed to the function\r\n * passed to f, including the initial boolean.\r\n */\nfunction start(f, callback, timeout) {\n // TODO(andysoto): make this code cleaner (probably refactor into an actual\n // type instead of a bunch of functions with state shared in the closure)\n var waitSeconds = 1;\n // Would type this as \"number\" but that doesn't work for Node so ¯\\_(ツ)_/¯\n var timeoutId = null;\n var hitTimeout = false;\n var cancelState = 0;\n function canceled() {\n return cancelState === 2;\n }\n var triggeredCallback = false;\n function triggerCallback() {\n if (!triggeredCallback) {\n triggeredCallback = true;\n callback.apply(null, arguments);\n }\n }\n function callWithDelay(millis) {\n timeoutId = setTimeout(function () {\n timeoutId = null;\n f(handler, canceled());\n }, millis);\n }\n function handler(success) {\n var var_args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n var_args[_i - 1] = arguments[_i];\n }\n if (triggeredCallback) {\n return;\n }\n if (success) {\n triggerCallback.apply(null, arguments);\n return;\n }\n var mustStop = canceled() || hitTimeout;\n if (mustStop) {\n triggerCallback.apply(null, arguments);\n return;\n }\n if (waitSeconds < 64) {\n /* TODO(andysoto): don't back off so quickly if we know we're offline. */\n waitSeconds *= 2;\n }\n var waitMillis;\n if (cancelState === 1) {\n cancelState = 2;\n waitMillis = 0;\n } else {\n waitMillis = (waitSeconds + Math.random()) * 1000;\n }\n callWithDelay(waitMillis);\n }\n var stopped = false;\n function stop(wasTimeout) {\n if (stopped) {\n return;\n }\n stopped = true;\n if (triggeredCallback) {\n return;\n }\n if (timeoutId !== null) {\n if (!wasTimeout) {\n cancelState = 2;\n }\n clearTimeout(timeoutId);\n callWithDelay(0);\n } else {\n if (!wasTimeout) {\n cancelState = 1;\n }\n }\n }\n callWithDelay(0);\n setTimeout(function () {\n hitTimeout = true;\n stop(true);\n }, timeout);\n return stop;\n}\n/**\r\n * Stops the retry loop from repeating.\r\n * If the function is currently \"in between\" retries, it is invoked immediately\r\n * with the second parameter as \"true\". Otherwise, it will be invoked once more\r\n * after the current invocation finishes iff the current invocation would have\r\n * triggered another retry.\r\n */\nfunction stop(id) {\n id(false);\n}\n// CONCATENATED MODULE: ./src/storage/implementation/request.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n/**\r\n * @fileoverview Defines methods used to actually send HTTP requests from\r\n * abstract representations.\r\n */\n\n\n\n\n\n\n\n\n/**\r\n * @struct\r\n * @template T\r\n */\nvar request_NetworkRequest = function () {\n function NetworkRequest(url, method, headers, body, successCodes, additionalRetryCodes, callback, errorCallback, timeout, progressCallback, pool) {\n this.pendingXhr_ = null;\n this.backoffId_ = null;\n this.resolve_ = null;\n this.reject_ = null;\n this.canceled_ = false;\n this.appDelete_ = false;\n this.url_ = url;\n this.method_ = method;\n this.headers_ = headers;\n this.body_ = body;\n this.successCodes_ = successCodes.slice();\n this.additionalRetryCodes_ = additionalRetryCodes.slice();\n this.callback_ = callback;\n this.errorCallback_ = errorCallback;\n this.progressCallback_ = progressCallback;\n this.timeout_ = timeout;\n this.pool_ = pool;\n var self = this;\n this.promise_ = make(function (resolve, reject) {\n self.resolve_ = resolve;\n self.reject_ = reject;\n self.start_();\n });\n }\n /**\r\n * Actually starts the retry loop.\r\n */\n NetworkRequest.prototype.start_ = function () {\n var self = this;\n function doTheRequest(backoffCallback, canceled) {\n if (canceled) {\n backoffCallback(false, new RequestEndStatus(false, null, true));\n return;\n }\n var xhr = self.pool_.createXhrIo();\n self.pendingXhr_ = xhr;\n function progressListener(progressEvent) {\n var loaded = progressEvent.loaded;\n var total = progressEvent.lengthComputable ? progressEvent.total : -1;\n if (self.progressCallback_ !== null) {\n self.progressCallback_(loaded, total);\n }\n }\n if (self.progressCallback_ !== null) {\n xhr.addUploadProgressListener(progressListener);\n }\n xhr.send(self.url_, self.method_, self.body_, self.headers_).then(function (xhr) {\n if (self.progressCallback_ !== null) {\n xhr.removeUploadProgressListener(progressListener);\n }\n self.pendingXhr_ = null;\n xhr = xhr;\n var hitServer = xhr.getErrorCode() === ErrorCode.NO_ERROR;\n var status = xhr.getStatus();\n if (!hitServer || self.isRetryStatusCode_(status)) {\n var wasCanceled = xhr.getErrorCode() === ErrorCode.ABORT;\n backoffCallback(false, new RequestEndStatus(false, null, wasCanceled));\n return;\n }\n var successCode = array_contains(self.successCodes_, status);\n backoffCallback(true, new RequestEndStatus(successCode, xhr));\n });\n }\n /**\r\n * @param requestWentThrough True if the request eventually went\r\n * through, false if it hit the retry limit or was canceled.\r\n */\n function backoffDone(requestWentThrough, status) {\n var resolve = self.resolve_;\n var reject = self.reject_;\n var xhr = status.xhr;\n if (status.wasSuccessCode) {\n try {\n var result = self.callback_(xhr, xhr.getResponseText());\n if (isJustDef(result)) {\n resolve(result);\n } else {\n resolve();\n }\n } catch (e) {\n reject(e);\n }\n } else {\n if (xhr !== null) {\n var err = unknown();\n err.setServerResponseProp(xhr.getResponseText());\n if (self.errorCallback_) {\n reject(self.errorCallback_(xhr, err));\n } else {\n reject(err);\n }\n } else {\n if (status.canceled) {\n var err = self.appDelete_ ? appDeleted() : error_canceled();\n reject(err);\n } else {\n var err = retryLimitExceeded();\n reject(err);\n }\n }\n }\n }\n if (this.canceled_) {\n backoffDone(false, new RequestEndStatus(false, null, true));\n } else {\n this.backoffId_ = start(doTheRequest, backoffDone, this.timeout_);\n }\n };\n /** @inheritDoc */\n NetworkRequest.prototype.getPromise = function () {\n return this.promise_;\n };\n /** @inheritDoc */\n NetworkRequest.prototype.cancel = function (appDelete) {\n this.canceled_ = true;\n this.appDelete_ = appDelete || false;\n if (this.backoffId_ !== null) {\n stop(this.backoffId_);\n }\n if (this.pendingXhr_ !== null) {\n this.pendingXhr_.abort();\n }\n };\n NetworkRequest.prototype.isRetryStatusCode_ = function (status) {\n // The codes for which to retry came from this page:\n // https://cloud.google.com/storage/docs/exponential-backoff\n var isFiveHundredCode = status >= 500 && status < 600;\n var extraRetryCodes = [\n // Request Timeout: web server didn't receive full request in time.\n 408,\n // Too Many Requests: you're getting rate-limited, basically.\n 429];\n var isExtraRetryCode = array_contains(extraRetryCodes, status);\n var isRequestSpecificRetryCode = array_contains(this.additionalRetryCodes_, status);\n return isFiveHundredCode || isExtraRetryCode || isRequestSpecificRetryCode;\n };\n return NetworkRequest;\n}();\n/**\r\n * A collection of information about the result of a network request.\r\n * @param opt_canceled Defaults to false.\r\n * @struct\r\n */\nvar RequestEndStatus = function () {\n function RequestEndStatus(wasSuccessCode, xhr, opt_canceled) {\n this.wasSuccessCode = wasSuccessCode;\n this.xhr = xhr;\n this.canceled = !!opt_canceled;\n }\n return RequestEndStatus;\n}();\n\nfunction addAuthHeader_(headers, authToken) {\n if (authToken !== null && authToken.length > 0) {\n headers['Authorization'] = 'Firebase ' + authToken;\n }\n}\nfunction addVersionHeader_(headers) {\n var number = typeof firebase !== 'undefined' ? firebase.SDK_VERSION : 'AppManager';\n headers['X-Firebase-Storage-Version'] = 'webjs/' + number;\n}\n/**\r\n * @template T\r\n */\nfunction makeRequest(requestInfo, authToken, pool) {\n var queryPart = makeQueryString(requestInfo.urlParams);\n var url = requestInfo.url + queryPart;\n var headers = clone(requestInfo.headers);\n addAuthHeader_(headers, authToken);\n addVersionHeader_(headers);\n return new request_NetworkRequest(url, requestInfo.method, headers, requestInfo.body, requestInfo.successCodes, requestInfo.additionalRetryCodes, requestInfo.handler, requestInfo.errorHandler, requestInfo.timeout, requestInfo.progressCallback, pool);\n}\n// CONCATENATED MODULE: ./src/storage/service.ts\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n/**\r\n * A service that provides firebaseStorage.Reference instances.\r\n * @param opt_url gs:// url to a custom Storage Bucket\r\n *\r\n * @struct\r\n */\nvar service_Service = function () {\n function Service(app, pool, url) {\n this.bucket_ = null;\n function maker(authWrapper, loc) {\n return new reference_Reference(authWrapper, loc);\n }\n this.authWrapper_ = new authwrapper_AuthWrapper(app, maker, makeRequest, this, pool);\n this.app_ = app;\n if (url != null) {\n this.bucket_ = location_Location.makeFromBucketSpec(url);\n } else {\n var authWrapperBucket = this.authWrapper_.bucket();\n if (authWrapperBucket != null) {\n this.bucket_ = new location_Location(authWrapperBucket, '');\n }\n }\n this.internals_ = new service_ServiceInternals(this);\n }\n /**\r\n * Returns a firebaseStorage.Reference for the given path in the default\r\n * bucket.\r\n */\n Service.prototype.ref = function (path) {\n function validator(path) {\n if (/^[A-Za-z]+:\\/\\//.test(path)) {\n throw 'Expected child path but got a URL, use refFromURL instead.';\n }\n }\n validate('ref', [stringSpec(validator, true)], arguments);\n if (this.bucket_ == null) {\n throw new Error('No Storage Bucket defined in Firebase Options.');\n }\n var ref = new reference_Reference(this.authWrapper_, this.bucket_);\n if (path != null) {\n return ref.child(path);\n } else {\n return ref;\n }\n };\n /**\r\n * Returns a firebaseStorage.Reference object for the given absolute URL,\r\n * which must be a gs:// or http[s]:// URL.\r\n */\n Service.prototype.refFromURL = function (url) {\n function validator(p) {\n if (!/^[A-Za-z]+:\\/\\//.test(p)) {\n throw 'Expected full URL but got a child path, use ref instead.';\n }\n try {\n location_Location.makeFromUrl(p);\n } catch (e) {\n throw 'Expected valid full URL but got an invalid one.';\n }\n }\n validate('refFromURL', [stringSpec(validator, false)], arguments);\n return new reference_Reference(this.authWrapper_, url);\n };\n Object.defineProperty(Service.prototype, \"maxUploadRetryTime\", {\n get: function get() {\n return this.authWrapper_.maxUploadRetryTime();\n },\n enumerable: true,\n configurable: true\n });\n Service.prototype.setMaxUploadRetryTime = function (time) {\n validate('setMaxUploadRetryTime', [nonNegativeNumberSpec()], arguments);\n this.authWrapper_.setMaxUploadRetryTime(time);\n };\n Object.defineProperty(Service.prototype, \"maxOperationRetryTime\", {\n get: function get() {\n return this.authWrapper_.maxOperationRetryTime();\n },\n enumerable: true,\n configurable: true\n });\n Service.prototype.setMaxOperationRetryTime = function (time) {\n validate('setMaxOperationRetryTime', [nonNegativeNumberSpec()], arguments);\n this.authWrapper_.setMaxOperationRetryTime(time);\n };\n Object.defineProperty(Service.prototype, \"app\", {\n get: function get() {\n return this.app_;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Service.prototype, \"INTERNAL\", {\n get: function get() {\n return this.internals_;\n },\n enumerable: true,\n configurable: true\n });\n return Service;\n}();\n\n/**\r\n * @struct\r\n */\nvar service_ServiceInternals = function () {\n function ServiceInternals(service) {\n this.service_ = service;\n }\n /**\r\n * Called when the associated app is deleted.\r\n * @see {!fbs.AuthWrapper.prototype.deleteApp}\r\n */\n ServiceInternals.prototype.delete = function () {\n this.service_.authWrapper_.deleteApp();\n return promise_external_resolve(undefined);\n };\n return ServiceInternals;\n}();\n\n// CONCATENATED MODULE: ./src/storage.ts\n/* harmony export (immutable) */ __webpack_exports__[\"registerStorage\"] = registerStorage;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__app__ = __webpack_require__(5);\n/**\r\n* Copyright 2017 Google Inc.\r\n*\r\n* Licensed under the Apache License, Version 2.0 (the \"License\");\r\n* you may not use this file except in compliance with the License.\r\n* You may obtain a copy of the License at\r\n*\r\n* http://www.apache.org/licenses/LICENSE-2.0\r\n*\r\n* Unless required by applicable law or agreed to in writing, software\r\n* distributed under the License is distributed on an \"AS IS\" BASIS,\r\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n* See the License for the specific language governing permissions and\r\n* limitations under the License.\r\n*/\n\n\n\n\n\n\n\n/**\r\n * Type constant for Firebase Storage.\r\n */\nvar STORAGE_TYPE = 'storage';\nfunction factory(app, unused, opt_url) {\n return new service_Service(app, new xhriopool_XhrIoPool(), opt_url);\n}\nfunction registerStorage(instance) {\n var namespaceExports = {\n // no-inline\n 'TaskState': TaskState,\n 'TaskEvent': TaskEvent,\n 'StringFormat': StringFormat,\n 'Storage': service_Service,\n 'Reference': reference_Reference\n };\n instance.INTERNAL.registerService(STORAGE_TYPE, factory, namespaceExports, undefined,\n // Allow multiple storage instances per app.\n true);\n}\nregisterStorage(__WEBPACK_IMPORTED_MODULE_5__app__[\"default\"]);\n\n/***/ })\n\n},[22]);\n } catch(error) {\n throw new Error(\n 'Cannot instantiate firebase-storage.js - ' +\n 'be sure to load firebase-app.js first.'\n )\n }\n\n\n// WEBPACK FOOTER //\n// firebase-storage.js","/**\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*/\nimport {configOption} from './constants';\n\nexport class FirebaseStorageError implements Error {\n private code_: string;\n private message_: string;\n private serverResponse_: string|null;\n private name_: string;\n\n constructor(code: Code, message: string) {\n this.code_ = prependCode(code);\n this.message_ = 'Firebase Storage: ' + message;\n this.serverResponse_ = null;\n this.name_ = 'FirebaseError';\n }\n\n codeProp(): string {\n return this.code;\n }\n\n codeEquals(code: Code): boolean {\n return prependCode(code) === this.codeProp();\n }\n\n serverResponseProp(): string|null {\n return this.serverResponse_;\n }\n\n setServerResponseProp(serverResponse: string|null) {\n this.serverResponse_ = serverResponse;\n }\n\n get name(): string {\n return this.name_;\n }\n\n get code(): string {\n return this.code_;\n }\n\n get message(): string {\n return this.message_;\n }\n\n get serverResponse(): null|string {\n return this.serverResponse_;\n }\n}\n\nexport const errors = {};\n\n/**\n * @enum {string}\n */\nexport type Code = string;\nexport const Code = {\n // Shared between all platforms\n UNKNOWN: 'unknown',\n OBJECT_NOT_FOUND: 'object-not-found',\n BUCKET_NOT_FOUND: 'bucket-not-found',\n PROJECT_NOT_FOUND: 'project-not-found',\n QUOTA_EXCEEDED: 'quota-exceeded',\n UNAUTHENTICATED: 'unauthenticated',\n UNAUTHORIZED: 'unauthorized',\n RETRY_LIMIT_EXCEEDED: 'retry-limit-exceeded',\n INVALID_CHECKSUM: 'invalid-checksum',\n CANCELED: 'canceled',\n // JS specific\n INVALID_EVENT_NAME: 'invalid-event-name',\n INVALID_URL: 'invalid-url',\n INVALID_DEFAULT_BUCKET: 'invalid-default-bucket',\n NO_DEFAULT_BUCKET: 'no-default-bucket',\n CANNOT_SLICE_BLOB: 'cannot-slice-blob',\n SERVER_FILE_WRONG_SIZE: 'server-file-wrong-size',\n NO_DOWNLOAD_URL: 'no-download-url',\n INVALID_ARGUMENT: 'invalid-argument',\n INVALID_ARGUMENT_COUNT: 'invalid-argument-count',\n APP_DELETED: 'app-deleted',\n INVALID_ROOT_OPERATION: 'invalid-root-operation',\n INVALID_FORMAT: 'invalid-format',\n INTERNAL_ERROR: 'internal-error'\n};\n\nexport function prependCode(code: Code): string {\n return 'storage/' + code;\n}\n\nexport function unknown(): FirebaseStorageError {\n let message =\n 'An unknown error occurred, please check the error payload for ' +\n 'server response.';\n return new FirebaseStorageError(Code.UNKNOWN, message);\n}\n\nexport function objectNotFound(path: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.OBJECT_NOT_FOUND, 'Object \\'' + path + '\\' does not exist.');\n}\n\nexport function bucketNotFound(bucket: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.BUCKET_NOT_FOUND, 'Bucket \\'' + bucket + '\\' does not exist.');\n}\n\nexport function projectNotFound(project: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.PROJECT_NOT_FOUND, 'Project \\'' + project + '\\' does not exist.');\n}\n\nexport function quotaExceeded(bucket: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.QUOTA_EXCEEDED,\n 'Quota for bucket \\'' + bucket + '\\' exceeded, please view quota on ' +\n 'https://firebase.google.com/pricing/.');\n}\n\nexport function unauthenticated(): FirebaseStorageError {\n let message =\n 'User is not authenticated, please authenticate using Firebase ' +\n 'Authentication and try again.';\n return new FirebaseStorageError(Code.UNAUTHENTICATED, message);\n}\n\nexport function unauthorized(path: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.UNAUTHORIZED,\n 'User does not have permission to access \\'' + path + '\\'.');\n}\n\nexport function retryLimitExceeded(): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.RETRY_LIMIT_EXCEEDED,\n 'Max retry time for operation exceeded, please try again.');\n}\n\nexport function invalidChecksum(\n path: string, checksum: string, calculated: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.INVALID_CHECKSUM,\n 'Uploaded/downloaded object \\'' + path + '\\' has checksum \\'' + checksum +\n '\\' which does not match \\'' + calculated +\n '\\'. Please retry the upload/download.');\n}\n\nexport function canceled(): FirebaseStorageError {\n return new FirebaseStorageError(Code.CANCELED, 'User canceled the upload/download.');\n}\n\nexport function invalidEventName(name: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.INVALID_EVENT_NAME, 'Invalid event name \\'' + name + '\\'.');\n}\n\nexport function invalidUrl(url: string): FirebaseStorageError {\n return new FirebaseStorageError(Code.INVALID_URL, 'Invalid URL \\'' + url + '\\'.');\n}\n\nexport function invalidDefaultBucket(bucket: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.INVALID_DEFAULT_BUCKET,\n 'Invalid default bucket \\'' + bucket + '\\'.');\n}\n\nexport function noDefaultBucket(): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.NO_DEFAULT_BUCKET,\n 'No default bucket ' +\n 'found. Did you set the \\'' + configOption +\n '\\' property when initializing the app?');\n}\n\nexport function cannotSliceBlob(): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.CANNOT_SLICE_BLOB,\n 'Cannot slice blob for upload. Please retry the upload.');\n}\n\nexport function serverFileWrongSize(): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.SERVER_FILE_WRONG_SIZE,\n 'Server recorded incorrect upload file size, please retry the upload.');\n}\n\nexport function noDownloadURL(): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.NO_DOWNLOAD_URL, 'The given file does not have any download URLs.');\n}\n\nexport function invalidArgument(\n index: number, fnName: string, message: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.INVALID_ARGUMENT,\n 'Invalid argument in `' + fnName + '` at index ' + index + ': ' +\n message);\n}\n\nexport function invalidArgumentCount(\n argMin: number, argMax: number, fnName: string, real: number): FirebaseStorageError {\n let countPart;\n let plural;\n if (argMin === argMax) {\n countPart = argMin;\n plural = argMin === 1 ? 'argument' : 'arguments';\n } else {\n countPart = 'between ' + argMin + ' and ' + argMax;\n plural = 'arguments';\n }\n return new FirebaseStorageError(\n Code.INVALID_ARGUMENT_COUNT,\n 'Invalid argument count in `' + fnName + '`: Expected ' + countPart +\n ' ' + plural + ', received ' + real + '.');\n}\n\nexport function appDeleted(): FirebaseStorageError {\n return new FirebaseStorageError(Code.APP_DELETED, 'The Firebase app was deleted.');\n}\n\n/**\n * @param name The name of the operation that was invalid.\n */\nexport function invalidRootOperation(name: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.INVALID_ROOT_OPERATION,\n 'The operation \\'' + name +\n '\\' cannot be performed on a root reference, create a non-root ' +\n 'reference using child, such as .child(\\'file.png\\').');\n}\n\n/**\n * @param format The format that was not valid.\n * @param message A message describing the format violation.\n */\nexport function invalidFormat(format: string, message: string): FirebaseStorageError {\n return new FirebaseStorageError(\n Code.INVALID_FORMAT,\n 'String does not match format \\'' + format + '\\': ' + message);\n}\n\n/**\n * @param message A message describing the internal error.\n */\nexport function internalError(message: string): FirebaseStorageError {\n throw new FirebaseStorageError(Code.INTERNAL_ERROR, 'Internal error: ' + message);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/error.ts","/**\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*/\nimport * as errorsExports from './error';\nimport {errors} from './error';\n\n/**\n * @enum {string}\n */\nexport type StringFormat = string;\nexport const StringFormat = {\n RAW: 'raw',\n BASE64: 'base64',\n BASE64URL: 'base64url',\n DATA_URL: 'data_url'\n};\n\nexport function formatValidator(stringFormat: string) {\n switch (stringFormat) {\n case StringFormat.RAW:\n case StringFormat.BASE64:\n case StringFormat.BASE64URL:\n case StringFormat.DATA_URL:\n return;\n default:\n throw 'Expected one of the event types: [' + StringFormat.RAW + ', ' +\n StringFormat.BASE64 + ', ' + StringFormat.BASE64URL + ', ' +\n StringFormat.DATA_URL + '].';\n }\n}\n\n/**\n * @struct\n */\nexport class StringData {\n contentType: string|null;\n\n constructor(public data: Uint8Array, opt_contentType?: string|null) {\n this.contentType = opt_contentType || null;\n }\n}\n\nexport function dataFromString(\n format: StringFormat, string: string): StringData {\n switch (format) {\n case StringFormat.RAW:\n return new StringData(utf8Bytes_(string));\n case StringFormat.BASE64:\n case StringFormat.BASE64URL:\n return new StringData(base64Bytes_(format, string));\n case StringFormat.DATA_URL:\n return new StringData(dataURLBytes_(string), dataURLContentType_(string));\n }\n\n // assert(false);\n throw errorsExports.unknown();\n}\n\nexport function utf8Bytes_(string: string): Uint8Array {\n let b = [];\n for (let i = 0; i < string.length; i++) {\n let c = string.charCodeAt(i);\n if (c <= 127) {\n b.push(c);\n } else {\n if (c <= 2047) {\n b.push(192 | c >> 6, 128 | c & 63);\n } else {\n if ((c & 64512) == 55296) {\n // The start of a surrogate pair.\n let valid = i < string.length - 1 &&\n (string.charCodeAt(i + 1) & 64512) == 56320;\n if (!valid) {\n // The second surrogate wasn't there.\n b.push(239, 191, 189);\n } else {\n let hi = c;\n let lo = string.charCodeAt(++i);\n c = 65536 | (hi & 1023) << 10 | lo & 1023;\n b.push(\n 240 | c >> 18, 128 | c >> 12 & 63, 128 | c >> 6 & 63,\n 128 | c & 63);\n }\n } else {\n if ((c & 64512) == 56320) {\n // Invalid low surrogate.\n b.push(239, 191, 189);\n } else {\n b.push(224 | c >> 12, 128 | c >> 6 & 63, 128 | c & 63);\n }\n }\n }\n }\n }\n return new Uint8Array(b);\n}\n\nexport function percentEncodedBytes_(string: string): Uint8Array {\n let decoded;\n try {\n decoded = decodeURIComponent(string);\n } catch (e) {\n throw errorsExports.invalidFormat(\n StringFormat.DATA_URL, 'Malformed data URL.');\n }\n return utf8Bytes_(decoded);\n}\n\nexport function base64Bytes_(format: StringFormat, string: string): Uint8Array {\n switch (format) {\n case StringFormat.BASE64: {\n let hasMinus = string.indexOf('-') !== -1;\n let hasUnder = string.indexOf('_') !== -1;\n if (hasMinus || hasUnder) {\n let invalidChar = hasMinus ? '-' : '_';\n throw errorsExports.invalidFormat(\n format,\n 'Invalid character \\'' + invalidChar +\n '\\' found: is it base64url encoded?');\n }\n break;\n }\n case StringFormat.BASE64URL: {\n let hasPlus = string.indexOf('+') !== -1;\n let hasSlash = string.indexOf('/') !== -1;\n if (hasPlus || hasSlash) {\n let invalidChar = hasPlus ? '+' : '/';\n throw errorsExports.invalidFormat(\n format,\n 'Invalid character \\'' + invalidChar +\n '\\' found: is it base64 encoded?');\n }\n string = string.replace(/-/g, '+').replace(/_/g, '/');\n break;\n }\n }\n let bytes;\n try {\n bytes = atob(string);\n } catch (e) {\n throw errorsExports.invalidFormat(format, 'Invalid character found');\n }\n let array = new Uint8Array(bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n array[i] = bytes.charCodeAt(i);\n }\n return array;\n}\n\n/**\n * @struct\n */\nclass DataURLParts {\n base64: boolean = false;\n contentType: string|null = null;\n rest: string;\n\n constructor(dataURL: string) {\n let matches = dataURL.match(/^data:([^,]+)?,/);\n if (matches === null) {\n throw errorsExports.invalidFormat(\n StringFormat.DATA_URL,\n 'Must be formatted \\'data:[][;base64],');\n }\n let middle = matches[1] || null;\n if (middle != null) {\n this.base64 = endsWith(middle, ';base64');\n this.contentType = this.base64 ?\n middle.substring(0, middle.length - ';base64'.length) :\n middle;\n }\n this.rest = dataURL.substring(dataURL.indexOf(',') + 1);\n }\n}\n\nexport function dataURLBytes_(string: string): Uint8Array {\n let parts = new DataURLParts(string);\n if (parts.base64) {\n return base64Bytes_(StringFormat.BASE64, parts.rest);\n } else {\n return percentEncodedBytes_(parts.rest);\n }\n}\n\nexport function dataURLContentType_(string: string): string|null {\n let parts = new DataURLParts(string);\n return parts.contentType;\n}\n\nfunction endsWith(s: string, end: string): boolean {\n const longEnough = s.length >= end.length;\n if (!longEnough) {\n return false;\n }\n\n return s.substring(s.length - end.length) === end;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/string.ts","/**\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 Enumerations used for upload tasks.\n */\n\n/**\n * Enum for task events.\n * @enum {string}\n */\nexport type TaskEvent = string;\nexport const TaskEvent = {\n /** Triggered whenever the task changes or progress is updated. */\n STATE_CHANGED: 'state_changed'\n};\n\n/**\n * Internal enum for task state.\n * @enum {string}\n */\nexport type InternalTaskState = string;\nexport const InternalTaskState = {\n RUNNING: 'running',\n PAUSING: 'pausing',\n PAUSED: 'paused',\n SUCCESS: 'success',\n CANCELING: 'canceling',\n CANCELED: 'canceled',\n ERROR: 'error'\n};\n\n/**\n * External (API-surfaced) enum for task state.\n * @enum {string}\n */\nexport type TaskState = string;\nexport const TaskState = {\n /** The task is currently transferring data. */\n RUNNING: 'running',\n /** The task was paused by the user. */\n PAUSED: 'paused',\n /** The task completed successfully. */\n SUCCESS: 'success',\n /** The task was canceled. */\n CANCELED: 'canceled',\n /** The task failed with an error. */\n ERROR: 'error'\n};\n\nexport function taskStateFromInternalTaskState(state: InternalTaskState):\n TaskState {\n switch (state) {\n case InternalTaskState.RUNNING:\n case InternalTaskState.PAUSING:\n case InternalTaskState.CANCELING:\n return TaskState.RUNNING;\n case InternalTaskState.PAUSED:\n return TaskState.PAUSED;\n case InternalTaskState.SUCCESS:\n return TaskState.SUCCESS;\n case InternalTaskState.CANCELED:\n return TaskState.CANCELED;\n case InternalTaskState.ERROR:\n return TaskState.ERROR;\n default:\n\n // TODO(andysoto): assert(false);\n return TaskState.ERROR;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/taskenums.ts","/**\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 Contains methods for working with objects.\n */\nexport function contains(\n obj: Object, prop: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nexport function forEach(\n obj: {[key: string]: T},\n f: (p1: string, p2: T) => void) {\n for (let key in obj) {\n if (contains(obj, key)) {\n f(key, obj[key]);\n }\n }\n}\n\nexport function clone(obj?: {[key: string]: any}|null): T {\n if (obj == null) {\n return {} as T;\n }\n\n let c: {[name: string]: any} = {};\n forEach(obj, function(key, val) {\n c[key] = val;\n });\n return c as T;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/object.ts","/**\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 Implements the promise abstraction interface for external\n * (public SDK) packaging, which just passes through to the firebase-app impl.\n */\n\n/**\n * @template T\n * @param {function((function(T): void),\n * (function(!Error): void))} resolver\n */\n\nimport { PromiseImpl } from \"../../utils/promise\";\n\nexport function make(resolver: (p1: (p1: T) => void, \n p2: (p1: Error) => void) => void): Promise {\n return new PromiseImpl(resolver);\n}\n\n/**\n * @template T\n */\nexport function resolve(value: T): Promise {\n return (PromiseImpl.resolve(value) as Promise);\n}\n\nexport function reject(error: Error): Promise {\n return (PromiseImpl.reject(error) as Promise);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/promise_external.ts","/**\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 * @return False if the object is undefined or null, true otherwise.\n */\nexport function isDef(p: any): boolean {\n return p != null;\n}\n\nexport function isJustDef(p: any): boolean {\n return p !== void 0;\n}\n\nexport function isFunction(p: any): boolean {\n return typeof p === 'function';\n}\n\nexport function isObject(p: any): boolean {\n return typeof p === 'object';\n}\n\nexport function isNonNullObject(p: any): boolean {\n return isObject(p) && p !== null;\n}\n\nexport function isNonArrayObject(p: any): boolean {\n return isObject(p) && !Array.isArray(p);\n}\n\nexport function isString(p: any): boolean {\n return typeof p === 'string' || p instanceof String;\n}\n\nexport function isNumber(p: any): boolean {\n return typeof p === 'number' || p instanceof Number;\n}\n\nexport function isNativeBlob(p: any): boolean {\n return isNativeBlobDefined() && p instanceof Blob;\n}\n\nexport function isNativeBlobDefined(): boolean {\n return typeof Blob !== 'undefined';\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/type.ts","/**\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*/\nimport * as type from './type';\n\n/**\n * Returns the Object resulting from parsing the given JSON, or null if the\n * given string does not represent a JSON object.\n */\nexport function jsonObjectOrNull(s: string): {[name: string]: any}|null {\n let obj;\n try {\n obj = JSON.parse(s);\n } catch (e) {\n return null;\n }\n if (type.isNonArrayObject(obj)) {\n return obj;\n } else {\n return null;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/json.ts","/**\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 Contains helper methods for manipulating paths.\n */\n\n/**\n * @return Null if the path is already at the root.\n */\nexport function parent(path: string): string|null {\n if (path.length == 0) {\n return null;\n }\n let index = path.lastIndexOf('/');\n if (index === -1) {\n return '';\n }\n let newPath = path.slice(0, index);\n return newPath;\n}\n\nexport function child(path: string, childPath: string): string {\n let canonicalChildPath = childPath.split('/')\n .filter(function(component) {\n return component.length > 0;\n })\n .join('/');\n if (path.length === 0) {\n return canonicalChildPath;\n } else {\n return path + '/' + canonicalChildPath;\n }\n}\n\n/**\n * Returns the last component of a path.\n * '/foo/bar' -> 'bar'\n * '/foo/bar/baz/' -> 'baz/'\n * '/a' -> 'a'\n */\nexport function lastComponent(path: string): string {\n let index = path.lastIndexOf('/', path.length - 2);\n if (index === -1) {\n return path;\n } else {\n return path.slice(index + 1);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/path.ts","/**\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 Functions to create and manipulate URLs for the server API.\n */\nimport * as constants from './constants';\nimport * as object from './object';\n\nexport function makeNormalUrl(urlPart: string): string {\n return constants.domainBase + constants.apiBaseUrl + urlPart;\n}\n\nexport function makeDownloadUrl(urlPart: string): string {\n return constants.downloadBase + constants.apiBaseUrl + urlPart;\n}\n\nexport function makeUploadUrl(urlPart: string): string {\n return constants.domainBase + constants.apiUploadBaseUrl + urlPart;\n}\n\nexport function makeQueryString(params: { [key: string]: string }): string {\n let encode = encodeURIComponent;\n let queryPart = '?';\n object.forEach(params, function(key, val) {\n let nextPart = encode(key) + '=' + encode(val);\n queryPart = queryPart + nextPart + '&';\n });\n\n // Chop off the extra '&' or '?' on the end\n queryPart = queryPart.slice(0, -1);\n return queryPart;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/url.ts","/**\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 Documentation for the metadata format\n */\nimport {Metadata} from '../metadata';\n\nimport {AuthWrapper} from './authwrapper';\nimport * as json from './json';\nimport {Location} from './location';\nimport * as path from './path';\nimport * as type from './type';\nimport * as UrlUtils from './url';\n\nexport function noXform_(\n metadata: Metadata, value: any): any {\n return value;\n}\n\n/**\n * @struct\n */\nexport class Mapping {\n local: string;\n writable: boolean;\n xform: (p1: Metadata, p2: any) => any;\n\n constructor(\n public server: string, opt_local?: string|null, opt_writable?: boolean,\n opt_xform?: (p1: Metadata, p2: any) => any |\n null) {\n this.local = opt_local || server;\n this.writable = !!opt_writable;\n this.xform = opt_xform || noXform_;\n }\n}\ntype Mappings = Mapping[];\n\nexport {Mappings};\n\nlet mappings_: Mappings|null = null;\n\nexport function xformPath(fullPath: any): string {\n let valid = type.isString(fullPath);\n if (!valid || fullPath.length < 2) {\n return fullPath;\n } else {\n fullPath = (fullPath as string);\n return path.lastComponent(fullPath);\n }\n}\n\nexport function getMappings(): Mappings {\n if (mappings_) {\n return mappings_;\n }\n let mappings = [];\n mappings.push(new Mapping('bucket'));\n mappings.push(new Mapping('generation'));\n mappings.push(new Mapping('metageneration'));\n mappings.push(new Mapping('name', 'fullPath', true));\n\n function mappingsXformPath(\n metadata: Metadata, fullPath: any): string {\n return xformPath(fullPath);\n }\n let nameMapping = new Mapping('name');\n nameMapping.xform = mappingsXformPath;\n mappings.push(nameMapping);\n\n /**\n * Coerces the second param to a number, if it is defined.\n */\n function xformSize(\n metadata: Metadata, size: any): number|null|undefined {\n if (type.isDef(size)) {\n return +(size as number);\n } else {\n return size;\n }\n }\n let sizeMapping = new Mapping('size');\n sizeMapping.xform = xformSize;\n mappings.push(sizeMapping);\n mappings.push(new Mapping('timeCreated'));\n mappings.push(new Mapping('updated'));\n mappings.push(new Mapping('md5Hash', null, true));\n mappings.push(new Mapping('cacheControl', null, true));\n mappings.push(new Mapping('contentDisposition', null, true));\n mappings.push(new Mapping('contentEncoding', null, true));\n mappings.push(new Mapping('contentLanguage', null, true));\n mappings.push(new Mapping('contentType', null, true));\n mappings.push(new Mapping('metadata', 'customMetadata', true));\n\n /**\n * Transforms a comma-separated string of tokens into a list of download\n * URLs.\n */\n function xformTokens(\n metadata: Metadata, tokens: any): string[] {\n let valid = type.isString(tokens) && tokens.length > 0;\n if (!valid) {\n // This can happen if objects are uploaded through GCS and retrieved\n // through list, so we don't want to throw an Error.\n return [];\n }\n let encode = encodeURIComponent;\n let tokensList = tokens.split(',');\n let urls = tokensList.map(function(token: string) {\n let bucket: string = metadata['bucket'] as string;\n let path: string = metadata['fullPath'] as string;\n let urlPart = '/b/' + encode(bucket) + '/o/' + encode(path);\n let base = UrlUtils.makeDownloadUrl(urlPart);\n let queryString = UrlUtils.makeQueryString({'alt': 'media', 'token': token});\n return base + queryString;\n });\n return urls;\n }\n mappings.push(\n new Mapping('downloadTokens', 'downloadURLs', false, xformTokens));\n mappings_ = mappings;\n return mappings_;\n}\n\nexport function addRef(metadata: Metadata, authWrapper: AuthWrapper) {\n function generateRef() {\n let bucket: string = metadata['bucket'] as string;\n let path: string = metadata['fullPath'] as string;\n let loc = new Location(bucket, path);\n return authWrapper.makeStorageReference(loc);\n }\n Object.defineProperty(metadata, 'ref', {get: generateRef});\n}\n\nexport function fromResource(\n authWrapper: AuthWrapper, resource: {[name: string]: any},\n mappings: Mappings): Metadata {\n let metadata: Metadata = {} as Metadata;\n metadata['type'] = 'file';\n let len = mappings.length;\n for (let i = 0; i < len; i++) {\n let mapping = mappings[i];\n metadata[mapping.local] = mapping.xform(metadata, resource[mapping.server]);\n }\n addRef(metadata, authWrapper);\n return metadata;\n}\n\nexport function fromResourceString(\n authWrapper: AuthWrapper, resourceString: string,\n mappings: Mappings): Metadata|null {\n let obj = json.jsonObjectOrNull(resourceString);\n if (obj === null) {\n return null;\n }\n let resource = (obj as Metadata);\n return fromResource(authWrapper, resource, mappings);\n}\n\nexport function toResourceString(\n metadata: Metadata, mappings: Mappings): string {\n let resource: {\n [prop: string]: any\n } = {};\n let len = mappings.length;\n for (let i = 0; i < len; i++) {\n let mapping = mappings[i];\n if (mapping.writable) {\n resource[mapping.server] = metadata[mapping.local];\n }\n }\n return JSON.stringify(resource);\n}\n\nexport function metadataValidator(p: any) {\n let validType = p && type.isObject(p);\n if (!validType) {\n throw 'Expected Metadata object.';\n }\n for (let key in p) {\n let val = p[key];\n if (key === 'customMetadata') {\n if (!type.isObject(val)) {\n throw 'Expected object for \\'customMetadata\\' mapping.';\n }\n } else {\n if (type.isNonNullObject(val)) {\n throw 'Mapping for \\'' + key + '\\' cannot be an object.';\n }\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/metadata.ts","/**\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*/\nimport * as errorsExports from './error';\nimport {errors} from './error';\nimport * as MetadataUtils from './metadata';\nimport * as type from './type';\n\n/**\n * @param name Name of the function.\n * @param specs Argument specs.\n * @param passed The actual arguments passed to the function.\n * @throws {fbs.Error} If the arguments are invalid.\n */\nexport function validate(name: string, specs: ArgSpec[], passed: IArguments) {\n let minArgs = specs.length;\n let maxArgs = specs.length;\n for (let i = 0; i < specs.length; i++) {\n if (specs[i].optional) {\n minArgs = i;\n break;\n }\n }\n let validLength = minArgs <= passed.length && passed.length <= maxArgs;\n if (!validLength) {\n throw errorsExports.invalidArgumentCount(\n minArgs, maxArgs, name, passed.length);\n }\n for (let i = 0; i < passed.length; i++) {\n try {\n specs[i].validator(passed[i]);\n } catch (e) {\n if (e instanceof Error) {\n throw errorsExports.invalidArgument(i, name, e.message);\n } else {\n throw errorsExports.invalidArgument(i, name, e);\n }\n }\n }\n}\n\n/**\n * @struct\n */\nexport class ArgSpec {\n validator: (p1: any) => void;\n optional: boolean;\n\n constructor(\n validator: (p1: any) => void,\n opt_optional?: boolean) {\n let self = this;\n this.validator = function(p: any) {\n if (self.optional && !type.isJustDef(p)) {\n return;\n }\n validator(p);\n };\n this.optional = !!opt_optional;\n }\n}\n\nexport function and_(\n v1: (p1: any) => void,\n v2: Function): (p1: any) => void {\n return function(p) {\n v1(p);\n v2(p);\n };\n}\n\nexport function stringSpec(\n opt_validator?: (p1: any) => void | null,\n opt_optional?: boolean): ArgSpec {\n function stringValidator(p: any) {\n if (!type.isString(p)) {\n throw 'Expected string.';\n }\n }\n let validator;\n if (opt_validator) {\n validator = and_(stringValidator, opt_validator);\n } else {\n validator = stringValidator;\n }\n return new ArgSpec(validator, opt_optional);\n}\n\nexport function uploadDataSpec(): ArgSpec {\n function validator(p: any) {\n let valid = p instanceof Uint8Array || p instanceof ArrayBuffer ||\n type.isNativeBlobDefined() && p instanceof Blob;\n if (!valid) {\n throw 'Expected Blob or File.';\n }\n }\n return new ArgSpec(validator);\n}\n\nexport function metadataSpec(opt_optional?: boolean): ArgSpec {\n return new ArgSpec(MetadataUtils.metadataValidator, opt_optional);\n}\n\nexport function nonNegativeNumberSpec(): ArgSpec {\n function validator(p: any) {\n let valid = type.isNumber(p) && p >= 0;\n if (!valid) {\n throw 'Expected a number 0 or greater.';\n }\n }\n return new ArgSpec(validator);\n}\n\nexport function looseObjectSpec(\n opt_validator?: ((p1: any) => void) | null,\n opt_optional?: boolean): ArgSpec {\n function validator(p: any) {\n let isLooseObject = (p === null) || (type.isDef(p) && p instanceof Object);\n if (!isLooseObject) {\n throw 'Expected an Object.';\n }\n if (opt_validator !== undefined && opt_validator !== null) {\n opt_validator(p);\n }\n }\n return new ArgSpec(validator, opt_optional);\n}\n\nexport function nullFunctionSpec(opt_optional?: boolean): ArgSpec {\n function validator(p: any) {\n let valid = p === null || type.isFunction(p);\n if (!valid) {\n throw 'Expected a Function.';\n }\n }\n return new ArgSpec(validator, opt_optional);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/args.ts","/**\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 * @fileoverview Some methods copied from goog.fs.\n * We don't include goog.fs because it pulls in a bunch of Deferred code that\n * bloats the size of the released binary.\n */\nimport * as array from './array';\nimport * as type from './type';\n\ndeclare var IBlobBuilder;\ndeclare var BlobBuilder;\ndeclare var WebKitBlobBuilder;\n\nfunction getBlobBuilder(): (typeof IBlobBuilder)|undefined {\n if (typeof BlobBuilder !== 'undefined') {\n return BlobBuilder;\n } else if (typeof WebKitBlobBuilder !== 'undefined') {\n return WebKitBlobBuilder;\n } else {\n return undefined;\n }\n}\n\n/**\n * Concatenates one or more values together and converts them to a Blob.\n *\n * @param var_args The values that will make up the resulting blob.\n * @return The blob.\n */\nexport function getBlob(...var_args: (string|Blob|ArrayBuffer)[]): Blob {\n let BlobBuilder = getBlobBuilder();\n if (BlobBuilder !== undefined) {\n let bb = new BlobBuilder();\n for (let i = 0; i < var_args.length; i++) {\n bb.append(var_args[i]);\n }\n return bb.getBlob();\n } else {\n if (type.isNativeBlobDefined()) {\n return new Blob(var_args);\n } else {\n throw Error('This browser doesn\\'t seem to support creating Blobs');\n }\n }\n}\n\n/**\n * Slices the blob. The returned blob contains data from the start byte\n * (inclusive) till the end byte (exclusive). Negative indices cannot be used.\n *\n * @param blob The blob to be sliced.\n * @param start Index of the starting byte.\n * @param end Index of the ending byte.\n * @return The blob slice or null if not supported.\n */\nexport function sliceBlob(blob: Blob, start: number, end: number): Blob|null {\n if ((blob as any).webkitSlice) {\n return (blob as any).webkitSlice(start, end);\n } else if ((blob as any).mozSlice) {\n return (blob as any).mozSlice(start, end);\n } else if (blob.slice) {\n return blob.slice(start, end);\n }\n return null;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/fs.ts","/**\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 * Returns true if the object is contained in the array (compared with ===).\n * @template T\n */\nexport function contains(array: T[], elem: T): boolean {\n return array.indexOf(elem) !== -1;\n}\n\n/**\n * Returns a shallow copy of the array or array-like object (e.g. arguments).\n * @template T\n */\nexport function clone(arraylike: T[]): T[] {\n return Array.prototype.slice.call(arraylike);\n}\n\n/**\n * Removes the given element from the given array, if it is contained.\n * Directly modifies the passed-in array.\n * @template T\n */\nexport function remove(array: T[], elem: T) {\n const i = array.indexOf(elem);\n if (i !== -1) {\n array.splice(i, 1);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/array.ts","/**\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 methods for interacting with the network.\n */\n\nimport {Metadata} from '../metadata';\n\nimport * as array from './array';\nimport {AuthWrapper} from './authwrapper';\nimport {FbsBlob} from './blob';\nimport * as errorsExports from './error';\nimport {FirebaseStorageError} from './error';\nimport {errors} from './error';\nimport {Location} from './location';\nimport * as MetadataUtils from './metadata';\nimport * as object from './object';\nimport {RequestInfo} from './requestinfo';\nimport * as type from './type';\nimport * as UrlUtils from './url';\nimport {XhrIo} from './xhrio';\n\n/**\n * Throws the UNKNOWN FirebaseStorageError if cndn is false.\n */\nexport function handlerCheck(cndn: boolean) {\n if (!cndn) {\n throw errorsExports.unknown();\n }\n}\n\nexport function metadataHandler(\n authWrapper: AuthWrapper,\n mappings: MetadataUtils.Mappings): (p1: XhrIo, p2: string) => Metadata {\n function handler(xhr: XhrIo, text: string): Metadata {\n let metadata = MetadataUtils.fromResourceString(authWrapper, text, mappings);\n handlerCheck(metadata !== null);\n return metadata as Metadata;\n }\n return handler;\n}\n\nexport function sharedErrorHandler(location: Location): (\n p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError {\n function errorHandler(xhr: XhrIo, err: FirebaseStorageError): FirebaseStorageError {\n let newErr;\n if (xhr.getStatus() === 401) {\n newErr = errorsExports.unauthenticated();\n } else {\n if (xhr.getStatus() === 402) {\n newErr = errorsExports.quotaExceeded(location.bucket);\n } else {\n if (xhr.getStatus() === 403) {\n newErr = errorsExports.unauthorized(location.path);\n } else {\n newErr = err;\n }\n }\n }\n newErr.setServerResponseProp(err.serverResponseProp());\n return newErr;\n }\n return errorHandler;\n}\n\nexport function objectErrorHandler(location: Location): (\n p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError {\n let shared = sharedErrorHandler(location);\n\n function errorHandler(xhr: XhrIo, err: FirebaseStorageError): FirebaseStorageError {\n let newErr = shared(xhr, err);\n if (xhr.getStatus() === 404) {\n newErr = errorsExports.objectNotFound(location.path);\n }\n newErr.setServerResponseProp(err.serverResponseProp());\n return newErr;\n }\n return errorHandler;\n}\n\nexport function getMetadata(\n authWrapper: AuthWrapper, location: Location,\n mappings: MetadataUtils.Mappings): RequestInfo {\n let urlPart = location.fullServerUrl();\n let url = UrlUtils.makeNormalUrl(urlPart);\n let method = 'GET';\n let timeout = authWrapper.maxOperationRetryTime();\n let requestInfo = new RequestInfo(\n url, method, metadataHandler(authWrapper, mappings), timeout);\n requestInfo.errorHandler = objectErrorHandler(location);\n return requestInfo;\n}\n\nexport function updateMetadata(\n authWrapper: AuthWrapper, location: Location, metadata: Metadata,\n mappings: MetadataUtils.Mappings): RequestInfo {\n let urlPart = location.fullServerUrl();\n let url = UrlUtils.makeNormalUrl(urlPart);\n let method = 'PATCH';\n let body = MetadataUtils.toResourceString(metadata, mappings);\n let headers = {'Content-Type': 'application/json; charset=utf-8'};\n let timeout = authWrapper.maxOperationRetryTime();\n let requestInfo = new RequestInfo(\n url, method, metadataHandler(authWrapper, mappings), timeout);\n requestInfo.headers = headers;\n requestInfo.body = body;\n requestInfo.errorHandler = objectErrorHandler(location);\n return requestInfo;\n}\n\nexport function deleteObject(\n authWrapper: AuthWrapper, location: Location): RequestInfo {\n let urlPart = location.fullServerUrl();\n let url = UrlUtils.makeNormalUrl(urlPart);\n let method = 'DELETE';\n let timeout = authWrapper.maxOperationRetryTime();\n\n function handler(xhr: XhrIo, text: string) {}\n let requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.successCodes = [200, 204];\n requestInfo.errorHandler = objectErrorHandler(location);\n return requestInfo;\n}\n\nexport function determineContentType_(\n metadata: Metadata|null, blob: FbsBlob|null): string {\n return metadata && metadata['contentType'] || blob && blob.type() ||\n 'application/octet-stream';\n}\n\nexport function metadataForUpload_(\n location: Location, blob: FbsBlob, opt_metadata?: Metadata|null): Metadata {\n let metadata = object.clone(opt_metadata);\n metadata['fullPath'] = location.path;\n metadata['size'] = blob.size();\n if (!metadata['contentType']) {\n metadata['contentType'] = determineContentType_(null, blob);\n }\n return metadata;\n}\n\nexport function multipartUpload(\n authWrapper: AuthWrapper, location: Location, mappings: MetadataUtils.Mappings,\n blob: FbsBlob, opt_metadata?: Metadata|null): RequestInfo {\n let urlPart = location.bucketOnlyServerUrl();\n let headers: { [prop: string]: string } = {'X-Goog-Upload-Protocol': 'multipart'};\n\n function genBoundary() {\n let str = '';\n for (let i = 0; i < 2; i++) {\n str = str + Math.random().toString().slice(2);\n }\n return str;\n }\n let boundary = genBoundary();\n headers['Content-Type'] = 'multipart/related; boundary=' + boundary;\n let metadata = metadataForUpload_(location, blob, opt_metadata);\n let metadataString = MetadataUtils.toResourceString(metadata, mappings);\n let preBlobPart = '--' + boundary + '\\r\\n' +\n 'Content-Type: application/json; charset=utf-8\\r\\n\\r\\n' + metadataString +\n '\\r\\n--' + boundary + '\\r\\n' +\n 'Content-Type: ' + metadata['contentType'] + '\\r\\n\\r\\n';\n let postBlobPart = '\\r\\n--' + boundary + '--';\n let body = FbsBlob.getBlob(preBlobPart, blob, postBlobPart);\n if (body === null) {\n throw errorsExports.cannotSliceBlob();\n }\n let urlParams = {'name': metadata['fullPath']};\n let url = UrlUtils.makeUploadUrl(urlPart);\n let method = 'POST';\n let timeout = authWrapper.maxUploadRetryTime();\n let requestInfo = new RequestInfo(\n url, method, metadataHandler(authWrapper, mappings), timeout);\n requestInfo.urlParams = urlParams;\n requestInfo.headers = headers;\n requestInfo.body = body.uploadData();\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n\n/**\n * @param current The number of bytes that have been uploaded so far.\n * @param total The total number of bytes in the upload.\n * @param opt_finalized True if the server has finished the upload.\n * @param opt_metadata The upload metadata, should\n * only be passed if opt_finalized is true.\n * @struct\n */\nexport class ResumableUploadStatus {\n finalized: boolean;\n metadata: Metadata|null;\n\n constructor(\n public current: number,\n public total: number,\n finalized?: boolean,\n metadata?: Metadata|null) {\n this.finalized = !!finalized;\n this.metadata = metadata || null;\n }\n}\n\nexport function checkResumeHeader_(xhr: XhrIo, opt_allowed?: string[]): string {\n let status;\n try {\n status = xhr.getResponseHeader('X-Goog-Upload-Status');\n } catch (e) {\n handlerCheck(false);\n }\n let allowed = opt_allowed || ['active'];\n handlerCheck(array.contains(allowed, status));\n return (status as string);\n}\n\nexport function createResumableUpload(\n authWrapper: AuthWrapper, location: Location, mappings: MetadataUtils.Mappings,\n blob: FbsBlob, opt_metadata?: Metadata|null): RequestInfo {\n let urlPart = location.bucketOnlyServerUrl();\n let metadata = metadataForUpload_(location, blob, opt_metadata);\n let urlParams = {'name': metadata['fullPath']};\n let url = UrlUtils.makeUploadUrl(urlPart);\n let method = 'POST';\n let headers = {\n 'X-Goog-Upload-Protocol': 'resumable',\n 'X-Goog-Upload-Command': 'start',\n 'X-Goog-Upload-Header-Content-Length': blob.size(),\n 'X-Goog-Upload-Header-Content-Type': metadata['contentType'],\n 'Content-Type': 'application/json; charset=utf-8'\n };\n let body = MetadataUtils.toResourceString(metadata, mappings);\n let timeout = authWrapper.maxUploadRetryTime();\n\n function handler(xhr: XhrIo, text: string): string {\n checkResumeHeader_(xhr);\n let url;\n try {\n url = xhr.getResponseHeader('X-Goog-Upload-URL');\n } catch (e) {\n handlerCheck(false);\n }\n handlerCheck(type.isString(url));\n return (url as string);\n }\n let requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.urlParams = urlParams;\n requestInfo.headers = headers;\n requestInfo.body = body;\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n\n/**\n * @param url From a call to fbs.requests.createResumableUpload.\n */\nexport function getResumableUploadStatus(\n authWrapper: AuthWrapper, location: Location, url: string,\n blob: FbsBlob): RequestInfo {\n let headers = {'X-Goog-Upload-Command': 'query'};\n\n function handler(xhr: XhrIo, text: string): ResumableUploadStatus {\n let status = checkResumeHeader_(xhr, ['active', 'final']);\n let sizeString;\n try {\n sizeString = xhr.getResponseHeader('X-Goog-Upload-Size-Received');\n } catch (e) {\n handlerCheck(false);\n }\n let size = parseInt(sizeString, 10);\n handlerCheck(!isNaN(size));\n return new ResumableUploadStatus(size, blob.size(), status === 'final');\n }\n let method = 'POST';\n let timeout = authWrapper.maxUploadRetryTime();\n let requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.headers = headers;\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n\n/**\n * Any uploads via the resumable upload API must transfer a number of bytes\n * that is a multiple of this number.\n */\nexport const resumableUploadChunkSize: number = 256 * 1024;\n\n/**\n * @param url From a call to fbs.requests.createResumableUpload.\n * @param chunkSize Number of bytes to upload.\n * @param opt_status The previous status.\n * If not passed or null, we start from the beginning.\n * @throws fbs.Error If the upload is already complete, the passed in status\n * has a final size inconsistent with the blob, or the blob cannot be sliced\n * for upload.\n */\nexport function continueResumableUpload(\n location: Location, authWrapper: AuthWrapper, url: string, blob: FbsBlob,\n chunkSize: number, mappings: MetadataUtils.Mappings,\n opt_status?: ResumableUploadStatus|null,\n opt_progressCallback?: ((p1: number, p2: number) => void) | null): RequestInfo {\n // TODO(andysoto): standardize on internal asserts\n // assert(!(opt_status && opt_status.finalized));\n let status = new ResumableUploadStatus(0, 0);\n if (opt_status) {\n status.current = opt_status.current;\n status.total = opt_status.total;\n } else {\n status.current = 0;\n status.total = blob.size();\n }\n if (blob.size() !== status.total) {\n throw errorsExports.serverFileWrongSize();\n }\n let bytesLeft = status.total - status.current;\n let bytesToUpload = bytesLeft;\n if (chunkSize > 0) {\n bytesToUpload = Math.min(bytesToUpload, chunkSize);\n }\n let startByte = status.current;\n let endByte = startByte + bytesToUpload;\n let uploadCommand =\n bytesToUpload === bytesLeft ? 'upload, finalize' : 'upload';\n let headers = {\n 'X-Goog-Upload-Command': uploadCommand,\n 'X-Goog-Upload-Offset': status.current\n };\n let body = blob.slice(startByte, endByte);\n if (body === null) {\n throw errorsExports.cannotSliceBlob();\n }\n\n function handler(xhr: XhrIo, text: string): ResumableUploadStatus {\n // TODO(andysoto): Verify the MD5 of each uploaded range:\n // the 'x-range-md5' header comes back with status code 308 responses.\n // We'll only be able to bail out though, because you can't re-upload a\n // range that you previously uploaded.\n let uploadStatus = checkResumeHeader_(xhr, ['active', 'final']);\n let newCurrent = status.current + bytesToUpload;\n let size = blob.size();\n let metadata;\n if (uploadStatus === 'final') {\n metadata = metadataHandler(authWrapper, mappings)(xhr, text);\n } else {\n metadata = null;\n }\n return new ResumableUploadStatus(\n newCurrent, size, uploadStatus === 'final', metadata);\n }\n let method = 'POST';\n let timeout = authWrapper.maxUploadRetryTime();\n let requestInfo = new RequestInfo(url, method, handler, timeout);\n requestInfo.headers = headers;\n requestInfo.body = body.uploadData();\n requestInfo.progressCallback = opt_progressCallback || null;\n requestInfo.errorHandler = sharedErrorHandler(location);\n return requestInfo;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/requests.ts","/**\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 Method for invoking a callback asynchronously.\n */\nimport * as promiseimpl from './promise_external';\n\n/**\n * Returns a function that invokes f with its arguments asynchronously as a\n * microtask, i.e. as soon as possible after the current script returns back\n * into browser code.\n */\nexport function async(f: Function): Function {\n return function(...argsToForward: any[]) {\n promiseimpl.resolve(true).then(function() {\n f.apply(null, argsToForward);\n });\n };\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/async.ts","/**\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 a method for running a function with exponential\n * backoff.\n */\ntype id = (p1: boolean) => void;\n\nexport {id};\n\n/**\n * @param f May be invoked\n * before the function returns.\n * @param callback Get all the arguments passed to the function\n * passed to f, including the initial boolean.\n */\nexport function start(\n f: (p1: (success: boolean, ...rest: any[]) => void,\n canceled: boolean) => void,\n callback: Function, timeout: number): id {\n // TODO(andysoto): make this code cleaner (probably refactor into an actual\n // type instead of a bunch of functions with state shared in the closure)\n let waitSeconds = 1;\n // Would type this as \"number\" but that doesn't work for Node so ¯\\_(ツ)_/¯\n let timeoutId: any = null;\n let hitTimeout = false;\n let cancelState = 0;\n\n function canceled() {\n return cancelState === 2;\n }\n let triggeredCallback = false;\n\n function triggerCallback() {\n if (!triggeredCallback) {\n triggeredCallback = true;\n callback.apply(null, arguments);\n }\n }\n\n function callWithDelay(millis: number): void {\n timeoutId = setTimeout(function() {\n timeoutId = null;\n f(handler, canceled());\n }, millis);\n }\n\n function handler(success: boolean, ...var_args: any[]):void {\n if (triggeredCallback) {\n return;\n }\n if (success) {\n triggerCallback.apply(null, arguments);\n return;\n }\n let mustStop = canceled() || hitTimeout;\n if (mustStop) {\n triggerCallback.apply(null, arguments);\n return;\n }\n if (waitSeconds < 64) {\n /* TODO(andysoto): don't back off so quickly if we know we're offline. */\n waitSeconds *= 2;\n }\n let waitMillis;\n if (cancelState === 1) {\n cancelState = 2;\n waitMillis = 0;\n } else {\n waitMillis = (waitSeconds + Math.random()) * 1000;\n }\n callWithDelay(waitMillis);\n }\n let stopped = false;\n\n function stop(wasTimeout: boolean): void {\n if (stopped) {\n return;\n }\n stopped = true;\n if (triggeredCallback) {\n return;\n }\n if (timeoutId !== null) {\n if (!wasTimeout) {\n cancelState = 2;\n }\n clearTimeout(timeoutId);\n callWithDelay(0);\n } else {\n if (!wasTimeout) {\n cancelState = 1;\n }\n }\n }\n callWithDelay(0);\n setTimeout(function() {\n hitTimeout = true;\n stop(true);\n }, timeout);\n return stop;\n}\n\n/**\n * Stops the retry loop from repeating.\n * If the function is currently \"in between\" retries, it is invoked immediately\n * with the second parameter as \"true\". Otherwise, it will be invoked once more\n * after the current invocation finishes iff the current invocation would have\n * triggered another retry.\n */\nexport function stop(id: id) {\n id(false);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/backoff.ts","/**\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 methods used to actually send HTTP requests from\n * abstract representations.\n */\nimport * as array from './array';\nimport * as backoff from './backoff';\nimport * as errorsExports from './error';\nimport {FirebaseStorageError} from './error';\nimport {errors} from './error';\nimport * as object from './object';\nimport * as promiseimpl from './promise_external';\nimport {RequestInfo} from './requestinfo';\nimport * as type from './type';\nimport * as UrlUtils from './url';\nimport * as XhrIoExports from './xhrio';\nimport {Headers, XhrIo} from './xhrio';\nimport {XhrIoPool} from './xhriopool';\nimport { FirebaseNamespace } from \"../../app/firebase_app\";\n\ndeclare var firebase: FirebaseNamespace;\n\n/**\n * @template T\n */\nexport interface Request {\n getPromise(): Promise;\n\n /**\n * Cancels the request. IMPORTANT: the promise may still be resolved with an\n * appropriate value (if the request is finished before you call this method,\n * but the promise has not yet been resolved), so don't just assume it will be\n * rejected if you call this function.\n * @param appDelete True if the cancelation came from the app being deleted.\n */\n cancel(appDelete?: boolean): void;\n}\n\n/**\n * @struct\n * @template T\n */\nclass NetworkRequest implements Request {\n private url_: string;\n private method_: string;\n private headers_: Headers;\n private body_: string|Blob|Uint8Array|null;\n private successCodes_: number[];\n private additionalRetryCodes_: number[];\n private pendingXhr_: XhrIo|null = null;\n private backoffId_: backoff.id|null = null;\n private resolve_: Function|null = null;\n private reject_: Function|null = null;\n private canceled_: boolean = false;\n private appDelete_: boolean = false;\n private callback_: (p1: XhrIo, p2: string) => T;\n private errorCallback_: ((p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError) | null;\n private progressCallback_:\n ((p1: number, p2: number) => void) | null;\n private timeout_: number;\n private pool_: XhrIoPool;\n promise_: Promise;\n\n constructor(\n url: string, method: string, headers: Headers,\n body: string|Blob|Uint8Array|null, successCodes: number[],\n additionalRetryCodes: number[],\n callback: (p1: XhrIo, p2: string) => T,\n errorCallback: ((p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError) | null, timeout: number,\n progressCallback: ((p1: number, p2: number) => void) | null,\n pool: XhrIoPool) {\n this.url_ = url;\n this.method_ = method;\n this.headers_ = headers;\n this.body_ = body;\n this.successCodes_ = successCodes.slice();\n this.additionalRetryCodes_ = additionalRetryCodes.slice();\n this.callback_ = callback;\n this.errorCallback_ = errorCallback;\n this.progressCallback_ = progressCallback;\n this.timeout_ = timeout;\n this.pool_ = pool;\n let self = this;\n this.promise_ = promiseimpl.make(function(resolve, reject) {\n self.resolve_ = resolve;\n self.reject_ = reject;\n self.start_();\n });\n }\n\n /**\n * Actually starts the retry loop.\n */\n private start_() {\n let self = this;\n\n function doTheRequest(\n backoffCallback: (p1: boolean, ...p2: any[]) => void,\n canceled: boolean) {\n if (canceled) {\n backoffCallback(false, new RequestEndStatus(false, null, true));\n return;\n }\n let xhr = self.pool_.createXhrIo();\n self.pendingXhr_ = xhr;\n\n function progressListener(progressEvent: ProgressEvent) {\n let loaded = progressEvent.loaded;\n let total = progressEvent.lengthComputable ? progressEvent.total : -1;\n if (self.progressCallback_ !== null) {\n self.progressCallback_(loaded, total);\n }\n }\n if (self.progressCallback_ !== null) {\n xhr.addUploadProgressListener(progressListener);\n }\n xhr.send(self.url_, self.method_, self.body_, self.headers_)\n .then(function(xhr: XhrIo) {\n if (self.progressCallback_ !== null) {\n xhr.removeUploadProgressListener(progressListener);\n }\n self.pendingXhr_ = null;\n xhr = (xhr as XhrIo);\n let hitServer =\n xhr.getErrorCode() === XhrIoExports.ErrorCode.NO_ERROR;\n let status = xhr.getStatus();\n if (!hitServer || self.isRetryStatusCode_(status)) {\n let wasCanceled =\n xhr.getErrorCode() === XhrIoExports.ErrorCode.ABORT;\n backoffCallback(\n false, new RequestEndStatus(false, null, wasCanceled));\n return;\n }\n let successCode = array.contains(self.successCodes_, status);\n backoffCallback(true, new RequestEndStatus(successCode, xhr));\n });\n }\n\n /**\n * @param requestWentThrough True if the request eventually went\n * through, false if it hit the retry limit or was canceled.\n */\n function backoffDone(\n requestWentThrough: boolean, status: RequestEndStatus) {\n let resolve = self.resolve_ as Function;\n let reject = self.reject_ as Function;\n let xhr = status.xhr as XhrIo;\n if (status.wasSuccessCode) {\n try {\n let result = self.callback_(xhr, xhr.getResponseText());\n if (type.isJustDef(result)) {\n resolve(result);\n } else {\n resolve();\n }\n } catch (e) {\n reject(e);\n }\n } else {\n if (xhr !== null) {\n let err = errorsExports.unknown();\n err.setServerResponseProp(xhr.getResponseText());\n if (self.errorCallback_) {\n reject(self.errorCallback_(xhr, err));\n } else {\n reject(err);\n }\n } else {\n if (status.canceled) {\n let err = self.appDelete_ ? errorsExports.appDeleted() :\n errorsExports.canceled();\n reject(err);\n } else {\n let err = errorsExports.retryLimitExceeded();\n reject(err);\n }\n }\n }\n }\n if (this.canceled_) {\n backoffDone(false, new RequestEndStatus(false, null, true));\n } else {\n this.backoffId_ = backoff.start(doTheRequest, backoffDone, this.timeout_);\n }\n }\n\n /** @inheritDoc */\n getPromise() {\n return this.promise_;\n }\n\n /** @inheritDoc */\n cancel(appDelete?: boolean) {\n this.canceled_ = true;\n this.appDelete_ = appDelete || false;\n if (this.backoffId_ !== null) {\n backoff.stop(this.backoffId_);\n }\n if (this.pendingXhr_ !== null) {\n this.pendingXhr_.abort();\n }\n }\n\n private isRetryStatusCode_(status: number): boolean {\n // The codes for which to retry came from this page:\n // https://cloud.google.com/storage/docs/exponential-backoff\n let isFiveHundredCode = status >= 500 && status < 600;\n let extraRetryCodes = [\n // Request Timeout: web server didn't receive full request in time.\n 408,\n // Too Many Requests: you're getting rate-limited, basically.\n 429\n ];\n let isExtraRetryCode = array.contains(extraRetryCodes, status);\n let isRequestSpecificRetryCode =\n array.contains(this.additionalRetryCodes_, status);\n return isFiveHundredCode || isExtraRetryCode || isRequestSpecificRetryCode;\n }\n}\n\n/**\n * A collection of information about the result of a network request.\n * @param opt_canceled Defaults to false.\n * @struct\n */\nexport class RequestEndStatus {\n /**\n * True if the request was canceled.\n */\n canceled: boolean;\n\n constructor(\n public wasSuccessCode: boolean, public xhr: XhrIo|null,\n opt_canceled?: boolean) {\n this.canceled = !!opt_canceled;\n }\n}\n\nexport function addAuthHeader_(headers: Headers, authToken: string|null) {\n if (authToken !== null && authToken.length > 0) {\n headers['Authorization'] = 'Firebase ' + authToken;\n }\n}\n\nexport function addVersionHeader_(headers: Headers) {\n let number = typeof firebase !== 'undefined' ? firebase.SDK_VERSION : 'AppManager';\n headers['X-Firebase-Storage-Version'] = 'webjs/' + number;\n}\n\n/**\n * @template T\n */\nexport function makeRequest(\n requestInfo: RequestInfo, authToken: string|null,\n pool: XhrIoPool): Request {\n let queryPart = UrlUtils.makeQueryString(requestInfo.urlParams);\n let url = requestInfo.url + queryPart;\n let headers = object.clone(requestInfo.headers);\n addAuthHeader_(headers, authToken);\n addVersionHeader_(headers);\n return new NetworkRequest(\n url, requestInfo.method, headers, requestInfo.body,\n requestInfo.successCodes, requestInfo.additionalRetryCodes,\n requestInfo.handler, requestInfo.errorHandler, requestInfo.timeout,\n requestInfo.progressCallback, pool);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/request.ts","/**\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*/\nimport {StringFormat} from './storage/implementation/string';\nimport {TaskEvent} from './storage/implementation/taskenums';\nimport {TaskState} from './storage/implementation/taskenums';\nimport {XhrIoPool} from './storage/implementation/xhriopool';\nimport {Reference} from './storage/reference';\nimport {Service} from './storage/service';\nimport firebase from './app';\nimport { \n FirebaseApp, \n FirebaseServiceFactory \n} from \"./app/firebase_app\";\n/**\n * Type constant for Firebase Storage.\n */\nconst STORAGE_TYPE = 'storage';\n\nfunction factory(app: FirebaseApp, unused: any, opt_url?: string): Service {\n return new Service(app, new XhrIoPool(), opt_url);\n}\n\nexport function registerStorage(instance) {\n let namespaceExports = {\n // no-inline\n 'TaskState': TaskState,\n 'TaskEvent': TaskEvent,\n 'StringFormat': StringFormat,\n 'Storage': Service,\n 'Reference': Reference\n };\n instance.INTERNAL.registerService(\n STORAGE_TYPE, \n (factory as FirebaseServiceFactory),\n namespaceExports, \n undefined,\n // Allow multiple storage instances per app.\n true);\n}\n\nregisterStorage(firebase);\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage.ts","/**\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 * @fileoverview Constants used in the Firebase Storage library.\n */\n\n/**\n * Domain and scheme for API calls.\n */\nexport const domainBase: string = 'https://firebasestorage.googleapis.com';\n\n/**\n * Domain and scheme for object downloads.\n */\nexport const downloadBase: string = 'https://firebasestorage.googleapis.com';\n\n/**\n * Base URL for non-upload calls to the API.\n */\nexport const apiBaseUrl: string = '/v0';\n\n/**\n * Base URL for upload calls to the API.\n */\nexport const apiUploadBaseUrl: string = '/v0';\n\nexport function setDomainBase(domainBase: string) {\n domainBase = domainBase;\n}\n\nexport const configOption: string = 'storageBucket';\n\n/**\n * 1 minute\n */\nexport const shortMaxOperationRetryTime: number = 1 * 60 * 1000;\n\n/**\n * 2 minutes\n */\nexport const defaultMaxOperationRetryTime: number = 2 * 60 * 1000;\n\n/**\n * 10 minutes\n */\nexport const defaultMaxUploadRetryTime: number = 10 * 60 * 100;\n\n/**\n * This is the value of Number.MIN_SAFE_INTEGER, which is not well supported\n * enough for us to use it directly.\n */\nexport const minSafeInteger: number = -9007199254740991;\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/constants.ts","/**\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 A lightweight wrapper around XMLHttpRequest with a\n * goog.net.XhrIo-like interface.\n */\n\nexport type Headers = {[name: string]: (string|number)};\n\nexport interface XhrIo {\n send(\n url: string, method: string, opt_body?: ArrayBufferView|Blob|string|null,\n opt_headers?: Headers): Promise;\n\n getErrorCode(): ErrorCode;\n\n getStatus(): number;\n\n getResponseText(): string;\n\n /**\n * Abort the request.\n */\n abort(): void;\n\n getResponseHeader(header: string): string|null;\n\n addUploadProgressListener(listener: (p1: Event) => void): void;\n\n removeUploadProgressListener(listener: (p1: Event) => void): void;\n}\n\n/**\n * @enum{number}\n */\nexport enum ErrorCode {\n NO_ERROR = 0,\n NETWORK_ERROR = 1,\n ABORT = 2\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/xhrio.ts","/**\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*/\nimport * as errorsExports from './error';\nimport * as object from './object';\nimport * as promiseimpl from './promise_external';\nimport * as type from './type';\nimport * as XhrIoExports from './xhrio';\nimport {Headers, XhrIo} from './xhrio';\n\n/**\n * We use this instead of goog.net.XhrIo because goog.net.XhrIo is hyuuuuge and\n * doesn't work in React Native on Android.\n */\nexport class NetworkXhrIo implements XhrIo {\n private xhr_: XMLHttpRequest;\n private errorCode_: XhrIoExports.ErrorCode;\n private sendPromise_: Promise;\n private sent_: boolean = false;\n\n constructor() {\n this.xhr_ = new XMLHttpRequest();\n this.errorCode_ = XhrIoExports.ErrorCode.NO_ERROR;\n this.sendPromise_ = promiseimpl.make((resolve, reject) => {\n this.xhr_.addEventListener('abort', (event) => {\n this.errorCode_ = XhrIoExports.ErrorCode.ABORT;\n resolve(this);\n });\n this.xhr_.addEventListener('error', (event) => {\n this.errorCode_ = XhrIoExports.ErrorCode.NETWORK_ERROR;\n resolve(this);\n });\n this.xhr_.addEventListener('load', (event) => {\n resolve(this);\n });\n });\n }\n\n /**\n * @override\n */\n send(\n url: string, method: string, opt_body?: ArrayBufferView|Blob|string|null,\n opt_headers?: Headers): Promise {\n if (this.sent_) {\n throw errorsExports.internalError('cannot .send() more than once');\n }\n this.sent_ = true;\n this.xhr_.open(method, url, true);\n if (type.isDef(opt_headers)) {\n const headers = (opt_headers as Headers);\n object.forEach(headers, (key, val) => {\n this.xhr_.setRequestHeader(key, val.toString());\n });\n }\n if (type.isDef(opt_body)) {\n this.xhr_.send(opt_body);\n } else {\n this.xhr_.send();\n }\n return this.sendPromise_;\n }\n\n /**\n * @override\n */\n getErrorCode(): XhrIoExports.ErrorCode {\n if (!this.sent_) {\n throw errorsExports.internalError(\n 'cannot .getErrorCode() before sending');\n }\n return this.errorCode_;\n }\n\n /**\n * @override\n */\n getStatus(): number {\n if (!this.sent_) {\n throw errorsExports.internalError('cannot .getStatus() before sending');\n }\n try {\n return this.xhr_.status;\n } catch (e) {\n return -1;\n }\n }\n\n /**\n * @override\n */\n getResponseText(): string {\n if (!this.sent_) {\n throw errorsExports.internalError(\n 'cannot .getResponseText() before sending');\n }\n return this.xhr_.responseText;\n }\n\n /**\n * Aborts the request.\n * @override\n */\n abort() {\n this.xhr_.abort();\n }\n\n /**\n * @override\n */\n getResponseHeader(header: string): string|null {\n return this.xhr_.getResponseHeader(header);\n }\n\n /**\n * @override\n */\n addUploadProgressListener(listener: (p1: Event) => void) {\n if (type.isDef(this.xhr_.upload)) {\n this.xhr_.upload.addEventListener('progress', listener);\n }\n }\n\n /**\n * @override\n */\n removeUploadProgressListener(listener: (p1: Event) => void) {\n if (type.isDef(this.xhr_.upload)) {\n this.xhr_.upload.removeEventListener('progress', listener);\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/xhrio_network.ts","/**\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 Replacement for goog.net.XhrIoPool that works with fbs.XhrIo.\n */\nimport {XhrIo} from './xhrio';\nimport {NetworkXhrIo} from './xhrio_network';\n\n/**\n * Factory-like class for creating XhrIo instances.\n */\nexport class XhrIoPool {\n createXhrIo(): XhrIo {\n return new NetworkXhrIo();\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/xhriopool.ts","/**\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 Functionality related to the parsing/composition of bucket/\n * object location.\n */\nimport * as errorsExports from './error';\nimport {errors} from './error';\n\n/**\n * @struct\n */\nexport class Location {\n private path_: string;\n\n constructor(public readonly bucket: string, path: string) {\n this.path_ = path;\n }\n\n get path(): string {\n return this.path_;\n }\n\n fullServerUrl(): string {\n let encode = encodeURIComponent;\n return '/b/' + encode(this.bucket) + '/o/' + encode(this.path);\n }\n\n bucketOnlyServerUrl(): string {\n let encode = encodeURIComponent;\n return '/b/' + encode(this.bucket) + '/o';\n }\n\n static makeFromBucketSpec(bucketString: string): Location {\n let bucketLocation;\n try {\n bucketLocation = Location.makeFromUrl(bucketString);\n } catch (e) {\n // Not valid URL, use as-is. This lets you put bare bucket names in\n // config.\n return new Location(bucketString, '');\n }\n if (bucketLocation.path === '') {\n return bucketLocation;\n } else {\n throw errorsExports.invalidDefaultBucket(bucketString);\n }\n }\n\n static makeFromUrl(url: string): Location {\n let location = null;\n let bucketDomain = '([A-Za-z0-9.\\\\-]+)';\n\n function gsModify(loc: Location) {\n if (loc.path.charAt(loc.path.length - 1) === '/') {\n loc.path_ = loc.path_.slice(0, -1);\n }\n }\n let gsPath = '(/(.*))?$';\n let path = '(/([^?#]*).*)?$';\n let gsRegex = new RegExp('^gs://' + bucketDomain + gsPath, 'i');\n let gsIndices = {bucket: 1, path: 3};\n\n function httpModify(loc: Location) {\n loc.path_ = decodeURIComponent(loc.path);\n }\n let version = 'v[A-Za-z0-9_]+';\n let httpRegex = new RegExp(\n '^https?://firebasestorage\\\\.googleapis\\\\.com/' + version + '/b/' +\n bucketDomain + '/o' + path,\n 'i');\n let httpIndices = {bucket: 1, path: 3};\n let groups = [\n {regex: gsRegex, indices: gsIndices, postModify: gsModify},\n {regex: httpRegex, indices: httpIndices, postModify: httpModify}\n ];\n for (let i = 0; i < groups.length; i++) {\n let group = groups[i];\n let captures = group.regex.exec(url);\n if (captures) {\n let bucketValue = captures[group.indices.bucket];\n let pathValue = captures[group.indices.path];\n if (!pathValue) {\n pathValue = '';\n }\n location = new Location(bucketValue, pathValue);\n group.postModify(location);\n break;\n }\n }\n if (location == null) {\n throw errorsExports.invalidUrl(url);\n }\n return location;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/location.ts","/**\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 * @file Provides a Blob-like wrapper for various binary types (including the\n * native Blob type). This makes it possible to upload types like ArrayBuffers,\n * making uploads possible in environments without the native Blob type.\n */\nimport * as fs from './fs';\nimport * as string from './string';\nimport {StringFormat} from './string';\nimport * as type from './type';\n\n/**\n * @param opt_elideCopy If true, doesn't copy mutable input data\n * (e.g. Uint8Arrays). Pass true only if you know the objects will not be\n * modified after this blob's construction.\n */\nexport class FbsBlob {\n private data_: Blob|Uint8Array;\n private size_: number;\n private type_: string;\n\n constructor(data: Blob|Uint8Array|ArrayBuffer, opt_elideCopy?: boolean) {\n let size: number = 0;\n let blobType: string = '';\n if (type.isNativeBlob(data)) {\n this.data_ = (data as Blob);\n size = (data as Blob).size;\n blobType = (data as Blob).type;\n } else if (data instanceof ArrayBuffer) {\n if (opt_elideCopy) {\n this.data_ = new Uint8Array(data);\n } else {\n this.data_ = new Uint8Array(data.byteLength);\n this.data_.set(new Uint8Array(data));\n }\n size = this.data_.length;\n } else if (data instanceof Uint8Array) {\n if (opt_elideCopy) {\n this.data_ = (data as Uint8Array);\n } else {\n this.data_ = new Uint8Array(data.length);\n this.data_.set((data as Uint8Array));\n }\n size = data.length;\n }\n this.size_ = size;\n this.type_ = blobType;\n }\n\n size(): number {\n return this.size_;\n }\n\n type(): string {\n return this.type_;\n }\n\n slice(startByte: number, endByte: number): FbsBlob|null {\n if (type.isNativeBlob(this.data_)) {\n let realBlob = (this.data_ as Blob);\n let sliced = fs.sliceBlob(realBlob, startByte, endByte);\n if (sliced === null) {\n return null;\n }\n return new FbsBlob(sliced);\n } else {\n let slice =\n new Uint8Array((this.data_ as Uint8Array).buffer, startByte, endByte - startByte);\n return new FbsBlob(slice, true);\n }\n }\n\n static getBlob(...var_args: (string|FbsBlob)[]): FbsBlob|null {\n if (type.isNativeBlobDefined()) {\n var blobby: (Blob|Uint8Array|string)[] = var_args.map(function(val: string|FbsBlob): Blob|Uint8Array|string {\n if (val instanceof FbsBlob) {\n return val.data_;\n } else {\n return val;\n }\n });\n return new FbsBlob(fs.getBlob.apply(null, blobby));\n } else {\n let uint8Arrays: Uint8Array[] = var_args.map(function(val: string|FbsBlob): Uint8Array {\n if (type.isString(val)) {\n return string.dataFromString(StringFormat.RAW, val as string).data;\n } else {\n // Blobs don't exist, so this has to be a Uint8Array.\n return ((val as FbsBlob).data_ as Uint8Array);\n }\n });\n let finalLength = 0;\n uint8Arrays.forEach(function(array: Uint8Array): void {\n finalLength += array.byteLength;\n });\n let merged = new Uint8Array(finalLength);\n let index = 0;\n uint8Arrays.forEach(function(array: Uint8Array) {\n for (let i = 0; i < array.length; i++) {\n merged[index++] = array[i];\n }\n });\n return new FbsBlob(merged, true);\n }\n }\n\n uploadData(): Blob|Uint8Array {\n return this.data_;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/blob.ts","/**\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*/\nimport {FirebaseStorageError} from './error';\nimport {Headers, XhrIo} from './xhrio';\n\nexport type UrlParams = {[name: string]: string};\n\nexport class RequestInfo {\n urlParams: UrlParams = {};\n headers: Headers = {};\n body: Blob|string|Uint8Array|null = null;\n\n errorHandler: ((p1: XhrIo, p2: FirebaseStorageError) => FirebaseStorageError) | null = null;\n\n /**\n * Called with the current number of bytes uploaded and total size (-1 if not\n * computable) of the request body (i.e. used to report upload progress).\n */\n progressCallback:\n ((p1: number, p2: number) => void) | null = null;\n successCodes: number[] = [200];\n additionalRetryCodes: number[] = [];\n\n constructor(\n public url: string,\n public method: string,\n /**\n * Returns the value with which to resolve the request's promise. Only called\n * if the request is successful. Throw from this function to reject the\n * returned Request's promise with the thrown error.\n * Note: The XhrIo passed to this function may be reused after this callback\n * returns. Do not keep a reference to it in any way.\n */\n public handler: (p1: XhrIo, p2: string) => T,\n public timeout: number) {}\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/requestinfo.ts","/**\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*/\nimport * as type from './type';\n\ntype NextFn = (value: T) => void;\ntype ErrorFn = (error: Error) => void;\ntype CompleteFn = () => void;\ntype Unsubscribe = () => void;\n\ntype Subscribe =\n (next: NextFn | {[name: string]: string|null},\n error?: ErrorFn,\n complete?: CompleteFn) => Unsubscribe;\n\nexport {NextFn, ErrorFn, CompleteFn, Unsubscribe, Subscribe};\n\n/**\n * @struct\n */\nexport class Observer {\n next: NextFn | null;\n error: ErrorFn | null;\n complete: CompleteFn | null;\n\n constructor(\n nextOrObserver: NextFn | {[name: string]: string|null} | null,\n opt_error?: ErrorFn | null,\n opt_complete?: CompleteFn | null) {\n let asFunctions = type.isFunction(nextOrObserver) ||\n type.isDef(opt_error) || type.isDef(opt_complete);\n if (asFunctions) {\n this.next = nextOrObserver as (NextFn | null);\n this.error = opt_error || null;\n this.complete = opt_complete || null;\n } else {\n const observer = nextOrObserver as {\n next?: NextFn | null;\n error?: ErrorFn | null;\n complete?: CompleteFn | null;\n };\n this.next = observer.next || null;\n this.error = observer.error || null;\n this.complete = observer.complete || null;\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/observer.ts","/**\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*/\nimport {TaskState} from './implementation/taskenums';\nimport * as type from './implementation/type';\nimport {Metadata} from './metadata';\nimport {Reference} from './reference';\nimport {UploadTask} from './task';\n\nexport class UploadTaskSnapshot {\n constructor(readonly bytesTransferred: number, readonly totalBytes: number,\n readonly state: TaskState, readonly metadata: Metadata|null, \n readonly task: UploadTask, readonly ref: Reference) {}\n\n get downloadURL(): string|null {\n if (this.metadata !== null) {\n let urls = this.metadata['downloadURLs'];\n if (urls != null && urls[0] != null) {\n return urls[0];\n } else {\n return null;\n }\n } else {\n return null;\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/tasksnapshot.ts","/**\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 * @fileoverview Defines types for interacting with blob transfer tasks.\n */\n\nimport {AuthWrapper} from './implementation/authwrapper';\nimport {FbsBlob} from './implementation/blob';\nimport {FirebaseStorageError} from './implementation/error';\nimport {InternalTaskState} from './implementation/taskenums';\nimport {Metadata} from './metadata';\nimport {NextFn, ErrorFn, CompleteFn, Unsubscribe, Observer} from './implementation/observer';\nimport {Request} from './implementation/request';\nimport * as RequestExports from './implementation/request';\nimport {Subscribe} from './implementation/observer';\nimport {TaskEvent, TaskState} from './implementation/taskenums';\nimport {UploadTaskSnapshot} from './tasksnapshot';\nimport * as fbsArgs from './implementation/args';\nimport {ArgSpec} from './implementation/args';\nimport * as fbsArray from './implementation/array';\nimport {async as fbsAsync} from './implementation/async';\nimport {errors as fbsErrors} from './implementation/error';\nimport * as errors from './implementation/error';\nimport {Location} from './implementation/location';\nimport * as fbsMetadata from './implementation/metadata';\nimport * as fbsPromiseimpl from './implementation/promise_external';\nimport {RequestInfo} from './implementation/requestinfo';\nimport * as fbsRequests from './implementation/requests';\nimport * as fbsTaskEnums from './implementation/taskenums';\nimport * as typeUtils from './implementation/type';\nimport {Reference} from './reference';\n\n/**\n * Represents a blob being uploaded. Can be used to pause/resume/cancel the\n * upload and manage callbacks for various events.\n */\nexport class UploadTask {\n private ref_: Reference;\n private authWrapper_: AuthWrapper;\n private location_: Location;\n private blob_: FbsBlob;\n private metadata_: Metadata|null;\n private mappings_: fbsMetadata.Mappings;\n private transferred_: number = 0;\n private needToFetchStatus_: boolean = false;\n private needToFetchMetadata_: boolean = false;\n private observers_: Observer[] = [];\n private resumable_: boolean;\n private state_: InternalTaskState;\n private error_: Error|null = null;\n private uploadUrl_: string|null = null;\n private request_: Request|null = null;\n private chunkMultiplier_: number = 1;\n private errorHandler_: (p1: FirebaseStorageError) => void;\n private metadataErrorHandler_: (p1: FirebaseStorageError) => void;\n private resolve_:\n ((p1: UploadTaskSnapshot) => void) | null = null;\n private reject_: ((p1: Error) => void) | null = null;\n private promise_: Promise;\n\n /**\n * @param ref The firebaseStorage.Reference object this task came\n * from, untyped to avoid cyclic dependencies.\n * @param blob The blob to upload.\n */\n constructor(\n ref: Reference, authWrapper: AuthWrapper, location: Location,\n mappings: fbsMetadata.Mappings, blob: FbsBlob, metadata: Metadata|null = null) {\n this.ref_ = ref;\n this.authWrapper_ = authWrapper;\n this.location_ = location;\n this.blob_ = blob;\n this.metadata_ = metadata;\n this.mappings_ = mappings;\n this.resumable_ = this.shouldDoResumable_(this.blob_);\n this.state_ = InternalTaskState.RUNNING;\n this.errorHandler_ = (error) => {\n this.request_ = null;\n this.chunkMultiplier_ = 1;\n if (error.codeEquals(errors.Code.CANCELED)) {\n this.needToFetchStatus_ = true;\n this.completeTransitions_();\n } else {\n this.error_ = error;\n this.transition_(InternalTaskState.ERROR);\n }\n };\n this.metadataErrorHandler_ = (error) => {\n this.request_ = null;\n if (error.codeEquals(errors.Code.CANCELED)) {\n this.completeTransitions_();\n } else {\n this.error_ = error;\n this.transition_(InternalTaskState.ERROR);\n }\n };\n this.promise_ = fbsPromiseimpl.make((resolve, reject) => {\n this.resolve_ = resolve;\n this.reject_ = reject;\n this.start_();\n });\n\n // Prevent uncaught rejections on the internal promise from bubbling out\n // to the top level with a dummy handler.\n this.promise_.then(null, () => {});\n }\n\n private makeProgressCallback_():\n (p1: number, p2: number) => void {\n const sizeBefore = this.transferred_;\n return (loaded, total) => {\n this.updateProgress_(sizeBefore + loaded);\n };\n }\n\n private shouldDoResumable_(blob: FbsBlob): boolean {\n return blob.size() > 256 * 1024;\n }\n\n private start_() {\n if (this.state_ !== InternalTaskState.RUNNING) {\n // This can happen if someone pauses us in a resume callback, for example.\n return;\n }\n if (this.request_ !== null) {\n return;\n }\n if (this.resumable_) {\n if (this.uploadUrl_ === null) {\n this.createResumable_();\n } else {\n if (this.needToFetchStatus_) {\n this.fetchStatus_();\n } else {\n if (this.needToFetchMetadata_) {\n // Happens if we miss the metadata on upload completion.\n this.fetchMetadata_();\n } else {\n this.continueUpload_();\n }\n }\n }\n } else {\n this.oneShotUpload_();\n }\n }\n\n private resolveToken_(callback: (p1: string|null) => void) {\n this.authWrapper_.getAuthToken().then((authToken) => {\n switch (this.state_) {\n case InternalTaskState.RUNNING:\n callback(authToken);\n break;\n case InternalTaskState.CANCELING:\n this.transition_(InternalTaskState.CANCELED);\n break;\n case InternalTaskState.PAUSING:\n this.transition_(InternalTaskState.PAUSED);\n break;\n default:\n }\n });\n }\n\n // TODO(andysoto): assert false\n\n private createResumable_() {\n this.resolveToken_((authToken) => {\n const requestInfo = fbsRequests.createResumableUpload(\n this.authWrapper_, this.location_, this.mappings_, this.blob_,\n this.metadata_);\n const createRequest = this.authWrapper_.makeRequest(requestInfo, authToken);\n this.request_ = createRequest;\n createRequest.getPromise().then(\n (url: string) => {\n this.request_ = null;\n this.uploadUrl_ = url;\n this.needToFetchStatus_ = false;\n this.completeTransitions_();\n },\n this.errorHandler_);\n });\n }\n\n private fetchStatus_() {\n // TODO(andysoto): assert(this.uploadUrl_ !== null);\n const url = (this.uploadUrl_ as string);\n this.resolveToken_((authToken) => {\n const requestInfo = fbsRequests.getResumableUploadStatus(\n this.authWrapper_, this.location_, url, this.blob_);\n const statusRequest = this.authWrapper_.makeRequest(requestInfo, authToken);\n this.request_ = statusRequest;\n statusRequest.getPromise().then(\n (status) => {\n status = (status as fbsRequests.ResumableUploadStatus);\n this.request_ = null;\n this.updateProgress_(status.current);\n this.needToFetchStatus_ = false;\n if (status.finalized) {\n this.needToFetchMetadata_ = true;\n }\n this.completeTransitions_();\n },\n this.errorHandler_);\n });\n }\n\n private continueUpload_() {\n const chunkSize =\n fbsRequests.resumableUploadChunkSize * this.chunkMultiplier_;\n const status = new fbsRequests.ResumableUploadStatus(\n this.transferred_, this.blob_.size());\n\n // TODO(andysoto): assert(this.uploadUrl_ !== null);\n const url = (this.uploadUrl_ as string);\n this.resolveToken_((authToken) => {\n let requestInfo;\n try {\n requestInfo = fbsRequests.continueResumableUpload(\n this.location_, this.authWrapper_, url, this.blob_, chunkSize,\n this.mappings_, status, this.makeProgressCallback_());\n } catch (e) {\n this.error_ = e;\n this.transition_(InternalTaskState.ERROR);\n return;\n }\n const uploadRequest = this.authWrapper_.makeRequest(requestInfo, authToken);\n this.request_ = uploadRequest;\n uploadRequest.getPromise().then(\n (newStatus: fbsRequests.ResumableUploadStatus) => {\n this.increaseMultiplier_();\n this.request_ = null;\n this.updateProgress_(newStatus.current);\n if (newStatus.finalized) {\n this.metadata_ = newStatus.metadata;\n this.transition_(InternalTaskState.SUCCESS);\n } else {\n this.completeTransitions_();\n }\n },\n this.errorHandler_);\n });\n }\n\n private increaseMultiplier_() {\n const currentSize =\n fbsRequests.resumableUploadChunkSize * this.chunkMultiplier_;\n\n // Max chunk size is 32M.\n if (currentSize < 32 * 1024 * 1024) {\n this.chunkMultiplier_ *= 2;\n }\n }\n\n private fetchMetadata_() {\n this.resolveToken_((authToken) => {\n const requestInfo = fbsRequests.getMetadata(\n this.authWrapper_, this.location_, this.mappings_);\n const metadataRequest = this.authWrapper_.makeRequest(requestInfo, authToken);\n this.request_ = metadataRequest;\n metadataRequest.getPromise().then(\n (metadata) => {\n this.request_ = null;\n this.metadata_ = metadata;\n this.transition_(InternalTaskState.SUCCESS);\n },\n this.metadataErrorHandler_);\n });\n }\n\n private oneShotUpload_() {\n this.resolveToken_((authToken) => {\n const requestInfo = fbsRequests.multipartUpload(\n this.authWrapper_, this.location_, this.mappings_, this.blob_,\n this.metadata_);\n const multipartRequest = this.authWrapper_.makeRequest(requestInfo, authToken);\n this.request_ = multipartRequest;\n multipartRequest.getPromise().then(\n (metadata) => {\n this.request_ = null;\n this.metadata_ = metadata;\n this.updateProgress_(this.blob_.size());\n this.transition_(InternalTaskState.SUCCESS);\n },\n this.errorHandler_);\n });\n }\n\n private updateProgress_(transferred: number) {\n const old = this.transferred_;\n this.transferred_ = transferred;\n\n // A progress update can make the \"transferred\" value smaller (e.g. a\n // partial upload not completed by server, after which the \"transferred\"\n // value may reset to the value at the beginning of the request).\n if (this.transferred_ !== old) {\n this.notifyObservers_();\n }\n }\n\n private transition_(state: InternalTaskState) {\n if (this.state_ === state) {\n return;\n }\n switch (state) {\n case InternalTaskState.CANCELING:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING ||\n // this.state_ === InternalTaskState.PAUSING);\n this.state_ = state;\n if (this.request_ !== null) {\n this.request_.cancel();\n }\n break;\n case InternalTaskState.PAUSING:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING);\n this.state_ = state;\n if (this.request_ !== null) {\n this.request_.cancel();\n }\n break;\n case InternalTaskState.RUNNING:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.PAUSED ||\n // this.state_ === InternalTaskState.PAUSING);\n const wasPaused = this.state_ === InternalTaskState.PAUSED;\n this.state_ = state;\n if (wasPaused) {\n this.notifyObservers_();\n this.start_();\n }\n break;\n case InternalTaskState.PAUSED:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.PAUSING);\n this.state_ = state;\n this.notifyObservers_();\n break;\n case InternalTaskState.CANCELED:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.PAUSED ||\n // this.state_ === InternalTaskState.CANCELING);\n this.error_ = errors.canceled();\n this.state_ = state;\n this.notifyObservers_();\n break;\n case InternalTaskState.ERROR:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING ||\n // this.state_ === InternalTaskState.PAUSING ||\n // this.state_ === InternalTaskState.CANCELING);\n this.state_ = state;\n this.notifyObservers_();\n break;\n case InternalTaskState.SUCCESS:\n\n // TODO(andysoto):\n // assert(this.state_ === InternalTaskState.RUNNING ||\n // this.state_ === InternalTaskState.PAUSING ||\n // this.state_ === InternalTaskState.CANCELING);\n this.state_ = state;\n this.notifyObservers_();\n break;\n }\n }\n\n private completeTransitions_() {\n switch (this.state_) {\n case InternalTaskState.PAUSING:\n this.transition_(InternalTaskState.PAUSED);\n break;\n case InternalTaskState.CANCELING:\n this.transition_(InternalTaskState.CANCELED);\n break;\n case InternalTaskState.RUNNING:\n this.start_();\n break;\n default:\n\n // TODO(andysoto): assert(false);\n break;\n }\n }\n\n get snapshot(): UploadTaskSnapshot {\n const externalState =\n fbsTaskEnums.taskStateFromInternalTaskState(this.state_);\n return new UploadTaskSnapshot(\n this.transferred_, this.blob_.size(), externalState, this.metadata_,\n this, this.ref_);\n }\n\n /**\n * Adds a callback for an event.\n * @param type The type of event to listen for.\n */\n on(type: TaskEvent, nextOrObserver = undefined, error = undefined,\n completed = undefined): Unsubscribe | Subscribe {\n function typeValidator(_p: any) {\n if (type !== TaskEvent.STATE_CHANGED) {\n throw `Expected one of the event types: [${TaskEvent.STATE_CHANGED}].`;\n }\n }\n const nextOrObserverMessage =\n 'Expected a function or an Object with one of ' +\n '`next`, `error`, `complete` properties.';\n const nextValidator = fbsArgs.nullFunctionSpec(true).validator;\n const observerValidator = fbsArgs.looseObjectSpec(null, true).validator;\n\n function nextOrObserverValidator(p: any) {\n try {\n nextValidator(p);\n return;\n } catch (e) {\n }\n try {\n observerValidator(p);\n const anyDefined = typeUtils.isJustDef(p['next']) || typeUtils.isJustDef(p['error']) ||\n typeUtils.isJustDef(p['complete']);\n if (!anyDefined) {\n throw '';\n }\n return;\n } catch (e) {\n throw nextOrObserverMessage;\n }\n }\n const specs = [\n fbsArgs.stringSpec(typeValidator),\n fbsArgs.looseObjectSpec(nextOrObserverValidator, true),\n fbsArgs.nullFunctionSpec(true), fbsArgs.nullFunctionSpec(true)\n ];\n fbsArgs.validate('on', specs, arguments);\n const self = this;\n\n function makeBinder(specs: ArgSpec[]|null): Subscribe {\n function binder(\n nextOrObserver: NextFn | {[name: string]: string|null} | null,\n error?: ErrorFn | null,\n opt_complete?: CompleteFn | null) {\n if (specs !== null) {\n fbsArgs.validate('on', specs, arguments);\n }\n const observer = new Observer(nextOrObserver, error, completed);\n self.addObserver_(observer);\n return () => {\n self.removeObserver_(observer);\n };\n }\n return binder;\n }\n\n function binderNextOrObserverValidator(p: any) {\n if (p === null) {\n throw nextOrObserverMessage;\n }\n nextOrObserverValidator(p);\n }\n const binderSpecs = [\n fbsArgs.looseObjectSpec(binderNextOrObserverValidator),\n fbsArgs.nullFunctionSpec(true), fbsArgs.nullFunctionSpec(true)\n ];\n const typeOnly =\n !(typeUtils.isJustDef(nextOrObserver) || typeUtils.isJustDef(error) ||\n typeUtils.isJustDef(completed));\n if (typeOnly) {\n return makeBinder(binderSpecs);\n } else {\n return makeBinder(null)(nextOrObserver, error, completed);\n }\n }\n\n /**\n * This object behaves like a Promise, and resolves with its snapshot data\n * when the upload completes.\n * The fulfillment callback. Promise chaining works as normal.\n * @param onRejected The rejection callback.\n */\n then(onFulfilled?: ((value: UploadTaskSnapshot) => U | PromiseLike) | null, onRejected?: ((error: any) => U | PromiseLike) | null): Promise {\n return this.promise_.then(\n (onFulfilled as (value: UploadTaskSnapshot) => U | PromiseLike),\n (onRejected as ((error: any) => PromiseLike) | null));\n }\n\n /**\n * Equivalent to calling `then(null, onRejected)`.\n */\n catch(onRejected: (p1: Error) => T | PromiseLike): Promise {\n return this.then(null, onRejected);\n }\n\n /**\n * Adds the given observer.\n */\n private addObserver_(observer: Observer) {\n this.observers_.push(observer);\n this.notifyObserver_(observer);\n }\n\n /**\n * Removes the given observer.\n */\n private removeObserver_(observer: Observer) {\n fbsArray.remove(this.observers_, observer);\n }\n\n private notifyObservers_() {\n this.finishPromise_();\n const observers = fbsArray.clone(this.observers_);\n observers.forEach((observer) => {\n this.notifyObserver_(observer);\n });\n }\n\n private finishPromise_() {\n if (this.resolve_ !== null) {\n let triggered = true;\n switch (fbsTaskEnums.taskStateFromInternalTaskState(this.state_)) {\n case TaskState.SUCCESS:\n fbsAsync(this.resolve_.bind(null, this.snapshot))();\n break;\n case TaskState.CANCELED:\n case TaskState.ERROR:\n const toCall = (this.reject_ as ((p1: Error) => void));\n fbsAsync(toCall.bind(null, (this.error_ as Error)))();\n break;\n default:\n triggered = false;\n break;\n }\n if (triggered) {\n this.resolve_ = null;\n this.reject_ = null;\n }\n }\n }\n\n private notifyObserver_(observer: Observer) {\n const externalState =\n fbsTaskEnums.taskStateFromInternalTaskState(this.state_);\n switch (externalState) {\n case TaskState.RUNNING:\n case TaskState.PAUSED:\n if (observer.next !== null) {\n fbsAsync(observer.next.bind(observer, this.snapshot))();\n }\n break;\n case TaskState.SUCCESS:\n if (observer.complete !== null) {\n fbsAsync(observer.complete.bind(observer))();\n }\n break;\n case TaskState.CANCELED:\n case TaskState.ERROR:\n if (observer.error !== null) {\n fbsAsync(observer.error.bind(observer, (this.error_ as Error)))();\n }\n break;\n default:\n\n // TODO(andysoto): assert(false);\n if (observer.error !== null) {\n fbsAsync(observer.error.bind(observer, (this.error_ as Error)))();\n }\n }\n }\n\n /**\n * Resumes a paused task. Has no effect on a currently running or failed task.\n * @return True if the operation took effect, false if ignored.\n */\n resume(): boolean {\n fbsArgs.validate('resume', [], arguments);\n const valid = this.state_ === InternalTaskState.PAUSED ||\n this.state_ === InternalTaskState.PAUSING;\n if (valid) {\n this.transition_(InternalTaskState.RUNNING);\n }\n return valid;\n }\n\n /**\n * Pauses a currently running task. Has no effect on a paused or failed task.\n * @return True if the operation took effect, false if ignored.\n */\n pause(): boolean {\n fbsArgs.validate('pause', [], arguments);\n const valid = this.state_ === InternalTaskState.RUNNING;\n if (valid) {\n this.transition_(InternalTaskState.PAUSING);\n }\n return valid;\n }\n\n /**\n * Cancels a currently running or paused task. Has no effect on a complete or\n * failed task.\n * @return True if the operation took effect, false if ignored.\n */\n cancel(): boolean {\n fbsArgs.validate('cancel', [], arguments);\n const valid = this.state_ === InternalTaskState.RUNNING ||\n this.state_ === InternalTaskState.PAUSING;\n if (valid) {\n this.transition_(InternalTaskState.CANCELING);\n }\n return valid;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/task.ts","/**\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 Storage Reference class.\n */\nimport * as args from './implementation/args';\nimport {AuthWrapper} from './implementation/authwrapper';\nimport {FbsBlob} from './implementation/blob';\nimport * as errorsExports from './implementation/error';\nimport {errors} from './implementation/error';\nimport {Location} from './implementation/location';\nimport * as metadata from './implementation/metadata';\nimport * as object from './implementation/object';\nimport * as path from './implementation/path';\nimport * as requests from './implementation/requests';\nimport * as fbsString from './implementation/string';\nimport {StringFormat} from './implementation/string';\nimport * as type from './implementation/type';\nimport {Metadata} from './metadata';\nimport {Service} from './service';\nimport {UploadTask} from './task';\n\n/**\n * Provides methods to interact with a bucket in the Firebase Storage service.\n * @param location An fbs.location, or the URL at\n * which to base this object, in one of the following forms:\n * gs:///\n * http[s]://firebasestorage.googleapis.com/\n * /b//o/\n * Any query or fragment strings will be ignored in the http[s]\n * format. If no value is passed, the storage object will use a URL based on\n * the project ID of the base firebase.App instance.\n */\nexport class Reference {\n protected location: Location;\n\n constructor(protected authWrapper: AuthWrapper, location: string|Location) {\n if (location instanceof Location) {\n this.location = location;\n } else {\n this.location = Location.makeFromUrl(location);\n }\n }\n\n /**\n * @return The URL for the bucket and path this object references,\n * in the form gs:///\n * @override\n */\n toString(): string {\n args.validate('toString', [], arguments);\n return 'gs://' + this.location.bucket + '/' + this.location.path;\n }\n\n protected newRef(authWrapper: AuthWrapper, location: Location): Reference {\n return new Reference(authWrapper, location);\n }\n\n protected mappings(): metadata.Mappings {\n return metadata.getMappings();\n }\n\n /**\n * @return A reference to the object obtained by\n * appending childPath, removing any duplicate, beginning, or trailing\n * slashes.\n */\n child(childPath: string): Reference {\n args.validate('child', [args.stringSpec()], arguments);\n let newPath = path.child(this.location.path, childPath);\n let location = new Location(this.location.bucket, newPath);\n return this.newRef(this.authWrapper, location);\n }\n\n /**\n * @return A reference to the parent of the\n * current object, or null if the current object is the root.\n */\n get parent(): Reference|null {\n let newPath = path.parent(this.location.path);\n if (newPath === null) {\n return null;\n }\n let location = new Location(this.location.bucket, newPath);\n return this.newRef(this.authWrapper, location);\n }\n\n /**\n * @return An reference to the root of this\n * object's bucket.\n */\n get root(): Reference {\n let location = new Location(this.location.bucket, '');\n return this.newRef(this.authWrapper, location);\n }\n\n get bucket(): string {\n return this.location.bucket;\n }\n\n get fullPath(): string {\n return this.location.path;\n }\n\n get name(): string {\n return path.lastComponent(this.location.path);\n }\n\n get storage(): Service {\n return this.authWrapper.service();\n }\n\n /**\n * Uploads a blob to this object's location.\n * @param data The blob to upload.\n * @return An UploadTask that lets you control and\n * observe the upload.\n */\n put(data: Blob|Uint8Array|ArrayBuffer, metadata: Metadata|null = null): UploadTask {\n args.validate(\n 'put', [args.uploadDataSpec(), args.metadataSpec(true)], arguments);\n this.throwIfRoot_('put');\n return new UploadTask(\n this, this.authWrapper, this.location, this.mappings(), new FbsBlob(data),\n metadata);\n }\n\n /**\n * Uploads a string to this object's location.\n * @param string The string to upload.\n * @param opt_format The format of the string to upload.\n * @return An UploadTask that lets you control and\n * observe the upload.\n */\n putString(string: string, format: StringFormat = StringFormat.RAW, opt_metadata?: Metadata):\n UploadTask {\n args.validate(\n 'putString',\n [\n args.stringSpec(), args.stringSpec(fbsString.formatValidator, true),\n args.metadataSpec(true)\n ],\n arguments);\n this.throwIfRoot_('putString');\n let data = fbsString.dataFromString(format, string);\n let metadata = object.clone(opt_metadata);\n if (!type.isDef(metadata['contentType']) && type.isDef(data.contentType)) {\n metadata['contentType'] = data.contentType;\n }\n return new UploadTask(\n this, this.authWrapper, this.location, this.mappings(),\n new FbsBlob(data.data, true), metadata);\n }\n\n /**\n * Deletes the object at this location.\n * @return A promise that resolves if the deletion succeeds.\n */\n delete(): Promise {\n args.validate('delete', [], arguments);\n this.throwIfRoot_('delete');\n let self = this;\n return this.authWrapper.getAuthToken().then(function(authToken) {\n let requestInfo = requests.deleteObject(self.authWrapper, self.location);\n return self.authWrapper.makeRequest(requestInfo, authToken).getPromise();\n });\n }\n\n /**\n * A promise that resolves with the metadata for this object. If this\n * object doesn't exist or metadata cannot be retreived, the promise is\n * rejected.\n */\n getMetadata(): Promise {\n args.validate('getMetadata', [], arguments);\n this.throwIfRoot_('getMetadata');\n let self = this;\n return this.authWrapper.getAuthToken().then(function(authToken) {\n let requestInfo = requests.getMetadata(\n self.authWrapper, self.location, self.mappings());\n return self.authWrapper.makeRequest(requestInfo, authToken).getPromise();\n });\n }\n\n /**\n * Updates the metadata for this object.\n * @param metadata The new metadata for the object.\n * Only values that have been explicitly set will be changed. Explicitly\n * setting a value to null will remove the metadata.\n * @return A promise that resolves\n * with the new metadata for this object.\n * @see firebaseStorage.Reference.prototype.getMetadata\n */\n updateMetadata(metadata: Metadata): Promise {\n args.validate('updateMetadata', [args.metadataSpec()], arguments);\n this.throwIfRoot_('updateMetadata');\n let self = this;\n return this.authWrapper.getAuthToken().then(function(authToken) {\n let requestInfo = requests.updateMetadata(\n self.authWrapper, self.location, metadata, self.mappings());\n return self.authWrapper.makeRequest(requestInfo, authToken).getPromise();\n });\n }\n\n /**\n * @return A promise that resolves with the download\n * URL for this object.\n */\n getDownloadURL(): Promise {\n args.validate('getDownloadURL', [], arguments);\n this.throwIfRoot_('getDownloadURL');\n return this.getMetadata().then(function(metadata) {\n let url = (metadata['downloadURLs'] as string[])[0];\n if (type.isDef(url)) {\n return url;\n } else {\n throw errorsExports.noDownloadURL();\n }\n });\n }\n\n private throwIfRoot_(name: string) {\n if (this.location.path === '') {\n throw errorsExports.invalidRootOperation(name);\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/reference.ts","/**\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*/\nimport {FirebaseStorageError} from './error';\nimport * as promiseimpl from './promise_external';\nimport * as RequestExports from './request';\nimport {Request} from './request';\n\n/**\n * A request whose promise always fails.\n * @struct\n * @template T\n */\nexport class FailRequest implements Request {\n promise_: Promise;\n\n constructor(error: FirebaseStorageError) {\n this.promise_ = promiseimpl.reject(error);\n }\n\n /** @inheritDoc */\n getPromise() {\n return this.promise_;\n }\n\n /** @inheritDoc */\n cancel(appDelete = false) {}\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/failrequest.ts","/**\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*/\nimport * as object from './object';\nimport * as RequestExports from './request';\nimport {Request} from './request';\nimport * as constants from './constants';\n\n/**\n * @struct\n */\nexport class RequestMap {\n private map_: {[key: number]: Request} = {};\n private id_: number;\n\n constructor() {\n this.id_ = constants.minSafeInteger;\n }\n\n /**\n * Registers the given request with this map.\n * The request is unregistered when it completes.\n * @param r The request to register.\n */\n addRequest(r: Request) {\n let id = this.id_;\n this.id_++;\n this.map_[id] = r;\n let self = this;\n\n function unmap() {\n delete self.map_[id];\n }\n r.getPromise().then(unmap, unmap);\n }\n\n /**\n * Cancels all registered requests.\n */\n clear() {\n object.forEach(this.map_, (key: string, val: Request) => {\n if (val) {\n val.cancel(true);\n }\n });\n this.map_ = {};\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/requestmap.ts","/**\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*/\nimport {Reference} from '../reference';\nimport {Service} from '../service';\nimport * as constants from './constants';\nimport * as errorsExports from './error';\nimport {errors} from './error';\nimport {FailRequest} from './failrequest';\nimport {Location} from './location';\nimport * as promiseimpl from './promise_external';\nimport {Request} from './request';\nimport {RequestInfo} from './requestinfo';\nimport {requestMaker} from './requestmaker';\nimport {RequestMap} from './requestmap';\nimport * as type from './type';\nimport {XhrIoPool} from './xhriopool';\nimport { FirebaseApp, FirebaseAuthTokenData } from \"../../app/firebase_app\";\n\n/**\n * @param app If null, getAuthToken always resolves with null.\n * @param service The storage service associated with this auth wrapper.\n * Untyped to avoid circular type dependencies.\n * @struct\n */\nexport class AuthWrapper {\n private app_: FirebaseApp|null;\n private bucket_: string|null = null;\n\n /**\n maker\n */\n private storageRefMaker_:\n (p1: AuthWrapper, p2: Location) => Reference;\n private requestMaker_: requestMaker;\n private pool_: XhrIoPool;\n private service_: Service;\n private maxOperationRetryTime_: number;\n private maxUploadRetryTime_: number;\n private requestMap_: RequestMap;\n private deleted_: boolean = false;\n\n constructor(\n app: FirebaseApp|null,\n maker: (p1: AuthWrapper, p2: Location) => Reference,\n requestMaker: requestMaker, service: Service,\n pool: XhrIoPool) {\n this.app_ = app;\n if (this.app_ !== null) {\n let options = this.app_.options;\n if (type.isDef(options)) {\n this.bucket_ = AuthWrapper.extractBucket_(options);\n }\n }\n this.storageRefMaker_ = maker;\n this.requestMaker_ = requestMaker;\n this.pool_ = pool;\n this.service_ = service;\n this.maxOperationRetryTime_ = constants.defaultMaxOperationRetryTime;\n this.maxUploadRetryTime_ = constants.defaultMaxUploadRetryTime;\n this.requestMap_ = new RequestMap();\n }\n\n private static extractBucket_(config: {[prop: string]: any}): string|null {\n let bucketString = config[constants.configOption] || null;\n if (bucketString == null) {\n return null;\n }\n let loc: Location = Location.makeFromBucketSpec(bucketString);\n return loc.bucket;\n }\n\n getAuthToken(): Promise {\n // TODO(andysoto): remove ifDef checks after firebase-app implements stubs\n // (b/28673818).\n if (this.app_ !== null && type.isDef(this.app_.INTERNAL) &&\n type.isDef(this.app_.INTERNAL.getToken)) {\n return this.app_.INTERNAL.getToken().then(\n function(response: FirebaseAuthTokenData|null): string|null {\n if (response !== null) {\n return response.accessToken;\n } else {\n return null;\n }\n },\n function(_error) {\n return null;\n });\n } else {\n return (promiseimpl.resolve(null) as Promise);\n }\n }\n\n bucket(): string|null {\n if (this.deleted_) {\n throw errorsExports.appDeleted();\n } else {\n return this.bucket_;\n }\n }\n\n /**\n * The service associated with this auth wrapper. Untyped to avoid circular\n * type dependencies.\n */\n service(): Service {\n return this.service_;\n }\n\n /**\n * Returns a new firebaseStorage.Reference object referencing this AuthWrapper\n * at the given Location.\n * @param loc The Location.\n * @return Actually a firebaseStorage.Reference, typing not allowed\n * because of circular dependency problems.\n */\n makeStorageReference(loc: Location): Reference {\n return this.storageRefMaker_(this, loc);\n }\n\n makeRequest(requestInfo: RequestInfo, authToken: string|null): Request {\n if (!this.deleted_) {\n let request = this.requestMaker_(\n requestInfo, authToken, this.pool_);\n this.requestMap_.addRequest(request);\n return request;\n } else {\n return new FailRequest(errorsExports.appDeleted());\n }\n }\n\n /**\n * Stop running requests and prevent more from being created.\n */\n deleteApp() {\n this.deleted_ = true;\n this.app_ = null;\n this.requestMap_.clear();\n }\n\n maxUploadRetryTime(): number {\n return this.maxUploadRetryTime_;\n }\n\n setMaxUploadRetryTime(time: number) {\n this.maxUploadRetryTime_ = time;\n }\n\n maxOperationRetryTime(): number {\n return this.maxOperationRetryTime_;\n }\n\n setMaxOperationRetryTime(time: number) {\n this.maxOperationRetryTime_ = time;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/implementation/authwrapper.ts","/**\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*/\nimport * as args from './implementation/args';\nimport {AuthWrapper} from './implementation/authwrapper';\nimport {Location} from './implementation/location';\nimport * as fbsPromiseImpl from './implementation/promise_external';\nimport * as RequestExports from './implementation/request';\nimport {Request} from './implementation/request';\nimport {XhrIoPool} from './implementation/xhriopool';\nimport {Reference} from './reference';\nimport { FirebaseApp } from \"../app/firebase_app\";\n\n/**\n * A service that provides firebaseStorage.Reference instances.\n * @param opt_url gs:// url to a custom Storage Bucket\n *\n * @struct\n */\nexport class Service {\n authWrapper_: AuthWrapper;\n private app_: FirebaseApp;\n private bucket_: Location|null = null;\n private internals_: ServiceInternals;\n\n constructor(app: FirebaseApp, pool: XhrIoPool, url?: string) {\n function maker(authWrapper: AuthWrapper, loc: Location) {\n return new Reference(authWrapper, loc);\n }\n this.authWrapper_ =\n new AuthWrapper(app, maker, RequestExports.makeRequest, this, pool);\n this.app_ = app;\n if (url != null) {\n this.bucket_ = Location.makeFromBucketSpec(url);\n } else {\n const authWrapperBucket = this.authWrapper_.bucket();\n if (authWrapperBucket != null) {\n this.bucket_ = new Location(authWrapperBucket, '');\n }\n }\n this.internals_ = new ServiceInternals(this);\n }\n\n /**\n * Returns a firebaseStorage.Reference for the given path in the default\n * bucket.\n */\n ref(path?: string): Reference {\n function validator(path: string) {\n if (/^[A-Za-z]+:\\/\\//.test(path)) {\n throw 'Expected child path but got a URL, use refFromURL instead.';\n }\n }\n args.validate('ref', [args.stringSpec(validator, true)], arguments);\n if (this.bucket_ == null) {\n throw new Error('No Storage Bucket defined in Firebase Options.');\n }\n\n let ref = new Reference(this.authWrapper_, this.bucket_);\n if (path != null) {\n return ref.child(path);\n } else {\n return ref;\n }\n }\n\n /**\n * Returns a firebaseStorage.Reference object for the given absolute URL,\n * which must be a gs:// or http[s]:// URL.\n */\n refFromURL(url: string): Reference {\n function validator(p: string) {\n if (!/^[A-Za-z]+:\\/\\//.test(p)) {\n throw 'Expected full URL but got a child path, use ref instead.';\n }\n try {\n Location.makeFromUrl(p);\n } catch (e) {\n throw 'Expected valid full URL but got an invalid one.';\n }\n }\n args.validate('refFromURL', [args.stringSpec(validator, false)], arguments);\n return new Reference(this.authWrapper_, url);\n }\n\n get maxUploadRetryTime(): number {\n return this.authWrapper_.maxUploadRetryTime();\n }\n\n setMaxUploadRetryTime(time: number) {\n args.validate(\n 'setMaxUploadRetryTime', [args.nonNegativeNumberSpec()], arguments);\n this.authWrapper_.setMaxUploadRetryTime(time);\n }\n\n get maxOperationRetryTime(): number {\n return this.authWrapper_.maxOperationRetryTime();\n }\n\n setMaxOperationRetryTime(time: number) {\n args.validate(\n 'setMaxOperationRetryTime', [args.nonNegativeNumberSpec()], arguments);\n this.authWrapper_.setMaxOperationRetryTime(time);\n }\n\n get app(): FirebaseApp {\n return this.app_;\n }\n\n get INTERNAL(): ServiceInternals {\n return this.internals_;\n }\n}\n\n/**\n * @struct\n */\nexport class ServiceInternals {\n service_: Service;\n\n constructor(service: Service) {\n this.service_ = service;\n }\n\n /**\n * Called when the associated app is deleted.\n * @see {!fbs.AuthWrapper.prototype.deleteApp}\n */\n delete(): Promise {\n this.service_.authWrapper_.deleteApp();\n return fbsPromiseImpl.resolve(undefined);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/storage/service.ts"]}