{"version":3,"sources":["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/database/core/util/Path.ts","webpack:///./src/database/core/snap/indexes/PriorityIndex.ts","webpack:///./src/database/core/snap/ChildrenNode.ts","webpack:///./src/database/core/snap/Node.ts","webpack:///./src/utils/json.ts","webpack:///./src/utils/validation.ts","webpack:///./src/database/core/util/validation.ts","webpack:///./src/database/core/operation/Operation.ts","webpack:///./src/utils/environment.ts","webpack:///./src/database/core/view/Change.ts","webpack:///./src/database/core/snap/indexes/KeyIndex.ts","webpack:///./src/database/core/snap/nodeFromJSON.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/database/core/snap/indexes/Index.ts","webpack:///./src/database/core/snap/LeafNode.ts","webpack:///./src/database/core/util/SortedMap.ts","webpack:///./src/database/core/operation/AckUserWrite.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/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/utils/util.ts","webpack:///./src/database/core/ReadonlyRestClient.ts","webpack:///./src/database/core/Repo.ts","webpack:///./src/utils/utf8.ts","webpack:///./src/database/api/onDisconnect.ts","webpack:///./src/database/api/TransactionResult.ts","webpack:///./src/database/core/util/NextPushId.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/util/ImmutableTree.ts","webpack:///./src/database/core/view/filter/IndexedFilter.ts","webpack:///./src/database/core/stats/StatsCollection.ts","webpack:///./src/database/core/stats/StatsManager.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/core/util/libs/parser.ts","webpack:///./src/database/core/RepoInfo.ts","webpack:///./src/database/core/view/Event.ts","webpack:///./src/database/core/view/EventRegistration.ts","webpack:///./src/database/api/Query.ts","webpack:///./src/database/core/snap/snap.ts","webpack:///./src/database/core/snap/indexes/ValueIndex.ts","webpack:///./src/database/core/snap/IndexMap.ts","webpack:///./src/database/core/snap/childSet.ts","webpack:///./src/database/core/snap/comparators.ts","webpack:///./src/database/core/snap/indexes/PathIndex.ts","webpack:///./src/database/api/DataSnapshot.ts","webpack:///./src/database/core/util/ServerValues.ts","webpack:///./src/database/core/SparseSnapshotTree.ts","webpack:///./src/database/core/util/CountedSet.ts","webpack:///./src/database/core/view/CacheNode.ts","webpack:///./src/database/core/view/ViewCache.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/SyncPoint.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/core/PersistentConnection.ts","webpack:///./src/database/realtime/TransportManager.ts","webpack:///./src/database/realtime/Connection.ts","webpack:///./src/database/realtime/polling/PacketReceiver.ts","webpack:///./src/database/realtime/BrowserPollConnection.ts","webpack:///./src/database/realtime/WebSocketConnection.ts","webpack:///./src/database/core/ServerActions.ts","webpack:///./src/database.ts","webpack:///(webpack)/buildin/harmony-module.js","webpack:///./src/database/api/internal.ts","webpack:///./src/database/api/test_access.ts"],"names":["webpackJsonpFirebase","module","__webpack_exports__","__webpack_require__","d","assert","assertionError","__WEBPACK_IMPORTED_MODULE_0__constants__","assertion","message","Error","SDK_VERSION","utils_obj","globalScope","stringToByteArray","str","output","p","i","length","c","charCodeAt","byteArrayToString","bytes","String","fromCharCode","apply","chunk","slice","base64","_","O","S","T","ENCODED_VALS_BASE","ENCODED_VALS","this","ENCODED_VALS_WEBSAFE","HAS_NATIVE_SUPPORT","atob","encodeByteArray","input","opt_webSafe","Array","isArray","init_","byteToCharMap","byteToCharMapWebSafe_","byteToCharMap_","byte1","haveByte2","byte2","haveByte3","byte3","outByte1","outByte2","outByte3","outByte4","push","join","encodeString","btoa","decodeString","decodeStringToByteArray","charToByteMap","charToByteMapWebSafe_","charToByteMap_","charAt","haveByte4","byte4","N","Hash","blockSize","__extends","extendStatics","Object","setPrototypeOf","__proto__","b","hasOwnProperty","__","constructor","prototype","create","Sha1","_super","_this","call","chain_","buf_","W_","pad_","inbuf_","total_","reset","compress_","buf","opt_offset","W","t","f","k","a","e","update","opt_length","undefined","lengthMinusBlock","n","inbuf","digest","totalBits","j","utf8","json","storage","environment","LUIDGenerator","util_base64Encode","util_base64Decode","util_sha1","logger","util_enableLogging","util_log","logWrapper","error","fatal","warn","warnIfPageIsSecure","isInvalidJSONNumber","util_executeWhenDOMReady","MIN_NAME","MAX_NAME","nameCompare","stringCompare","util_requireKey","util_ObjectToUniqueKey","splitStringBySize","util_each","util_doubleToIEEE754String","isChromeExtensionContentScript","isWindowsStoreApp","errorForServerCode","exceptionGuard","beingCrawled","setTimeoutNonBlocking","BufferImpl","_typeof","Symbol","iterator","obj","id","utf8Bytes","toString","sha1","sha1Bytes","util_buildLogMessage_","buildLogMessage_","var_args","_i","arguments","firstLog_","logger_","persistent","console","log","bind","set","remove","get","prefix","concat","window","location","protocol","indexOf","data","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","fn","document","readyState","called_1","wrappedFn_1","body","setTimeout","Math","floor","addEventListener","attachEvent","aAsInt","tryParseInt","bAsInt","key","ObjectToUniqueKey","keys","sort","segsize","len","dataSegs","substring","val","v","s","ln","bits","abs","pow","min","LN2","round","reverse","hexByteString","hexByte","parseInt","substr","toLowerCase","test","href","Windows","UI","code","query","reason","path","toUpperCase","INTEGER_REGEXP_","RegExp","intVal","stack","search","time","timeout","contains","safeGet","forEach","clone","isEmpty","getCount","map","findKey","findValue","getAnyKey","getValues","every","extend","objTo","objFrom","value","rv","opt_obj","res","opt_this","Path","ValidationPath","__WEBPACK_IMPORTED_MODULE_0__util__","__WEBPACK_IMPORTED_MODULE_1__utils_utf8__","pathOrString","pieceNum","pieces_","split","copyTo","pieceNum_","defineProperty","enumerable","configurable","getFront","getLength","popFront","getBack","pathString","toUrlEncodedString","encodeURIComponent","begin","parent","pieces","child","childPathObj","childPieces","relativePath","outerPath","innerPath","outer","inner","comparePaths","left","right","leftKeys","rightKeys","cmp","equals","other","errorPrefix_","parts_","byteLength_","max","checkValid_","pop","last","MAX_PATH_LENGTH_BYTES","MAX_PATH_DEPTH","toErrorString","setNodeFromJSON","nodeFromJSON","setMaxNode","MAX_NODE","PRIORITY_INDEX","__WEBPACK_IMPORTED_MODULE_0__Index__","__WEBPACK_IMPORTED_MODULE_1__util_util__","__WEBPACK_IMPORTED_MODULE_2__Node__","__WEBPACK_IMPORTED_MODULE_3__LeafNode__","PriorityIndex","compare","aPriority","node","getPriority","bPriority","indexCmp","compareTo","name","isDefinedOn","indexedValueChanged","oldNode","newNode","minPost","MIN","maxPost","makePost","indexValue","priorityNode","ChildrenNode","EMPTY_NODE","__WEBPACK_IMPORTED_MODULE_0__utils_assert__","__WEBPACK_IMPORTED_MODULE_2__util_SortedMap__","__WEBPACK_IMPORTED_MODULE_3__Node__","__WEBPACK_IMPORTED_MODULE_4__snap__","__WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__","__WEBPACK_IMPORTED_MODULE_6__indexes_KeyIndex__","__WEBPACK_IMPORTED_MODULE_7__IndexMap__","__WEBPACK_IMPORTED_MODULE_8__LeafNode__","__WEBPACK_IMPORTED_MODULE_9__comparators__","children_","priorityNode_","indexMap_","lazyHash_","Default","isLeafNode","updatePriority","newPriorityNode","getImmediateChild","childName","getChild","front","hasChild","updateImmediateChild","newChildNode","namedNode","newChildren","newIndexMap","newPriority","removeFromIndexes","insert","addToIndexes","updateChild","newImmediateChild","numChildren","count","exportFormat","numKeys","maxKey","allIntegerKeys","forEachChild","childNode","array","hash","toHash_1","childHash","getPredecessorChildName","index","idx","resolveIndex_","predecessor","getPredecessorKey","getFirstChildName","indexDefinition","minKey","getFirstChild","getLastChildName","getLastChild","action","inorderTraversal","wrappedNode","getIterator","getIteratorFrom","startPost","Wrap","next","peek","getNext","getReverseIterator","getReverseIteratorFrom","endPost","withIndex","hasIndex","addIndex","isIndexed","otherChildrenNode","thisIter","otherIter","thisCurrent","otherCurrent","MaxNode","defineProperties","MAX","__EMPTY_NODE","__childrenNodeConstructor","NamedNode","jsonEval","stringify","JSON","parse","errorPrefix","fnName","argumentNumber","optional","argName","validateArgCount","validateCallback","validateContextObject","minCount","maxCount","argCount","argError","callback","context","isValidPriority","validateFirebaseDataArg","validateFirebaseData","validateFirebaseMergeDataArg","validatePriority","validateEventType","validateKey","validatePathString","validateRootPathString","validateWritablePath","validateUrl","validateBoolean","__WEBPACK_IMPORTED_MODULE_0__Path__","__WEBPACK_IMPORTED_MODULE_1__utils_obj__","__WEBPACK_IMPORTED_MODULE_2__util__","__WEBPACK_IMPORTED_MODULE_3__utils_validation__","__WEBPACK_IMPORTED_MODULE_4__utils_utf8__","INVALID_KEY_REGEX_","INVALID_PATH_REGEX_","isValidKey","isValidPathString","isValidRootPathString","replace","priority","path_","hasDotValue_1","hasActualChild_1","validateFirebaseMergePaths","mergePaths","curPath","prevPath","eventType","parsedUrl","repoInfo","host","namespace","bool","OperationType","OperationSource","fromUser","fromServer","queryId","tagged","User","Server","forServerTaggedQuery","isMobileCordova","isReactNative","isNodeSdk","getUA","navigator","NODE_CLIENT","NODE_ADMIN","Change","type","snapshotNode","oldSnap","prevName","valueChange","snapshot","VALUE","childAddedChange","childKey","CHILD_ADDED","childRemovedChange","CHILD_REMOVED","childChangedChange","newSnapshot","oldSnapshot","CHILD_CHANGED","childMovedChange","CHILD_MOVED","KeyIndex","KEY_INDEX","__WEBPACK_IMPORTED_MODULE_1__Node__","__WEBPACK_IMPORTED_MODULE_2__util_util__","__WEBPACK_IMPORTED_MODULE_3__utils_assert__","__WEBPACK_IMPORTED_MODULE_0__ChildrenNode__","__WEBPACK_IMPORTED_MODULE_4__utils_assert__","jsonLeaf","__WEBPACK_IMPORTED_MODULE_1__LeafNode__","USE_HINZE","node_1","jsonObj_1","__WEBPACK_IMPORTED_MODULE_3__utils_obj__","childData","children_1","childrenHavePriority_1","hinzeJsonObj_1","childSet","__WEBPACK_IMPORTED_MODULE_5__childSet__","__WEBPACK_IMPORTED_MODULE_6__comparators__","sortedChildSet","__WEBPACK_IMPORTED_MODULE_8__indexes_PriorityIndex__","getCompare",".priority","CONSTANTS","DOMStorageWrapper_DOMStorageWrapper","DOMStorageWrapper","domStorage_","prefix_","removeItem","prefixedName_","setItem","storedVal","getItem","MemoryStorage_MemoryStorage","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","Index","__WEBPACK_IMPORTED_MODULE_0__Node__","oldWrapped","newWrapped","LeafNode","__WEBPACK_IMPORTED_MODULE_2__snap__","value_",".value","getValue","toHash","compareToLeafNode_","otherLeaf","otherLeafType","thisLeafType","otherIndex","VALUE_TYPE_ORDER","thisIndex","LLRBNode","SortedMap","SortedMapIterator","startKey","comparator","isReverse_","resultGenerator_","nodeStack_","result","hasNext","color","RED","copy","reverseTraversal","min_","fixUp_","removeMin_","isRed_","moveRedLeft_","smallest","rotateRight_","moveRedRight_","rotateLeft_","colorFlip_","nl","nr","checkMaxDepth_","blackDepth","check_","BLACK","LLRBEmptyNode","comparator_","root_","rightParent","resultGenerator","ServerValues","SparseSnapshotTree","util","Operation","AckUserWrite_AckUserWrite","AckUserWrite","affectedTree","revert","ACK_USER_WRITE","source","operationForChild","children","childTree","subtree","Empty","ImmutableTree","ListenComplete_ListenComplete","ListenComplete","LISTEN_COMPLETE","Overwrite_Overwrite","Overwrite","snap","OVERWRITE","Merge_Merge","Merge","MERGE","SyncPoint","Node","CompoundWrite_CompoundWrite","CompoundWrite","writeTree_","addWrite","rootmost","findRootMostValueAndPath","rootMostPath","setTree","addWrites","updates","newWrite","removeWrite","hasCompleteWrite","getCompleteNode","getCompleteChildren","childCompoundWrite","shadowingNode","applySubtreeWrite_","writeTree","priorityWrite_1","WriteTree_WriteTree","WriteTree","visibleWrites_","allWrites_","lastWriteId_","childWrites","WriteTreeRef","addOverwrite","writeId","visible","addMerge","changedChildren","getWrite","record","findIndex","writeToRemove","splice","removedWriteWasVisible","removedWriteOverlapsWithOtherWrites","currentWrite","recordContainsPath_","resetTree_","getCompleteWriteData","calcCompleteEventCache","treePath","completeServerCache","writeIdsToExclude","includeHiddenWrites","merge","filter","write","mergeAtPath","layerTree_","layeredCache","subMerge","calcCompleteEventChildren","completeServerChildren","completeChildren","topLevelSet","childSnap","merge_1","calcEventCacheAfterServerOverwrite","childPath","existingEventSnap","existingServerSnap","childMerge","calcCompleteChild","isCompleteForChild","getNode","shadowingWrite","calcIndexedSlice","completeServerData","toIterate","nodes","iter","writeRecord","DefaultFilter_","writes","treeRoot","compoundWrite","writePath","deepNode","treePath_","existingServerCache","SyncTree_SyncTree","SyncTree","listenProvider_","syncPointTree_","pendingWriteTree_","tagToQueryMap_","queryToTagMap_","applyUserOverwrite","newData","applyOperationToSyncPoints_","applyUserMerge","changeTree","fromObject","ackUserWrite","affectedTree_1","applyServerOverwrite","applyServerMerge","applyListenComplete","applyTaggedQueryOverwrite","tag","queryKey","queryKeyForTag_","r","parseQueryKey_","queryPath","op","applyTaggedOperation_","applyTaggedQueryMerge","applyTaggedListenComplete","addEventRegistration","eventRegistration","serverCache","foundAncestorDefaultView","foreachOnPath","pathToSyncPoint","sp","getCompleteServerCache","hasCompleteView","syncPoint","serverCacheComplete","foreachChild","childSyncPoint","completeCache","viewAlreadyExists","viewExistsForQuery","getQueryParams","loadsAllData","makeQueryKey_","getNextQueryTag_","writesCache","events","view","viewForQuery","setupListener_","removeEventRegistration","cancelError","maybeSyncPoint","cancelEvents","queryIdentifier","removedAndEvents","removed","removingDefault","covered","findOnPath","parentSyncPoint","newViews","collectDistinctViewsForSubTree_","newQuery","getQuery","listener","createListenerForView_","startListening","queryForListening_","tagForQuery_","hashFn","onComplete","stopListening","queryToRemove","tagToRemove","removeTags_","pathSoFar","fold","maybeChildSyncPoint","childMap","getCompleteView","views_1","getQueryViews","childViews","queries","removedQuery","removedQueryKey","removedQueryTag","isDefault","getRef","queriesToStop","queries_1","childQueries","queryToStop","getServerCache","status","splitIndex","nextQueryTag_","operation","applyOperation","applyOperationHelper_","syncPointTree","applyOperationDescendantsHelper_","childOperation","childServerCache","childWritesCache","SnapshotHolder_SnapshotHolder","SnapshotHolder","rootNode_","updateSnapshot","newSnapshotNode","AuthTokenProvider_AuthTokenProvider","AuthTokenProvider","app_","getToken","forceRefresh","then","Promise","reject","addTokenChangeListener","removeTokenChangeListener","notifyForInvalidToken","errorMessage","options","StatsManager","StatsListener_StatsListener","StatsListener","collection_","last_","newStats","delta","stat","FIRST_STATS_MIN_TIME","FIRST_STATS_MAX_TIME","StatsReporter_StatsReporter","StatsReporter","collection","server_","statsToReport_","statsListener_","random","reportStats_","includeStat","stats","reportedStats","haveStatsToReport","reportStats","EventQueue","eventLists_","recursionDepth_","queueEvents","eventDataList","currList","eventData","eventPath","getPath","EventQueue_EventList","add","raiseEventsAtPath","raiseQueuedEventsMatchingPredicate_","raiseEventsForChangedPath","changedPath","predicate","sentAll","eventList","raise","EventList","events_","eventFn","getEventRunner","PersistentConnection","util_querystring","querystringParams","params","arrayVal","ServerActions","ReadonlyRestClient_ReadonlyRestClient","ReadonlyRestClient","repoInfo_","onDataUpdate_","authTokenProvider_","log_","listens_","getListenId_","listen","currentHashFn","listenId","thisListen","queryStringParamaters","toRestQueryStringParameters","restRequest_","status_1","unlisten","refreshAuthToken","token","queryStringParameters","authTokenData","authToken","accessToken","url","secure","xhr","XMLHttpRequest","onreadystatechange","responseText","open","send","Database","Repo_Repo","Repo","forceRestClient","app","dataUpdateCount","eventQueue_","nextWriteId_","interceptServerDataCallback_","onDisconnect_","persistentConnection_","authTokenProvider","stats_","getCollection","onConnectStatus_","authOverride","onServerInfoUpdate_","statsReporter_","getOrCreateReporter","transactions_init_","infoData_","infoSyncTree_","infoEvents","updateInfo_","serverSyncTree_","serverTime","offsetNode","offset","Date","getTime","generateServerValues","timestamp","isMerge","taggedChildren","raw","taggedSnap","affectedPath","rerunTransactions_","interceptServerData_","connectStatus","runOnDisconnectEvents_","getNextWriteId_","setWithPriority","newVal","serverValues","newNodeUnresolved","put","errorReason","success","clearEvents","callOnCompleteCallback","abortTransactions_","childrenToMerge","empty","changedKey","changedValue","writeId_1","resolvedOnDisconnectTree","forEachTree","onDisconnectCancel","forget","onDisconnectSet","onDisconnectPut","remember","onDisconnectSetWithPriority","onDisconnectUpdate","onDisconnectMerge","addEventCallbackForQuery","removeEventCallbackForQuery","interrupt","resume","showDelta","longestName","reduce","previousValue","currentValue","statsIncrementCounter","metric","incrementCounter","__database","stringLength","__WEBPACK_IMPORTED_MODULE_0__assert__","out","high","validation","util_validation","utils_promise","onDisconnect_OnDisconnect","OnDisconnect","repo_","cancel","deferred","wrapCallback","promise","objectToMerge","newObjectToMerge","TransactionResult_TransactionResult","TransactionResult","committed","toJSON","nextPushId","PUSH_CHARS","lastPushTime","lastRandChars","now","duplicateTime","timeStampChars","Query","ValueIndex","PathIndex","IndexedFilter","RangedFilter_RangedFilter","RangedFilter","indexedFilter_","getIndex","index_","startPost_","getStartPost_","endPost_","getEndPost_","getStartPost","getEndPost","matches","newChild","optChangeAccumulator","updateFullNode","newSnap","filtered","self","filtersNodes","getIndexedFilter","hasStart","startName","getIndexStartName","getIndexStartValue","hasEnd","endName","getIndexEndName","getIndexEndValue","LimitedFilter_LimitedFilter","LimitedFilter","rangedFilter_","limit_","getLimit","reverse_","isViewFromLeft","fullLimitUpdateChild_","inRange","indexCompare_1","foundStartPost","changeAccumulator","indexCmp_1","oldEventCache","newChildNamedNode","windowBoundary","oldChildSnap","nextChild","getChildAfterChild","compareNext","trackChildChange","newEventCache","QueryParams_QueryParams","QueryParams","limitSet_","startSet_","startNameSet_","endSet_","endNameSet_","viewFrom_","indexStartValue_","indexStartName_","indexEndValue_","indexEndName_","WIRE_PROTOCOL_CONSTANTS_","VIEW_FROM_LEFT","hasLimit","hasAnchoredLimit","copy_","limit","newLimit","newParams","limitToFirst","limitToLast","VIEW_FROM_RIGHT","startAt","endAt","orderBy","getQueryObject","WIRE_PROTOCOL_CONSTANTS","INDEX_START_VALUE","INDEX_START_NAME","INDEX_END_VALUE","INDEX_END_NAME","LIMIT","viewFrom","VIEW_FROM","INDEX","getNodeFilter","REST_CONSTANTS","REST_QUERY_CONSTANTS_","qs","VALUE_INDEX","ORDER_BY","START_AT","END_AT","LIMIT_TO_FIRST","LIMIT_TO_LAST","DEFAULT","Reference_Reference","Reference","repo","getKey","getParent","parentPath","getRoot","ref","databaseProp","database","transaction","transactionUpdate","applyLocally","promiseComplete","resolve","startTransaction","setPriority","thennablePushRef","pushRef","catch","onDisconnect","__referenceConstructor","emptyChildrenSingleton","__WEBPACK_IMPORTED_MODULE_0__SortedMap__","__WEBPACK_IMPORTED_MODULE_1__Path__","EmptyChildren","tree","findRootMostMatchingPathAndValue","childExistingPathAndValue","toSet","newTree","fold_","accum","findOnPath_","pathToFollow","foreachOnPath_","currentRelativePath","foreach","foreach_","__WEBPACK_IMPORTED_MODULE_1__Change__","__WEBPACK_IMPORTED_MODULE_2__snap_ChildrenNode__","__WEBPACK_IMPORTED_MODULE_3__snap_indexes_PriorityIndex__","oldChild","deep_copy","StatsCollection_StatsCollection","StatsCollection","counters_","amount","StatsManager_StatsManager","hashString","collections_","creatorFunction","reporters_","TransactionStatus","parser","DataSnapshot","TreeNode","childCount","Tree_Tree","Tree","name_","parent_","node_","subTree","pathObj","setValue","updateParents_","clear","hasChildren","forEachDescendant","includeSelf","childrenFirst","forEachAncestor","forEachImmediateDescendantWithValue","updateChild_","childEmpty","childExists","MAX_TRANSACTION_RETRIES_","transactionQueueTree_","valueCallback","watchRef","on","unwatcher","off","order","retryCount","abortReason","currentWriteId","currentInputSnapshot","currentOutputSnapshotRaw","currentOutputSnapshotResolved","currentState","getLatestState_","RUN","queueNode","nodeQueue","priorityForNode","sendReadyTransactions_","excludeSets","pruneCompletedTransactionsBelowNode_","queue","buildTransactionQueue_","sendTransactionQueue_","setsToIgnore","txn","latestState","snapToSend","latestHash","SENT","dataToSend","pathToSend","callbacks","COMPLETED","SENT_NEEDS_ABORT","NEEDS_ABORT","rootMostTransactionNode","getAncestorTransactionNode_","rerunTransactionQueue_","txnsToRerun","q","abortTransaction","currentNode","newDataNode","hasExplicitPriority","oldWriteId","newNodeResolved","lastInput","transactionNode","transactionQueue","aggregateTransactionQueuesForNode_","to","from","abortTransactionsOnNode_","lastSent","RepoManager_RepoManager","_staticInstance","RepoManager","repos_","useRestClient_","getInstance","appName","dbUrl","databaseFromApp","createRepo","deleteRepo","appRepos","toURLString","__WEBPACK_IMPORTED_MODULE_0__core_util_util__","__WEBPACK_IMPORTED_MODULE_1__core_util_libs_parser__","__WEBPACK_IMPORTED_MODULE_2__core_util_Path__","__WEBPACK_IMPORTED_MODULE_3__utils_promise__","__WEBPACK_IMPORTED_MODULE_4__Reference__","__WEBPACK_IMPORTED_MODULE_5__core_Repo__","__WEBPACK_IMPORTED_MODULE_6__core_RepoManager__","__WEBPACK_IMPORTED_MODULE_7__utils_validation__","__WEBPACK_IMPORTED_MODULE_8__core_util_validation__","INTERNAL","DatabaseInternals","checkDeleted_","refFromURL","apiName","parsedURL","goOffline","goOnline","ServerValue","TIMESTAMP",".sv","delete","decodePath","pathStringDecoded","piece","decodeURIComponent","parseRepoInfo","__WEBPACK_IMPORTED_MODULE_1__RepoInfo__","dataURL","parseURL","subdomain","domain","webSocketOnly","scheme","port","colonInd","slashInd","parts","RepoInfo","__WEBPACK_IMPORTED_MODULE_2__storage_storage__","__WEBPACK_IMPORTED_MODULE_3__realtime_Constants__","persistenceKey","internalHost","needsQueryParam","isCacheableHost","isDemoHost","isCustomHost","updateHost","newHost","connectionURL","connURL","pairs","utils_validation","Event_DataEvent","DataEvent","getEventType","exportVal","CancelEvent","EventRegistration_ValueEventRegistration","ValueEventRegistration","callback_","cancelCallback_","context_","respondsTo","createEvent","change","ctx","cancelCB_1","cb_1","createCancelEvent","hasAnyCallback","EventRegistration_ChildEventRegistration","ChildEventRegistration","callbacks_","eventToCheck","cancelCB_2","cb_2","otherCount","otherKey","thisKey","cb","Query_Query","queryParams_","orderByCalled_","validateQueryEndpoints_","startNode","endNode","tooManyArgsError","wrongArgTypeError","validateLimit_","validateNoPreviousOrderByCall_","cancelCallbackOrContext","ret","getCancelAndContextArgs_","onValueEvent","onChildEvent","cancelCallback","container","once","userCallback","cancelOrContext","firstCall","onceCallback","err","orderByChild","parsedPath","orderByKey","orderByPriority","orderByValue","equalTo","queryObject","isEqual","sameRepo","samePath","sameQueryIdentifier","priorityHashText","validatePriorityNode","__WEBPACK_IMPORTED_MODULE_2__utils_obj__","__WEBPACK_IMPORTED_MODULE_3__nodeFromJSON__","valueNode","IndexMap","_defaultIndexMap","__WEBPACK_IMPORTED_MODULE_1__childSet__","__WEBPACK_IMPORTED_MODULE_4__indexes_PriorityIndex__","__WEBPACK_IMPORTED_MODULE_5__indexes_KeyIndex__","fallbackObject","indexes_","indexSet_","indexKey","sortedMap","existingChildren","childList","sawIndexedValue","newIndex","indexName","newIndexSet","newIndexes","indexedChildren","existingSnap","buildChildSet","__WEBPACK_IMPORTED_MODULE_0__util_SortedMap__","LOG_2","Base12Num","num","current_","mask","bits_","nextBitIsOne","keyFn","mapSortFn","buildBalancedTree","low","middle","base12","root","buildPennant","chunkSize","attachPennant","pennant","isOne","NAME_ONLY_COMPARATOR","__WEBPACK_IMPORTED_MODULE_0__util_util__","NAME_COMPARATOR","__WEBPACK_IMPORTED_MODULE_2__Index__","__WEBPACK_IMPORTED_MODULE_3__ChildrenNode__","__WEBPACK_IMPORTED_MODULE_4__Node__","__WEBPACK_IMPORTED_MODULE_5__nodeFromJSON__","indexPath_","extractChild","aChild","bChild","__WEBPACK_IMPORTED_MODULE_0__utils_validation__","__WEBPACK_IMPORTED_MODULE_1__core_util_validation__","__WEBPACK_IMPORTED_MODULE_3__core_snap_indexes_PriorityIndex__","ref_","exists","childPathString","childRef","generateWithValues","resolveDeferredValueTree","resolveDeferredValueSnapshot","__WEBPACK_IMPORTED_MODULE_2__SparseSnapshotTree__","__WEBPACK_IMPORTED_MODULE_3__snap_LeafNode__","__WEBPACK_IMPORTED_MODULE_4__snap_nodeFromJSON__","__WEBPACK_IMPORTED_MODULE_5__snap_indexes_PriorityIndex__","values","resolveDeferredValue","resolvedTree","rawPri","leafNode","childrenNode","__WEBPACK_IMPORTED_MODULE_0__util_Path__","__WEBPACK_IMPORTED_MODULE_1__snap_indexes_PriorityIndex__","__WEBPACK_IMPORTED_MODULE_2__util_CountedSet__","find","self_1","prefixPath","func","each","CountedSet","__WEBPACK_IMPORTED_MODULE_0__utils_obj__","item","CacheNode","fullyInitialized_","filtered_","isFullyInitialized","isFiltered","isCompleteForPath","ViewCache_ViewCache","ViewCache","eventCache_","serverCache_","updateEventSnap","eventSnap","complete","updateServerSnap","serverSnap","getEventCache","getCompleteEventSnap","getCompleteServerSnap","ChildChangeAccumulator_ChildChangeAccumulator","ChildChangeAccumulator","changeMap_","oldChange","oldType","getChanges","NoCompleteChildSource_","getCompleteChild","NO_COMPLETE_CHILD_SOURCE","CompleteChildSource_WriteTreeCompleteChildSource","WriteTreeCompleteChildSource","writes_","viewCache_","optCompleteServerCache_","serverNode","ProcessorResult","viewCache","changes","ViewProcessor_ViewProcessor","ViewProcessor","filter_","assertIndexed","oldViewCache","newViewCache","filterServerNode","accumulator","overwrite","applyUserOverwrite_","applyServerOverwrite_","applyUserMerge_","applyServerMerge_","revertUserWrite_","ackUserWrite_","listenComplete_","maybeAddValueEvent_","isLeafOrEmpty","oldCompleteSnap","generateEventCacheAfterServerEvent_","changePath","oldEventSnap","completeEventChildren","completeNode","oldEventNode","updatedPriority","childChangePath","newEventChild","eventChildUpdate","changedSnap","newServerCache","oldServerSnap","serverFilter","newServerNode","newEventSnap","cacheHasChild_","curViewCache","applyMerge_","viewMergeTree","serverChild","childMergeTree","isUnknownDeepMerge","ackPath","changedChildren_1","changedChildren_2","mergePath","serverCachePath","oldServerNode","serverChildren","EventGenerator_EventGenerator","EventGenerator","query_","generateEventsForChanges","eventCache","eventRegistrations","moves","generateEventsForType_","registrations","filteredChanges","compareChanges_","materializedChange","materializeSingleChange_","registration","aWrapped","bWrapped","View_View","View","initialViewCache","eventRegistrations_","indexFilter","processor_","initialServerCache","initialEventCache","eventGenerator_","cache","path_1","maybeEvent","remaining","existing","generateEventsForChanges_","getInitialEvents","initialChanges","SyncPoint_SyncPoint","views_","optCompleteServerCache","events_1","eventCacheComplete","hadCompleteView","viewQueryId","EventEmitter_EventEmitter","EventEmitter","allowedEvents_","listeners_","trigger","listeners","validateEventType_","getInitialEvent","et","VisibilityMonitor_VisibilityMonitor","VisibilityMonitor","hidden","visibilityChange","visible_","OnlineMonitor___extends","OnlineMonitor_OnlineMonitor","OnlineMonitor","online_","currentlyOnline","jwt_decode","header","claims","signature","isValidFormat","decoded","isAdmin","Connection","constants","PersistentConnection_PersistentConnection","PersistentConnection__typeof","PersistentConnection___extends","RECONNECT_MIN_DELAY","RECONNECT_MAX_DELAY_DEFAULT","authOverride_","nextPersistentConnectionId_","interruptReasons_","outstandingPuts_","outstandingPutCount_","onDisconnectRequestQueue_","connected_","reconnectDelay_","maxReconnectDelay_","securityDebugCallback_","lastSessionId","establishConnectionTimer_","requestCBHash_","requestNumber_","realtime_","authToken_","forceTokenRefresh_","invalidAuthTokenCount_","firstConnection_","lastConnectionAttemptTime_","lastConnectionEstablishedTime_","scheduleConnect_","onVisible_","onOnline_","sendRequest","onResponse","curReqNum","msg","listenSpec","sendListen_","req","payload","warnOnListenWarnings_","removeListen_","warnings","indexSpec","indexPath","tryAuth","reduceReconnectDelayIfAdminCredential_","credential","token_1","authMethod","requestData","cred","onAuthRevoked_","sendUnlisten_","queryObj","sendOnDisconnect_","request","response","putInternal","sendPut_","queued","onDataMessage_","reqNum","onDataPush_","onListenRevoked_","onSecurityDebugPacket_","onReady_","sessionId","handleTimestamp_","sendConnectStats_","restoreState_","clearTimeout","establishConnection_","online","close","onRealtimeDisconnect_","cancelSentTransactions_","shouldReconnect_","timeSinceLastConnectSucceeded","timeSinceLastConnectAttempt","reconnectDelay","onDataMessage_1","onReady_1","onDisconnect_1","connId_1","nextConnectionId_","lastSessionId_1","canceled_1","connection_1","closeFn_1","sendRequestFn","serverTimeOffset","normalizedPathString","statusCode","explanation","shift","clientName","Constants","BrowserPollConnection","WebSocketConnection","TransportManager_TransportManager","TransportManager","initTransports_","isWebSocketsAvailable","isSkipPollConnection","previouslyFailed","transports_","transports_1","ALL_TRANSPORTS","transport","initialTransport","upgradeTransport","Connection_Connection","onMessage_","onKill_","connectionCount","pendingDataMessages","state_","transportManager_","start_","conn","conn_","nextTransportId_","primaryResponsesRequired_","onMessageReceived","connReceiver_","onConnectionLost","disconnReceiver_","tx_","rx_","secondaryConn_","isHealthy_","healthyTimeout_ms","healthyTimeout_","bytesReceived","markConnectionHealthy","bytesSent","everConnected","onConnectionLost_","onSecondaryConnectionLost_","onPrimaryMessageReceived_","onSecondaryMessageReceived_","dataMsg","sendData_","tryCleanupConnection","connId","onSecondaryControl_","controlData","cmd","upgradeIfSecondaryHealthy_","secondaryResponsesRequired_","parsedData","layer","proceedWithUpgrade_","start","onControl_","onPrimaryResponse_","onHandshake_","onConnectionShutdown_","onReset_","sendPingOnPrimaryIfNecessary_","handshake","ts","version","h","onConnectionEstablished_","tryStartUpgrade_","startUpgrade_","onMessage","closeConnections_","PacketReceiver_PacketReceiver","PacketReceiver","pendingResponses","currentResponseNum","closeAfterResponse","onClose","closeAfter","responseNum","handleResponse","requestNum","this_1","toProcess","BrowserPollConnection_BrowserPollConnection","FIREBASE_LONGPOLL_COMMAND_CB_NAME","FIREBASE_LONGPOLL_DATA_CB_NAME","transportSessionId","everConnected_","urlFn","curSegmentNum","myPacketOrderer","isClosed_","connectTimeoutTimer_","onClosed_","scriptTagHolder","BrowserPollConnection_FirebaseIFrameScriptHolder","args","command","arg1","arg2","incrementIncomingBytes_","password","sendNewPolls","pN","urlParams","uniqueCallbackIdentifier","connectURL","addTag","startLongPoll","addDisconnectPingFrame","forceAllow","forceAllow_","forceDisallow","forceDisallow_","isAvailable","createElement","shutdown_","myDisconnFrame","removeChild","dataStr","base64data","MAX_URL_DATA_SIZE","enqueueSegment","pw","src","style","display","appendChild","FirebaseIFrameScriptHolder","commandCB","onMessageCB","outstandingRequests","pendingSegs","currentSerial","myIFrame","createIFrame_","script","iframeContents","doc","iframe","contentWindow","contentDocument","alive","innerHTML","myID","myPW","theURL","nodeRestRequest","newRequest_","curDataString","theSeg","seg","addLongPollTag_","segnum","totalsegs","serial","doNewRequest","keepaliveTimeout","readyStateCB","loadCB","doNodeLongPoll","newScript_1","async","onload","rstate","parentNode","onerror","process","__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","keepaliveTimer","frames","totalFrames","connectionURL_","device","headers","User-Agent","platform","env","proxy","origin","mySock","onopen","onclose","onmessage","m","handleIncomingFrame","isOldAndroid","userAgent","oldAndroidRegex","oldAndroidMatch","match","parseFloat","appendFrame_","fullMess","jsonMess","handleNewFrameCount_","frameCount","extractFrameCount_","isNaN","mess","resetKeepAlive","remainingData","sendString_","clearInterval","setInterval","responsesRequiredToBeHealthy","healthyTimeout","registerDatabase","instance","registerService","unused","__WEBPACK_IMPORTED_MODULE_5__database_core_RepoManager__","__WEBPACK_IMPORTED_MODULE_3__database_api_Reference__","__WEBPACK_IMPORTED_MODULE_2__database_api_Query__","__WEBPACK_IMPORTED_MODULE_1__database_api_Database__","enableLogging","__WEBPACK_IMPORTED_MODULE_4__database_core_util_util__","__WEBPACK_IMPORTED_MODULE_6__database_api_internal__","TEST_ACCESS","__WEBPACK_IMPORTED_MODULE_7__database_api_test_access__","exports","originalModule","webpackPolyfill","l","forceLongPolling","forceWebSockets","setSecurityDebugCallback","interceptServerData","__WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__","__WEBPACK_IMPORTED_MODULE_1__realtime_BrowserPollConnection__","DataConnection","RealTimeConnection","hijackHash","ConnectionTarget","listens","__WEBPACK_IMPORTED_MODULE_0__core_RepoInfo__","__WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__","__WEBPACK_IMPORTED_MODULE_2__core_RepoManager__","__WEBPACK_IMPORTED_MODULE_3__realtime_Connection__","simpleListen","echo","onEcho","newHash","oldPut","opt_onComplete","opt_hash","firebaseRef","_forceRestClient"],"mappings":"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","file":"firebase-database.js","sourcesContent":["try {\n webpackJsonpFirebase([0],[\n/* 0 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return assert; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return assertionError; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__constants__ = __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/**\r\n * Throws an error if the provided assertion is falsy\r\n * @param {*} assertion The assertion to be tested for falsiness\r\n * @param {!string} message The message to display if the check fails\r\n */\nvar assert = function assert(assertion, message) {\n if (!assertion) {\n throw assertionError(message);\n }\n};\n/**\r\n * Returns an Error object suitable for throwing.\r\n * @param {string} message\r\n * @return {!Error}\r\n */\nvar assertionError = function assertionError(message) {\n return new Error('Firebase Database (' + __WEBPACK_IMPORTED_MODULE_0__constants__[\"a\" /* CONSTANTS */].SDK_VERSION + ') INTERNAL ASSERT FAILED: ' + message);\n};\n\n/***/ }),\n/* 1 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar utils_obj = __webpack_require__(2);\n\n// EXTERNAL MODULE: ./src/utils/globalScope.ts\nvar globalScope = __webpack_require__(32);\n\n// CONCATENATED MODULE: ./src/utils/crypt.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 stringToByteArray = function stringToByteArray(str) {\n var output = [],\n 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/**\r\n * Turns an array of numbers into the string given by the concatenation of the\r\n * characters to which the numbers correspond.\r\n * @param {Array} bytes Array of numbers representing characters.\r\n * @return {string} Stringification of the array.\r\n */\nvar byteArrayToString = function byteArrayToString(bytes) {\n var CHUNK_SIZE = 8192;\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 // The remaining logic splits conversion by chunks since\n // Function#apply() has a maximum parameter count.\n // See discussion: http://goo.gl/LrWmZ9\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// Static lookup maps, lazily populated by init_()\nvar base64 = {\n /**\r\n * Maps bytes to characters.\r\n * @type {Object}\r\n * @private\r\n */\n byteToCharMap_: null,\n /**\r\n * Maps characters to bytes.\r\n * @type {Object}\r\n * @private\r\n */\n charToByteMap_: null,\n /**\r\n * Maps bytes to websafe characters.\r\n * @type {Object}\r\n * @private\r\n */\n byteToCharMapWebSafe_: null,\n /**\r\n * Maps websafe characters to bytes.\r\n * @type {Object}\r\n * @private\r\n */\n charToByteMapWebSafe_: null,\n /**\r\n * Our default alphabet, shared between\r\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\r\n * @type {string}\r\n */\n ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n /**\r\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\r\n * @type {string}\r\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n /**\r\n * Our websafe alphabet.\r\n * @type {string}\r\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n /**\r\n * Whether this browser supports the atob and btoa functions. This extension\r\n * started at Mozilla but is now implemented by many browsers. We use the\r\n * ASSUME_* variables to avoid pulling in the full useragent detection library\r\n * but still allowing the standard per-browser compilations.\r\n *\r\n * @type {boolean}\r\n */\n HAS_NATIVE_SUPPORT: typeof globalScope[\"a\" /* globalScope */].atob === 'function',\n /**\r\n * Base64-encode an array of bytes.\r\n *\r\n * @param {Array|Uint8Array} input An array of bytes (numbers with\r\n * value in [0, 255]) to encode.\r\n * @param {boolean=} opt_webSafe Boolean indicating we should use the\r\n * alternative alphabet.\r\n * @return {string} The base64 encoded string.\r\n */\n encodeByteArray: function encodeByteArray(input, opt_webSafe) {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n this.init_();\n var byteToCharMap = opt_webSafe ? this.byteToCharMapWebSafe_ : this.byteToCharMap_;\n var output = [];\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 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 if (!haveByte3) {\n outByte4 = 64;\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);\n }\n return output.join('');\n },\n /**\r\n * Base64-encode a string.\r\n *\r\n * @param {string} input A string to encode.\r\n * @param {boolean=} opt_webSafe If true, we should use the\r\n * alternative alphabet.\r\n * @return {string} The base64 encoded string.\r\n */\n encodeString: function 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(stringToByteArray(input), opt_webSafe);\n },\n /**\r\n * Base64-decode a string.\r\n *\r\n * @param {string} input to decode.\r\n * @param {boolean=} opt_webSafe True if we should use the\r\n * alternative alphabet.\r\n * @return {string} string representing the decoded value.\r\n */\n decodeString: function 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 /**\r\n * Base64-decode a string.\r\n *\r\n * In base-64 decoding, groups of four characters are converted into three\r\n * bytes. If the encoder did not apply padding, the input length may not\r\n * be a multiple of 4.\r\n *\r\n * In this case, the last group will have fewer than 4 characters, and\r\n * padding will be inferred. If the group has one or two characters, it decodes\r\n * to one byte. If the group has three characters, it decodes to two bytes.\r\n *\r\n * @param {string} input Input to decode.\r\n * @param {boolean=} opt_webSafe True if we should use the web-safe alphabet.\r\n * @return {!Array} bytes representing the decoded value.\r\n */\n decodeStringToByteArray: function decodeStringToByteArray(input, opt_webSafe) {\n this.init_();\n var charToByteMap = opt_webSafe ? this.charToByteMapWebSafe_ : this.charToByteMap_;\n var output = [];\n for (var i = 0; i < input.length;) {\n var byte1 = charToByteMap[input.charAt(i++)];\n var haveByte2 = i < input.length;\n var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n var haveByte3 = i < input.length;\n var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n var haveByte4 = i < input.length;\n var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw Error();\n }\n var outByte1 = byte1 << 2 | byte2 >> 4;\n output.push(outByte1);\n if (byte3 != 64) {\n var outByte2 = byte2 << 4 & 0xf0 | byte3 >> 2;\n output.push(outByte2);\n if (byte4 != 64) {\n var outByte3 = byte3 << 6 & 0xc0 | byte4;\n output.push(outByte3);\n }\n }\n }\n return output;\n },\n /**\r\n * Lazy static initialization function. Called before\r\n * accessing any of the static map variables.\r\n * @private\r\n */\n init_: function init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\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] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n// CONCATENATED MODULE: ./src/utils/hash.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// 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/**\r\n * @fileoverview Abstract cryptographic hash interface.\r\n *\r\n * See Sha1 and Md5 for sample implementations.\r\n *\r\n */\n/**\r\n * Create a cryptographic hash instance.\r\n *\r\n * @constructor\r\n * @struct\r\n */\nvar Hash = /** @class */function () {\n function Hash() {\n /**\r\n * The block size for the hasher.\r\n * @type {number}\r\n */\n this.blockSize = -1;\n }\n return Hash;\n}();\n\n// CONCATENATED MODULE: ./src/utils/Sha1.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 __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/**\r\n * @fileoverview SHA-1 cryptographic hash.\r\n * Variable names follow the notation in FIPS PUB 180-3:\r\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\r\n *\r\n * Usage:\r\n * var sha1 = new sha1();\r\n * sha1.update(bytes);\r\n * var hash = sha1.digest();\r\n *\r\n * Performance:\r\n * Chrome 23: ~400 Mbit/s\r\n * Firefox 16: ~250 Mbit/s\r\n *\r\n */\n/**\r\n * SHA-1 cryptographic hash constructor.\r\n *\r\n * The properties declared here are discussed in the above algorithm document.\r\n * @constructor\r\n * @extends {Hash}\r\n * @final\r\n * @struct\r\n */\nvar Sha1 = /** @class */function (_super) {\n __extends(Sha1, _super);\n function Sha1() {\n var _this = _super.call(this) || this;\n /**\r\n * Holds the previous values of accumulated variables a-e in the compress_\r\n * function.\r\n * @type {!Array}\r\n * @private\r\n */\n _this.chain_ = [];\n /**\r\n * A buffer holding the partially computed hash result.\r\n * @type {!Array}\r\n * @private\r\n */\n _this.buf_ = [];\n /**\r\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\r\n * as the message schedule in the docs.\r\n * @type {!Array}\r\n * @private\r\n */\n _this.W_ = [];\n /**\r\n * Contains data needed to pad messages less than 64 bytes.\r\n * @type {!Array}\r\n * @private\r\n */\n _this.pad_ = [];\n /**\r\n * @private {number}\r\n */\n _this.inbuf_ = 0;\n /**\r\n * @private {number}\r\n */\n _this.total_ = 0;\n _this.blockSize = 512 / 8;\n _this.pad_[0] = 128;\n for (var i = 1; i < _this.blockSize; ++i) {\n _this.pad_[i] = 0;\n }\n _this.reset();\n return _this;\n }\n Sha1.prototype.reset = function () {\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 this.inbuf_ = 0;\n this.total_ = 0;\n };\n /**\r\n * Internal compress helper function.\r\n * @param {!Array|!Uint8Array|string} buf Block to compress.\r\n * @param {number=} opt_offset Offset of the block in the buffer.\r\n * @private\r\n */\n Sha1.prototype.compress_ = function (buf, opt_offset) {\n if (!opt_offset) {\n opt_offset = 0;\n }\n var W = this.W_;\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 | buf.charCodeAt(opt_offset + 1) << 16 | buf.charCodeAt(opt_offset + 2) << 8 | 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 | buf[opt_offset + 1] << 16 | buf[opt_offset + 2] << 8 | buf[opt_offset + 3];\n opt_offset += 4;\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 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 // 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 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 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 Sha1.prototype.update = function (bytes, opt_length) {\n // TODO(johnlenz): tighten the function signature and remove this check\n if (bytes == null) {\n return;\n }\n if (opt_length === undefined) {\n opt_length = bytes.length;\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 // 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 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 this.inbuf_ = inbuf;\n this.total_ += opt_length;\n };\n /** @override */\n Sha1.prototype.digest = function () {\n var digest = [];\n var totalBits = this.total_ * 8;\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 // 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 this.compress_(this.buf_);\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 return Sha1;\n}(Hash);\n\n// EXTERNAL MODULE: ./src/utils/utf8.ts\nvar utf8 = __webpack_require__(25);\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// EXTERNAL MODULE: ./src/database/core/storage/storage.ts + 2 modules\nvar storage = __webpack_require__(18);\n\n// EXTERNAL MODULE: ./src/utils/environment.ts\nvar environment = __webpack_require__(13);\n\n// CONCATENATED MODULE: ./src/database/core/util/util.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return LUIDGenerator; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"f\", function() { return util_base64Encode; });\n/* unused harmony export setBufferImpl */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"e\", function() { return util_base64Decode; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"y\", function() { return util_sha1; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"u\", function() { return logger; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"j\", function() { return util_enableLogging; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"s\", function() { return util_log; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"t\", function() { return logWrapper; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"k\", function() { return error; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"o\", function() { return fatal; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"B\", function() { return warn; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"C\", function() { return warnIfPageIsSecure; });\n/* unused harmony export warnAboutUnsupportedMethod */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"q\", function() { return isInvalidJSONNumber; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"n\", function() { return util_executeWhenDOMReady; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return MIN_NAME; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return MAX_NAME; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"v\", function() { return nameCompare; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"A\", function() { return stringCompare; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"w\", function() { return util_requireKey; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return util_ObjectToUniqueKey; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"z\", function() { return splitStringBySize; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"i\", function() { return util_each; });\n/* unused harmony export bindCallback */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"h\", function() { return util_doubleToIEEE754String; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"p\", function() { return isChromeExtensionContentScript; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"r\", function() { return isWindowsStoreApp; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"l\", function() { return errorForServerCode; });\n/* unused harmony export INTEGER_REGEXP_ */\n/* unused harmony export tryParseInt */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"m\", function() { return exceptionGuard; });\n/* unused harmony export callUserCallback */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"g\", function() { return beingCrawled; });\n/* unused harmony export exportPropGetter */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"x\", function() { return setTimeoutNonBlocking; });\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\n\n\n\n\n\n\n\n/**\r\n * Returns a locally-unique ID (generated by just incrementing up from 0 each time its called).\r\n * @type {function(): number} Generated ID.\r\n */\nvar LUIDGenerator = function () {\n var id = 1;\n return function () {\n return id++;\n };\n}();\n/**\r\n * URL-safe base64 encoding\r\n * @param {!string} str\r\n * @return {!string}\r\n */\nvar util_base64Encode = function base64Encode(str) {\n var utf8Bytes = Object(utf8[\"b\" /* stringToByteArray */])(str);\n return base64.encodeByteArray(utf8Bytes, /*useWebSafe=*/true);\n};\nvar BufferImpl;\nfunction setBufferImpl(impl) {\n BufferImpl = impl;\n}\n/**\r\n * URL-safe base64 decoding\r\n *\r\n * NOTE: DO NOT use the global atob() function - it does NOT support the\r\n * base64Url variant encoding.\r\n *\r\n * @param {string} str To be decoded\r\n * @return {?string} Decoded result, if possible\r\n */\nvar util_base64Decode = function base64Decode(str) {\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 util_log('base64Decode failed: ', e);\n }\n return null;\n};\n/**\r\n * Sha1 hash of the input string\r\n * @param {!string} str The string to hash\r\n * @return {!string} The resulting hash\r\n */\nvar util_sha1 = function sha1(str) {\n var utf8Bytes = Object(utf8[\"b\" /* stringToByteArray */])(str);\n var sha1 = new Sha1();\n sha1.update(utf8Bytes);\n var sha1Bytes = sha1.digest();\n return base64.encodeByteArray(sha1Bytes);\n};\n/**\r\n * @param {...*} var_args\r\n * @return {string}\r\n * @private\r\n */\nvar util_buildLogMessage_ = function buildLogMessage_() {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n var message = '';\n for (var i = 0; i < var_args.length; i++) {\n if (Array.isArray(var_args[i]) || var_args[i] && _typeof(var_args[i]) === 'object' && typeof var_args[i].length === 'number') {\n message += buildLogMessage_.apply(null, var_args[i]);\n } else if (_typeof(var_args[i]) === 'object') {\n message += Object(json[\"b\" /* stringify */])(var_args[i]);\n } else {\n message += var_args[i];\n }\n message += ' ';\n }\n return message;\n};\n/**\r\n * Use this for all debug messages in Firebase.\r\n * @type {?function(string)}\r\n */\nvar logger = null;\n/**\r\n * Flag to check for log availability on first log message\r\n * @type {boolean}\r\n * @private\r\n */\nvar firstLog_ = true;\n/**\r\n * The implementation of Firebase.enableLogging (defined here to break dependencies)\r\n * @param {boolean|?function(string)} logger_ A flag to turn on logging, or a custom logger\r\n * @param {boolean=} persistent Whether or not to persist logging settings across refreshes\r\n */\nvar util_enableLogging = function enableLogging(logger_, persistent) {\n Object(assert[\"a\" /* 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 logger(message) {\n console.log(message);\n };\n }\n }\n if (persistent) storage[\"b\" /* SessionStorage */].set('logging_enabled', true);\n } else if (typeof logger_ === 'function') {\n logger = logger_;\n } else {\n logger = null;\n storage[\"b\" /* SessionStorage */].remove('logging_enabled');\n }\n};\n/**\r\n *\r\n * @param {...(string|Arguments)} var_args\r\n */\nvar util_log = function log() {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n if (firstLog_ === true) {\n firstLog_ = false;\n if (logger === null && storage[\"b\" /* SessionStorage */].get('logging_enabled') === true) util_enableLogging(true);\n }\n if (logger) {\n var message = util_buildLogMessage_.apply(null, var_args);\n logger(message);\n }\n};\n/**\r\n * @param {!string} prefix\r\n * @return {function(...[*])}\r\n */\nvar logWrapper = function logWrapper(prefix) {\n return function () {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n util_log.apply(void 0, [prefix].concat(var_args));\n };\n};\n/**\r\n * @param {...string} var_args\r\n */\nvar error = function error() {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n if (typeof console !== 'undefined') {\n var message = 'FIREBASE INTERNAL ERROR: ' + util_buildLogMessage_.apply(void 0, var_args);\n if (typeof console.error !== 'undefined') {\n console.error(message);\n } else {\n console.log(message);\n }\n }\n};\n/**\r\n * @param {...string} var_args\r\n */\nvar fatal = function fatal() {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n var message = util_buildLogMessage_.apply(void 0, var_args);\n throw new Error('FIREBASE FATAL ERROR: ' + message);\n};\n/**\r\n * @param {...*} var_args\r\n */\nvar warn = function warn() {\n var var_args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n var_args[_i] = arguments[_i];\n }\n if (typeof console !== 'undefined') {\n var message = 'FIREBASE WARNING: ' + util_buildLogMessage_.apply(void 0, var_args);\n if (typeof console.warn !== 'undefined') {\n console.warn(message);\n } else {\n console.log(message);\n }\n }\n};\n/**\r\n * Logs a warning if the containing page uses https. Called when a call to new Firebase\r\n * does not use https.\r\n */\nvar warnIfPageIsSecure = function warnIfPageIsSecure() {\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 && window.location.protocol.indexOf('https:') !== -1) {\n warn('Insecure Firebase access from a secure page. ' + 'Please use https in calls to new Firebase().');\n }\n};\n/**\r\n * @param {!String} methodName\r\n */\nvar warnAboutUnsupportedMethod = function warnAboutUnsupportedMethod(methodName) {\n warn(methodName + ' is unsupported and will likely change soon. ' + 'Please do not use.');\n};\n/**\r\n * Returns true if data is NaN, or +/- Infinity.\r\n * @param {*} data\r\n * @return {boolean}\r\n */\nvar isInvalidJSONNumber = function isInvalidJSONNumber(data) {\n return typeof data === 'number' && (data != data || // NaN\n data == Number.POSITIVE_INFINITY || data == Number.NEGATIVE_INFINITY);\n};\n/**\r\n * @param {function()} fn\r\n */\nvar util_executeWhenDOMReady = function executeWhenDOMReady(fn) {\n if (Object(environment[\"b\" /* 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 var called_1 = false;\n var wrappedFn_1 = function wrappedFn_1() {\n if (!document.body) {\n setTimeout(wrappedFn_1, Math.floor(10));\n return;\n }\n if (!called_1) {\n called_1 = true;\n fn();\n }\n };\n if (document.addEventListener) {\n document.addEventListener('DOMContentLoaded', wrappedFn_1, false);\n // fallback to onload.\n window.addEventListener('load', wrappedFn_1, false);\n } else if (document.attachEvent) {\n // IE.\n document.attachEvent('onreadystatechange', function () {\n if (document.readyState === 'complete') wrappedFn_1();\n });\n // fallback to onload.\n window.attachEvent('onload', wrappedFn_1);\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/**\r\n * Minimum key name. Invalid for actual data, used as a marker to sort before any valid names\r\n * @type {!string}\r\n */\nvar MIN_NAME = '[MIN_NAME]';\n/**\r\n * Maximum key name. Invalid for actual data, used as a marker to sort above any valid names\r\n * @type {!string}\r\n */\nvar MAX_NAME = '[MAX_NAME]';\n/**\r\n * Compares valid Firebase key names, plus min and max name\r\n * @param {!string} a\r\n * @param {!string} b\r\n * @return {!number}\r\n */\nvar nameCompare = function nameCompare(a, b) {\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 var aAsInt = tryParseInt(a),\n bAsInt = tryParseInt(b);\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/**\r\n * @param {!string} a\r\n * @param {!string} b\r\n * @return {!number} comparison result.\r\n */\nvar stringCompare = function stringCompare(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else {\n return 1;\n }\n};\n/**\r\n * @param {string} key\r\n * @param {Object} obj\r\n * @return {*}\r\n */\nvar util_requireKey = function requireKey(key, obj) {\n if (obj && key in obj) {\n return obj[key];\n } else {\n throw new Error('Missing required key (' + key + ') in object: ' + Object(json[\"b\" /* stringify */])(obj));\n }\n};\n/**\r\n * @param {*} obj\r\n * @return {string}\r\n */\nvar util_ObjectToUniqueKey = function ObjectToUniqueKey(obj) {\n if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || obj === null) return Object(json[\"b\" /* stringify */])(obj);\n var keys = [];\n for (var k in obj) {\n keys.push(k);\n }\n // Export as json, but with the keys sorted.\n keys.sort();\n var key = '{';\n for (var i = 0; i < keys.length; i++) {\n if (i !== 0) key += ',';\n key += Object(json[\"b\" /* stringify */])(keys[i]);\n key += ':';\n key += ObjectToUniqueKey(obj[keys[i]]);\n }\n key += '}';\n return key;\n};\n/**\r\n * Splits a string into a number of smaller segments of maximum size\r\n * @param {!string} str The string\r\n * @param {!number} segsize The maximum number of chars in the string.\r\n * @return {Array.} The string, split into appropriately-sized chunks\r\n */\nvar splitStringBySize = function splitStringBySize(str, segsize) {\n var len = str.length;\n if (len <= segsize) {\n return [str];\n }\n var dataSegs = [];\n for (var c = 0; c < len; c += segsize) {\n if (c + segsize > len) {\n dataSegs.push(str.substring(c, len));\n } else {\n dataSegs.push(str.substring(c, c + segsize));\n }\n }\n return dataSegs;\n};\n/**\r\n * Apply a function to each (key, value) pair in an object or\r\n * apply a function to each (index, value) pair in an array\r\n * @param {!(Object|Array)} obj The object or array to iterate over\r\n * @param {function(?, ?)} fn The function to apply\r\n */\nvar util_each = function each(obj, fn) {\n if (Array.isArray(obj)) {\n for (var i = 0; i < obj.length; ++i) {\n fn(i, obj[i]);\n }\n } else {\n /**\r\n * in the conversion of code we removed the goog.object.forEach\r\n * function which did a value,key callback. We standardized on\r\n * a single impl that does a key, value callback. So we invert\r\n * to not have to touch the `each` code points\r\n */\n Object(utils_obj[\"f\" /* forEach */])(obj, function (key, val) {\n return fn(val, key);\n });\n }\n};\n/**\r\n * Like goog.bind, but doesn't bother to create a closure if opt_context is null/undefined.\r\n * @param {function(*)} callback Callback function.\r\n * @param {?Object=} context Optional context to bind to.\r\n * @return {function(*)}\r\n */\nvar bindCallback = function bindCallback(callback, context) {\n return context ? callback.bind(context) : callback;\n};\n/**\r\n * Borrowed from http://hg.secondlife.com/llsd/src/tip/js/typedarray.js (MIT License)\r\n * I made one modification at the end and removed the NaN / Infinity\r\n * handling (since it seemed broken [caused an overflow] and we don't need it). See MJL comments.\r\n * @param {!number} v A double\r\n * @return {string}\r\n */\nvar util_doubleToIEEE754String = function doubleToIEEE754String(v) {\n Object(assert[\"a\" /* assert */])(!isInvalidJSONNumber(v), 'Invalid JSON number'); // MJL\n var ebits = 11,\n fbits = 52;\n var bias = (1 << ebits - 1) - 1,\n s,\n e,\n f,\n ln,\n i,\n bits,\n str;\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 } else {\n s = v < 0;\n v = Math.abs(v);\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 } else {\n // Denormalized\n e = 0;\n f = Math.round(v / Math.pow(2, 1 - bias - fbits));\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 // Return the data as a hex string. --MJL\n var hexByteString = '';\n for (i = 0; i < 64; i += 8) {\n var hexByte = parseInt(str.substr(i, 8), 2).toString(16);\n if (hexByte.length === 1) hexByte = '0' + hexByte;\n hexByteString = hexByteString + hexByte;\n }\n return hexByteString.toLowerCase();\n};\n/**\r\n * Used to detect if we're in a Chrome content script (which executes in an\r\n * isolated environment where long-polling doesn't work).\r\n * @return {boolean}\r\n */\nvar isChromeExtensionContentScript = function isChromeExtensionContentScript() {\n return !!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window['chrome'] && window['chrome']['extension'] && !/^chrome/.test(window.location.href));\n};\n/**\r\n * Used to detect if we're in a Windows 8 Store app.\r\n * @return {boolean}\r\n */\nvar isWindowsStoreApp = function isWindowsStoreApp() {\n // Check for the presence of a couple WinRT globals\n return (typeof Windows === 'undefined' ? 'undefined' : _typeof(Windows)) === 'object' && _typeof(Windows.UI) === 'object';\n};\n/**\r\n * Converts a server error code to a Javascript Error\r\n * @param {!string} code\r\n * @param {!Query} query\r\n * @return {Error}\r\n */\nvar errorForServerCode = function errorForServerCode(code, query) {\n var reason = 'Unknown Error';\n if (code === 'too_big') {\n reason = 'The data requested exceeds the maximum size ' + '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 var error = new Error(code + ' at ' + query.path.toString() + ': ' + reason);\n error.code = code.toUpperCase();\n return error;\n};\n/**\r\n * Used to test for integer-looking strings\r\n * @type {RegExp}\r\n * @private\r\n */\nvar INTEGER_REGEXP_ = new RegExp('^-?\\\\d{1,10}$');\n/**\r\n * If the string contains a 32-bit integer, return it. Else return null.\r\n * @param {!string} str\r\n * @return {?number}\r\n */\nvar tryParseInt = function tryParseInt(str) {\n if (INTEGER_REGEXP_.test(str)) {\n var intVal = Number(str);\n if (intVal >= -2147483648 && intVal <= 2147483647) {\n return intVal;\n }\n }\n return null;\n};\n/**\r\n * Helper to run some code but catch any exceptions and re-throw them later.\r\n * Useful for preventing user callbacks from breaking internal code.\r\n *\r\n * Re-throwing the exception from a setTimeout is a little evil, but it's very\r\n * convenient (we don't have to try to figure out when is a safe point to\r\n * re-throw it), and the behavior seems reasonable:\r\n *\r\n * * If you aren't pausing on exceptions, you get an error in the console with\r\n * the correct stack trace.\r\n * * If you're pausing on all exceptions, the debugger will pause on your\r\n * exception and then again when we rethrow it.\r\n * * If you're only pausing on uncaught exceptions, the debugger will only pause\r\n * on us re-throwing it.\r\n *\r\n * @param {!function()} fn The code to guard.\r\n */\nvar exceptionGuard = function exceptionGuard(fn) {\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 var stack = e.stack || '';\n warn('Exception was thrown by user callback.', stack);\n throw e;\n }, Math.floor(0));\n }\n};\n/**\r\n * Helper function to safely call opt_callback with the specified arguments. It:\r\n * 1. Turns into a no-op if opt_callback is null or undefined.\r\n * 2. Wraps the call inside exceptionGuard to prevent exceptions from breaking our state.\r\n *\r\n * @param {?Function=} callback Optional onComplete callback.\r\n * @param {...*} var_args Arbitrary args to be passed to opt_onComplete\r\n */\nvar callUserCallback = function callUserCallback(callback) {\n var var_args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n var_args[_i - 1] = arguments[_i];\n }\n if (typeof callback === 'function') {\n exceptionGuard(function () {\n callback.apply(void 0, var_args);\n });\n }\n};\n/**\r\n * @return {boolean} true if we think we're currently being crawled.\r\n */\nvar beingCrawled = function beingCrawled() {\n var userAgent = (typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window['navigator'] && window['navigator']['userAgent'] || '';\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) >= 0;\n};\n/**\r\n * Export a property of an object using a getter function.\r\n *\r\n * @param {!Object} object\r\n * @param {string} name\r\n * @param {!function(): *} fnGet\r\n */\nvar exportPropGetter = function exportPropGetter(object, name, fnGet) {\n Object.defineProperty(object, name, { get: fnGet });\n};\n/**\r\n * Same as setTimeout() except on Node.JS it will /not/ prevent the process from exiting.\r\n *\r\n * It is removed with clearTimeout() as normal.\r\n *\r\n * @param {Function} fn Function to run.\r\n * @param {number} time Milliseconds to wait before running.\r\n * @return {number|Object} The setTimeout() return value.\r\n */\nvar setTimeoutNonBlocking = function setTimeoutNonBlocking(fn, time) {\n var timeout = setTimeout(fn, time);\n if ((typeof timeout === 'undefined' ? 'undefined' : _typeof(timeout)) === 'object' && timeout['unref']) {\n timeout['unref']();\n }\n return timeout;\n};\n\n/***/ }),\n/* 2 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return contains; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"l\", function() { return safeGet; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"f\", function() { return forEach; });\n/* unused harmony export extend */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return clone; });\n/* unused harmony export isNonNullObject */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"j\", function() { return isEmpty; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"h\", function() { return getCount; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"k\", function() { return map; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return findKey; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"e\", function() { return findValue; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"g\", function() { return getAnyKey; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"i\", function() { return getValues; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return every; });\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// See http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/\nvar contains = function contains(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n};\nvar safeGet = function safeGet(obj, key) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) return obj[key];\n // else return undefined.\n};\n/**\r\n * Enumerates the keys/values in an object, excluding keys defined on the prototype.\r\n *\r\n * @param {?Object.} obj Object to enumerate.\r\n * @param {!function(K, V)} fn Function to call for each key and value.\r\n * @template K,V\r\n */\nvar forEach = function forEach(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/**\r\n * Copies all the (own) properties from one object to another.\r\n * @param {!Object} objTo\r\n * @param {!Object} objFrom\r\n * @return {!Object} objTo\r\n */\nvar extend = function extend(objTo, objFrom) {\n forEach(objFrom, function (key, value) {\n objTo[key] = value;\n });\n return objTo;\n};\n/**\r\n * Returns a clone of the specified object.\r\n * @param {!Object} obj\r\n * @return {!Object} cloned obj.\r\n */\nvar clone = function clone(obj) {\n return extend({}, obj);\n};\n/**\r\n * Returns true if obj has typeof \"object\" and is not null. Unlike goog.isObject(), does not return true\r\n * for functions.\r\n *\r\n * @param obj {*} A potential object.\r\n * @returns {boolean} True if it's an object.\r\n */\nvar isNonNullObject = function isNonNullObject(obj) {\n return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null;\n};\nvar isEmpty = function isEmpty(obj) {\n for (var key in obj) {\n return false;\n }\n return true;\n};\nvar getCount = function getCount(obj) {\n var rv = 0;\n for (var key in obj) {\n rv++;\n }\n return rv;\n};\nvar map = function map(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};\nvar findKey = function findKey(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};\nvar findValue = function findValue(obj, fn, opt_this) {\n var key = findKey(obj, fn, opt_this);\n return key && obj[key];\n};\nvar getAnyKey = function getAnyKey(obj) {\n for (var key in obj) {\n return key;\n }\n};\nvar getValues = function getValues(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/**\r\n * Tests whether every key/value pair in an object pass the test implemented\r\n * by the provided function\r\n *\r\n * @param {?Object.} obj Object to test.\r\n * @param {!function(K, V)} fn Function to call for each key and value.\r\n * @template K,V\r\n */\nvar every = function every(obj, fn) {\n for (var 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/* 3 */,\n/* 4 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Path; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return ValidationPath; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utf8__ = __webpack_require__(25);\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 * An immutable object representing a parsed path. It's immutable so that you\r\n * can pass them around to other functions without worrying about them changing\r\n * it.\r\n */\nvar Path = /** @class */function () {\n /**\r\n * @param {string|Array.} pathOrString Path string to parse,\r\n * or another path, or the raw tokens array\r\n * @param {number=} pieceNum\r\n */\n function Path(pathOrString, pieceNum) {\n if (pieceNum === void 0) {\n this.pieces_ = pathOrString.split('/');\n // Remove empty pieces.\n var copyTo = 0;\n for (var 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 this.pieceNum_ = 0;\n } else {\n this.pieces_ = pathOrString;\n this.pieceNum_ = pieceNum;\n }\n }\n Object.defineProperty(Path, \"Empty\", {\n /**\r\n * Singleton to represent an empty path\r\n *\r\n * @const\r\n */\n get: function get() {\n return new Path('');\n },\n enumerable: true,\n configurable: true\n });\n Path.prototype.getFront = function () {\n if (this.pieceNum_ >= this.pieces_.length) return null;\n return this.pieces_[this.pieceNum_];\n };\n /**\r\n * @return {number} The number of segments in this path\r\n */\n Path.prototype.getLength = function () {\n return this.pieces_.length - this.pieceNum_;\n };\n /**\r\n * @return {!Path}\r\n */\n Path.prototype.popFront = function () {\n var pieceNum = this.pieceNum_;\n if (pieceNum < this.pieces_.length) {\n pieceNum++;\n }\n return new Path(this.pieces_, pieceNum);\n };\n /**\r\n * @return {?string}\r\n */\n Path.prototype.getBack = function () {\n if (this.pieceNum_ < this.pieces_.length) return this.pieces_[this.pieces_.length - 1];\n return null;\n };\n Path.prototype.toString = function () {\n var pathString = '';\n for (var i = this.pieceNum_; i < this.pieces_.length; i++) {\n if (this.pieces_[i] !== '') pathString += '/' + this.pieces_[i];\n }\n return pathString || '/';\n };\n Path.prototype.toUrlEncodedString = function () {\n var pathString = '';\n for (var i = this.pieceNum_; i < this.pieces_.length; i++) {\n if (this.pieces_[i] !== '') pathString += '/' + encodeURIComponent(String(this.pieces_[i]));\n }\n return pathString || '/';\n };\n /**\r\n * Shallow copy of the parts of the path.\r\n *\r\n * @param {number=} begin\r\n * @return {!Array}\r\n */\n Path.prototype.slice = function (begin) {\n if (begin === void 0) {\n begin = 0;\n }\n return this.pieces_.slice(this.pieceNum_ + begin);\n };\n /**\r\n * @return {?Path}\r\n */\n Path.prototype.parent = function () {\n if (this.pieceNum_ >= this.pieces_.length) return null;\n var pieces = [];\n for (var i = this.pieceNum_; i < this.pieces_.length - 1; i++) {\n pieces.push(this.pieces_[i]);\n }return new Path(pieces, 0);\n };\n /**\r\n * @param {string|!Path} childPathObj\r\n * @return {!Path}\r\n */\n Path.prototype.child = function (childPathObj) {\n var pieces = [];\n for (var i = this.pieceNum_; i < this.pieces_.length; i++) {\n pieces.push(this.pieces_[i]);\n }if (childPathObj instanceof Path) {\n for (var i = childPathObj.pieceNum_; i < childPathObj.pieces_.length; i++) {\n pieces.push(childPathObj.pieces_[i]);\n }\n } else {\n var childPieces = childPathObj.split('/');\n for (var i = 0; i < childPieces.length; i++) {\n if (childPieces[i].length > 0) pieces.push(childPieces[i]);\n }\n }\n return new Path(pieces, 0);\n };\n /**\r\n * @return {boolean} True if there are no segments in this path\r\n */\n Path.prototype.isEmpty = function () {\n return this.pieceNum_ >= this.pieces_.length;\n };\n /**\r\n * @param {!Path} outerPath\r\n * @param {!Path} innerPath\r\n * @return {!Path} The path from outerPath to innerPath\r\n */\n Path.relativePath = function (outerPath, innerPath) {\n var outer = outerPath.getFront(),\n inner = innerPath.getFront();\n if (outer === null) {\n return innerPath;\n } else if (outer === inner) {\n return Path.relativePath(outerPath.popFront(), innerPath.popFront());\n } else {\n throw new Error('INTERNAL ERROR: innerPath (' + innerPath + ') is not within ' + 'outerPath (' + outerPath + ')');\n }\n };\n /**\r\n * @param {!Path} left\r\n * @param {!Path} right\r\n * @return {number} -1, 0, 1 if left is less, equal, or greater than the right.\r\n */\n Path.comparePaths = function (left, right) {\n var leftKeys = left.slice();\n var rightKeys = right.slice();\n for (var i = 0; i < leftKeys.length && i < rightKeys.length; i++) {\n var cmp = Object(__WEBPACK_IMPORTED_MODULE_0__util__[\"v\" /* 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 /**\r\n *\r\n * @param {Path} other\r\n * @return {boolean} true if paths are the same.\r\n */\n Path.prototype.equals = function (other) {\n if (this.getLength() !== other.getLength()) {\n return false;\n }\n for (var 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 return true;\n };\n /**\r\n *\r\n * @param {!Path} other\r\n * @return {boolean} True if this path is a parent (or the same as) other\r\n */\n Path.prototype.contains = function (other) {\n var i = this.pieceNum_;\n var 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 return Path;\n}(); // end Path\n\n/**\r\n * Dynamic (mutable) path used to count path lengths.\r\n *\r\n * This class is used to efficiently check paths for valid\r\n * length (in UTF8 bytes) and depth (used in path validation).\r\n *\r\n * Throws Error exception if path is ever invalid.\r\n *\r\n * The definition of a path always begins with '/'.\r\n */\nvar ValidationPath = /** @class */function () {\n /**\r\n * @param {!Path} path Initial Path.\r\n * @param {string} errorPrefix_ Prefix for any error messages.\r\n */\n function ValidationPath(path, errorPrefix_) {\n this.errorPrefix_ = errorPrefix_;\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 for (var i = 0; i < this.parts_.length; i++) {\n this.byteLength_ += Object(__WEBPACK_IMPORTED_MODULE_1__utils_utf8__[\"a\" /* stringLength */])(this.parts_[i]);\n }\n this.checkValid_();\n }\n Object.defineProperty(ValidationPath, \"MAX_PATH_DEPTH\", {\n /** @const {number} Maximum key depth. */\n get: function get() {\n return 32;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ValidationPath, \"MAX_PATH_LENGTH_BYTES\", {\n /** @const {number} Maximum number of (UTF8) bytes in a Firebase path. */\n get: function get() {\n return 768;\n },\n enumerable: true,\n configurable: true\n });\n /** @param {string} child */\n ValidationPath.prototype.push = function (child) {\n // Count the needed '/'\n if (this.parts_.length > 0) {\n this.byteLength_ += 1;\n }\n this.parts_.push(child);\n this.byteLength_ += Object(__WEBPACK_IMPORTED_MODULE_1__utils_utf8__[\"a\" /* stringLength */])(child);\n this.checkValid_();\n };\n ValidationPath.prototype.pop = function () {\n var last = this.parts_.pop();\n this.byteLength_ -= Object(__WEBPACK_IMPORTED_MODULE_1__utils_utf8__[\"a\" /* stringLength */])(last);\n // Un-count the previous '/'\n if (this.parts_.length > 0) {\n this.byteLength_ -= 1;\n }\n };\n ValidationPath.prototype.checkValid_ = function () {\n if (this.byteLength_ > ValidationPath.MAX_PATH_LENGTH_BYTES) {\n throw new Error(this.errorPrefix_ + 'has a key path longer than ' + ValidationPath.MAX_PATH_LENGTH_BYTES + ' bytes (' + 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 (' + ValidationPath.MAX_PATH_DEPTH + ') or object contains a cycle ' + this.toErrorString());\n }\n };\n /**\r\n * String for use in error messages - uses '.' notation for path.\r\n *\r\n * @return {string}\r\n */\n ValidationPath.prototype.toErrorString = function () {\n if (this.parts_.length == 0) {\n return '';\n }\n return \"in property '\" + this.parts_.join('.') + \"'\";\n };\n return ValidationPath;\n}();\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"c\"] = setNodeFromJSON;\n/* harmony export (immutable) */ __webpack_exports__[\"b\"] = setMaxNode;\n/* unused harmony export PriorityIndex */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return PRIORITY_INDEX; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Index__ = __webpack_require__(20);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__LeafNode__ = __webpack_require__(21);\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 __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 nodeFromJSON;\nvar MAX_NODE;\nfunction setNodeFromJSON(val) {\n nodeFromJSON = val;\n}\nfunction setMaxNode(val) {\n MAX_NODE = val;\n}\n/**\r\n * @constructor\r\n * @extends {Index}\r\n * @private\r\n */\nvar PriorityIndex = /** @class */function (_super) {\n __extends(PriorityIndex, _super);\n function PriorityIndex() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n /**\r\n * @inheritDoc\r\n */\n PriorityIndex.prototype.compare = function (a, b) {\n var aPriority = a.node.getPriority();\n var bPriority = b.node.getPriority();\n var indexCmp = aPriority.compareTo(bPriority);\n if (indexCmp === 0) {\n return Object(__WEBPACK_IMPORTED_MODULE_1__util_util__[\"v\" /* nameCompare */])(a.name, b.name);\n } else {\n return indexCmp;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PriorityIndex.prototype.isDefinedOn = function (node) {\n return !node.getPriority().isEmpty();\n };\n /**\r\n * @inheritDoc\r\n */\n PriorityIndex.prototype.indexedValueChanged = function (oldNode, newNode) {\n return !oldNode.getPriority().equals(newNode.getPriority());\n };\n /**\r\n * @inheritDoc\r\n */\n PriorityIndex.prototype.minPost = function () {\n return __WEBPACK_IMPORTED_MODULE_2__Node__[\"a\" /* NamedNode */].MIN;\n };\n /**\r\n * @inheritDoc\r\n */\n PriorityIndex.prototype.maxPost = function () {\n return new __WEBPACK_IMPORTED_MODULE_2__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_1__util_util__[\"b\" /* MAX_NAME */], new __WEBPACK_IMPORTED_MODULE_3__LeafNode__[\"a\" /* LeafNode */]('[PRIORITY-POST]', MAX_NODE));\n };\n /**\r\n * @param {*} indexValue\r\n * @param {string} name\r\n * @return {!NamedNode}\r\n */\n PriorityIndex.prototype.makePost = function (indexValue, name) {\n var priorityNode = nodeFromJSON(indexValue);\n return new __WEBPACK_IMPORTED_MODULE_2__Node__[\"a\" /* NamedNode */](name, new __WEBPACK_IMPORTED_MODULE_3__LeafNode__[\"a\" /* LeafNode */]('[PRIORITY-POST]', priorityNode));\n };\n /**\r\n * @return {!string} String representation for inclusion in a query spec\r\n */\n PriorityIndex.prototype.toString = function () {\n return '.priority';\n };\n return PriorityIndex;\n}(__WEBPACK_IMPORTED_MODULE_0__Index__[\"a\" /* Index */]);\n\nvar PRIORITY_INDEX = new PriorityIndex();\n\n/***/ }),\n/* 6 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return ChildrenNode; });\n/* unused harmony export MaxNode */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return MAX_NODE; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_SortedMap__ = __webpack_require__(22);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__snap__ = __webpack_require__(40);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__indexes_KeyIndex__ = __webpack_require__(15);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__IndexMap__ = __webpack_require__(42);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__LeafNode__ = __webpack_require__(21);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__comparators__ = __webpack_require__(44);\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 __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// TODO: For memory savings, don't store priorityNode_ if it's empty.\nvar EMPTY_NODE;\n/**\r\n * ChildrenNode is a class for storing internal nodes in a DataSnapshot\r\n * (i.e. nodes with children). It implements Node and stores the\r\n * list of children in the children property, sorted by child name.\r\n *\r\n * @constructor\r\n * @implements {Node}\r\n */\nvar ChildrenNode = /** @class */function () {\n /**\r\n *\r\n * @param {!SortedMap.} children_ List of children\r\n * of this node..\r\n * @param {?Node} priorityNode_ The priority of this node (as a snapshot node).\r\n * @param {!IndexMap} indexMap_\r\n */\n function ChildrenNode(children_, priorityNode_, indexMap_) {\n this.children_ = children_;\n this.priorityNode_ = priorityNode_;\n this.indexMap_ = indexMap_;\n this.lazyHash_ = null;\n /**\r\n * Note: The only reason we allow null priority is for EMPTY_NODE, since we can't use\r\n * EMPTY_NODE as the priority of EMPTY_NODE. We might want to consider making EMPTY_NODE its own\r\n * class instead of an empty ChildrenNode.\r\n */\n if (this.priorityNode_) {\n Object(__WEBPACK_IMPORTED_MODULE_4__snap__[\"c\" /* validatePriorityNode */])(this.priorityNode_);\n }\n if (this.children_.isEmpty()) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(!this.priorityNode_ || this.priorityNode_.isEmpty(), 'An empty node cannot have a priority');\n }\n }\n Object.defineProperty(ChildrenNode, \"EMPTY_NODE\", {\n get: function get() {\n return EMPTY_NODE || (EMPTY_NODE = new ChildrenNode(new __WEBPACK_IMPORTED_MODULE_2__util_SortedMap__[\"b\" /* SortedMap */](__WEBPACK_IMPORTED_MODULE_9__comparators__[\"a\" /* NAME_COMPARATOR */]), null, __WEBPACK_IMPORTED_MODULE_7__IndexMap__[\"a\" /* IndexMap */].Default));\n },\n enumerable: true,\n configurable: true\n });\n /** @inheritDoc */\n ChildrenNode.prototype.isLeafNode = function () {\n return false;\n };\n /** @inheritDoc */\n ChildrenNode.prototype.getPriority = function () {\n return this.priorityNode_ || EMPTY_NODE;\n };\n /** @inheritDoc */\n ChildrenNode.prototype.updatePriority = function (newPriorityNode) {\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 /** @inheritDoc */\n ChildrenNode.prototype.getImmediateChild = function (childName) {\n // Hack to treat priority as a regular child\n if (childName === '.priority') {\n return this.getPriority();\n } else {\n var child = this.children_.get(childName);\n return child === null ? EMPTY_NODE : child;\n }\n };\n /** @inheritDoc */\n ChildrenNode.prototype.getChild = function (path) {\n var front = path.getFront();\n if (front === null) return this;\n return this.getImmediateChild(front).getChild(path.popFront());\n };\n /** @inheritDoc */\n ChildrenNode.prototype.hasChild = function (childName) {\n return this.children_.get(childName) !== null;\n };\n /** @inheritDoc */\n ChildrenNode.prototype.updateImmediateChild = function (childName, newChildNode) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(newChildNode, 'We should always be passing snapshot nodes');\n if (childName === '.priority') {\n return this.updatePriority(newChildNode);\n } else {\n var namedNode = new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](childName, newChildNode);\n var newChildren = void 0,\n newIndexMap = void 0,\n newPriority = void 0;\n if (newChildNode.isEmpty()) {\n newChildren = this.children_.remove(childName);\n newIndexMap = this.indexMap_.removeFromIndexes(namedNode, this.children_);\n } else {\n newChildren = this.children_.insert(childName, newChildNode);\n newIndexMap = this.indexMap_.addToIndexes(namedNode, this.children_);\n }\n newPriority = newChildren.isEmpty() ? EMPTY_NODE : this.priorityNode_;\n return new ChildrenNode(newChildren, newPriority, newIndexMap);\n }\n };\n /** @inheritDoc */\n ChildrenNode.prototype.updateChild = function (path, newChildNode) {\n var front = path.getFront();\n if (front === null) {\n return newChildNode;\n } else {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(path.getFront() !== '.priority' || path.getLength() === 1, '.priority must be the last token in a path');\n var newImmediateChild = this.getImmediateChild(front).updateChild(path.popFront(), newChildNode);\n return this.updateImmediateChild(front, newImmediateChild);\n }\n };\n /** @inheritDoc */\n ChildrenNode.prototype.isEmpty = function () {\n return this.children_.isEmpty();\n };\n /** @inheritDoc */\n ChildrenNode.prototype.numChildren = function () {\n return this.children_.count();\n };\n /** @inheritDoc */\n ChildrenNode.prototype.val = function (exportFormat) {\n if (this.isEmpty()) return null;\n var obj = {};\n var numKeys = 0,\n maxKey = 0,\n allIntegerKeys = true;\n this.forEachChild(__WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], function (key, childNode) {\n obj[key] = childNode.val(exportFormat);\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 if (!exportFormat && allIntegerKeys && maxKey < 2 * numKeys) {\n // convert to array.\n var array = [];\n for (var key in obj) {\n array[key] = obj[key];\n }return array;\n } else {\n if (exportFormat && !this.getPriority().isEmpty()) {\n obj['.priority'] = this.getPriority().val();\n }\n return obj;\n }\n };\n /** @inheritDoc */\n ChildrenNode.prototype.hash = function () {\n if (this.lazyHash_ === null) {\n var toHash_1 = '';\n if (!this.getPriority().isEmpty()) toHash_1 += 'priority:' + Object(__WEBPACK_IMPORTED_MODULE_4__snap__[\"a\" /* priorityHashText */])(this.getPriority().val()) + ':';\n this.forEachChild(__WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], function (key, childNode) {\n var childHash = childNode.hash();\n if (childHash !== '') toHash_1 += ':' + key + ':' + childHash;\n });\n this.lazyHash_ = toHash_1 === '' ? '' : Object(__WEBPACK_IMPORTED_MODULE_1__util_util__[\"y\" /* sha1 */])(toHash_1);\n }\n return this.lazyHash_;\n };\n /** @inheritDoc */\n ChildrenNode.prototype.getPredecessorChildName = function (childName, childNode, index) {\n var idx = this.resolveIndex_(index);\n if (idx) {\n var predecessor = idx.getPredecessorKey(new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](childName, childNode));\n return predecessor ? predecessor.name : null;\n } else {\n return this.children_.getPredecessorKey(childName);\n }\n };\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {?string}\r\n */\n ChildrenNode.prototype.getFirstChildName = function (indexDefinition) {\n var idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n var minKey = idx.minKey();\n return minKey && minKey.name;\n } else {\n return this.children_.minKey();\n }\n };\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {?NamedNode}\r\n */\n ChildrenNode.prototype.getFirstChild = function (indexDefinition) {\n var minKey = this.getFirstChildName(indexDefinition);\n if (minKey) {\n return new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](minKey, this.children_.get(minKey));\n } else {\n return null;\n }\n };\n /**\r\n * Given an index, return the key name of the largest value we have, according to that index\r\n * @param {!Index} indexDefinition\r\n * @return {?string}\r\n */\n ChildrenNode.prototype.getLastChildName = function (indexDefinition) {\n var idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n var maxKey = idx.maxKey();\n return maxKey && maxKey.name;\n } else {\n return this.children_.maxKey();\n }\n };\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {?NamedNode}\r\n */\n ChildrenNode.prototype.getLastChild = function (indexDefinition) {\n var maxKey = this.getLastChildName(indexDefinition);\n if (maxKey) {\n return new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](maxKey, this.children_.get(maxKey));\n } else {\n return null;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ChildrenNode.prototype.forEachChild = function (index, action) {\n var 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 /**\r\n * @param {!Index} indexDefinition\r\n * @return {SortedMapIterator}\r\n */\n ChildrenNode.prototype.getIterator = function (indexDefinition) {\n return this.getIteratorFrom(indexDefinition.minPost(), indexDefinition);\n };\n /**\r\n *\r\n * @param {!NamedNode} startPost\r\n * @param {!Index} indexDefinition\r\n * @return {!SortedMapIterator}\r\n */\n ChildrenNode.prototype.getIteratorFrom = function (startPost, indexDefinition) {\n var idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n return idx.getIteratorFrom(startPost, function (key) {\n return key;\n });\n } else {\n var iterator = this.children_.getIteratorFrom(startPost.name, __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */].Wrap);\n var 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 /**\r\n * @param {!Index} indexDefinition\r\n * @return {!SortedMapIterator}\r\n */\n ChildrenNode.prototype.getReverseIterator = function (indexDefinition) {\n return this.getReverseIteratorFrom(indexDefinition.maxPost(), indexDefinition);\n };\n /**\r\n * @param {!NamedNode} endPost\r\n * @param {!Index} indexDefinition\r\n * @return {!SortedMapIterator}\r\n */\n ChildrenNode.prototype.getReverseIteratorFrom = function (endPost, indexDefinition) {\n var idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n return idx.getReverseIteratorFrom(endPost, function (key) {\n return key;\n });\n } else {\n var iterator = this.children_.getReverseIteratorFrom(endPost.name, __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */].Wrap);\n var 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 /**\r\n * @inheritDoc\r\n */\n ChildrenNode.prototype.compareTo = function (other) {\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 /**\r\n * @inheritDoc\r\n */\n ChildrenNode.prototype.withIndex = function (indexDefinition) {\n if (indexDefinition === __WEBPACK_IMPORTED_MODULE_6__indexes_KeyIndex__[\"a\" /* KEY_INDEX */] || this.indexMap_.hasIndex(indexDefinition)) {\n return this;\n } else {\n var newIndexMap = this.indexMap_.addIndex(indexDefinition, this.children_);\n return new ChildrenNode(this.children_, this.priorityNode_, newIndexMap);\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ChildrenNode.prototype.isIndexed = function (index) {\n return index === __WEBPACK_IMPORTED_MODULE_6__indexes_KeyIndex__[\"a\" /* KEY_INDEX */] || this.indexMap_.hasIndex(index);\n };\n /**\r\n * @inheritDoc\r\n */\n ChildrenNode.prototype.equals = function (other) {\n if (other === this) {\n return true;\n } else if (other.isLeafNode()) {\n return false;\n } else {\n var otherChildrenNode = other;\n if (!this.getPriority().equals(otherChildrenNode.getPriority())) {\n return false;\n } else if (this.children_.count() === otherChildrenNode.children_.count()) {\n var thisIter = this.getIterator(__WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */]);\n var otherIter = otherChildrenNode.getIterator(__WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */]);\n var thisCurrent = thisIter.getNext();\n var 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 /**\r\n * Returns a SortedMap ordered by index, or null if the default (by-key) ordering can be used\r\n * instead.\r\n *\r\n * @private\r\n * @param {!Index} indexDefinition\r\n * @return {?SortedMap.}\r\n */\n ChildrenNode.prototype.resolveIndex_ = function (indexDefinition) {\n if (indexDefinition === __WEBPACK_IMPORTED_MODULE_6__indexes_KeyIndex__[\"a\" /* KEY_INDEX */]) {\n return null;\n } else {\n return this.indexMap_.get(indexDefinition.toString());\n }\n };\n /**\r\n * @private\r\n * @type {RegExp}\r\n */\n ChildrenNode.INTEGER_REGEXP_ = /^(0|[1-9]\\d*)$/;\n return ChildrenNode;\n}();\n\n/**\r\n * @constructor\r\n * @extends {ChildrenNode}\r\n * @private\r\n */\nvar MaxNode = /** @class */function (_super) {\n __extends(MaxNode, _super);\n function MaxNode() {\n return _super.call(this, new __WEBPACK_IMPORTED_MODULE_2__util_SortedMap__[\"b\" /* SortedMap */](__WEBPACK_IMPORTED_MODULE_9__comparators__[\"a\" /* NAME_COMPARATOR */]), ChildrenNode.EMPTY_NODE, __WEBPACK_IMPORTED_MODULE_7__IndexMap__[\"a\" /* IndexMap */].Default) || this;\n }\n MaxNode.prototype.compareTo = function (other) {\n if (other === this) {\n return 0;\n } else {\n return 1;\n }\n };\n MaxNode.prototype.equals = function (other) {\n // Not that we every compare it, but MAX_NODE is only ever equal to itself\n return other === this;\n };\n MaxNode.prototype.getPriority = function () {\n return this;\n };\n MaxNode.prototype.getImmediateChild = function (childName) {\n return ChildrenNode.EMPTY_NODE;\n };\n MaxNode.prototype.isEmpty = function () {\n return false;\n };\n return MaxNode;\n}(ChildrenNode);\n\n/**\r\n * Marker that will sort higher than any other snapshot.\r\n * @type {!MAX_NODE}\r\n * @const\r\n */\nvar MAX_NODE = new MaxNode();\nObject.defineProperties(__WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */], {\n MIN: {\n value: new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_1__util_util__[\"c\" /* MIN_NAME */], ChildrenNode.EMPTY_NODE)\n },\n MAX: {\n value: new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_1__util_util__[\"b\" /* MAX_NAME */], MAX_NODE)\n }\n});\n/**\r\n * Reference Extensions\r\n */\n__WEBPACK_IMPORTED_MODULE_6__indexes_KeyIndex__[\"b\" /* KeyIndex */].__EMPTY_NODE = ChildrenNode.EMPTY_NODE;\n__WEBPACK_IMPORTED_MODULE_8__LeafNode__[\"a\" /* LeafNode */].__childrenNodeConstructor = ChildrenNode;\nObject(__WEBPACK_IMPORTED_MODULE_4__snap__[\"b\" /* setMaxNode */])(MAX_NODE);\nObject(__WEBPACK_IMPORTED_MODULE_5__indexes_PriorityIndex__[\"b\" /* setMaxNode */])(MAX_NODE);\n\n/***/ }),\n/* 7 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return NamedNode; });\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 *\r\n * @param {!string} name\r\n * @param {!Node} node\r\n * @constructor\r\n * @struct\r\n */\nvar NamedNode = /** @class */function () {\n function NamedNode(name, node) {\n this.name = name;\n this.node = node;\n }\n /**\r\n *\r\n * @param {!string} name\r\n * @param {!Node} node\r\n * @return {NamedNode}\r\n */\n NamedNode.Wrap = function (name, node) {\n return new NamedNode(name, node);\n };\n return NamedNode;\n}();\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return jsonEval; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return stringify; });\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 * Evaluates a JSON string into a javascript object.\r\n *\r\n * @param {string} str A string containing JSON.\r\n * @return {*} The javascript object representing the specified JSON.\r\n */\nvar jsonEval = function jsonEval(str) {\n return JSON.parse(str);\n};\n/**\r\n * Returns JSON representing a javascript object.\r\n * @param {*} data Javascript object to be stringified.\r\n * @return {string} The JSON contents of the object.\r\n */\nvar stringify = function stringify(data) {\n return JSON.stringify(data);\n};\n\n/***/ }),\n/* 9 */,\n/* 10 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return validateArgCount; });\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = errorPrefix;\n/* unused harmony export validateNamespace */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return validateCallback; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return validateContextObject; });\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 * Check to make sure the appropriate number of arguments are provided for a public function.\r\n * Throws an error if it fails.\r\n *\r\n * @param {!string} fnName The function name\r\n * @param {!number} minCount The minimum number of arguments to allow for the function call\r\n * @param {!number} maxCount The maximum number of argument to allow for the function call\r\n * @param {!number} argCount The actual number of arguments provided.\r\n */\nvar validateArgCount = function validateArgCount(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 + (argCount === 1 ? ' argument.' : ' arguments.') + ' Expects ' + argError + '.';\n throw new Error(error);\n }\n};\n/**\r\n * Generates a string to prefix an error message about failed argument validation\r\n *\r\n * @param {!string} fnName The function name\r\n * @param {!number} argumentNumber The index of the argument\r\n * @param {boolean} optional Whether or not the argument is optional\r\n * @return {!string} The prefix to add to the error thrown for validation.\r\n */\nfunction 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 var error = fnName + ' failed: ';\n error += argName + ' argument ';\n return error;\n}\n/**\r\n * @param {!string} fnName\r\n * @param {!number} argumentNumber\r\n * @param {!string} namespace\r\n * @param {boolean} optional\r\n */\nvar validateNamespace = function validateNamespace(fnName, argumentNumber, namespace, optional) {\n if (optional && !namespace) 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) + 'must be a valid firebase namespace.');\n }\n};\nvar validateCallback = function validateCallback(fnName, argumentNumber, callback, optional) {\n if (optional && !callback) return;\n if (typeof callback !== 'function') throw new Error(errorPrefix(fnName, argumentNumber, optional) + 'must be a valid function.');\n};\nvar validateContextObject = function validateContextObject(fnName, argumentNumber, context, optional) {\n if (optional && !context) return;\n if ((typeof context === 'undefined' ? 'undefined' : _typeof(context)) !== 'object' || context === null) throw new Error(errorPrefix(fnName, argumentNumber, optional) + 'must be a valid context object.');\n};\n\n/***/ }),\n/* 11 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* unused harmony export INVALID_KEY_REGEX_ */\n/* unused harmony export INVALID_PATH_REGEX_ */\n/* unused harmony export MAX_LEAF_SIZE_ */\n/* unused harmony export isValidKey */\n/* unused harmony export isValidPathString */\n/* unused harmony export isValidRootPathString */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return isValidPriority; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"e\", function() { return validateFirebaseDataArg; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return validateFirebaseData; });\n/* unused harmony export validateFirebaseMergePaths */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"f\", function() { return validateFirebaseMergeDataArg; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"i\", function() { return validatePriority; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return validateEventType; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"g\", function() { return validateKey; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"h\", function() { return validatePathString; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"j\", function() { return validateRootPathString; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"l\", function() { return validateWritablePath; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"k\", function() { return validateUrl; });\n/* unused harmony export validateCredential */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return validateBoolean; });\n/* unused harmony export validateString */\n/* unused harmony export validateObject */\n/* unused harmony export validateObjectContainsKey */\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_validation__ = __webpack_require__(10);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_utf8__ = __webpack_require__(25);\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\n\n\n\n\n/**\r\n * True for invalid Firebase keys\r\n * @type {RegExp}\r\n * @private\r\n */\nvar INVALID_KEY_REGEX_ = /[\\[\\].#$\\/\\u0000-\\u001F\\u007F]/;\n/**\r\n * True for invalid Firebase paths.\r\n * Allows '/' in paths.\r\n * @type {RegExp}\r\n * @private\r\n */\nvar INVALID_PATH_REGEX_ = /[\\[\\].#$\\u0000-\\u001F\\u007F]/;\n/**\r\n * Maximum number of characters to allow in leaf value\r\n * @type {number}\r\n * @private\r\n */\nvar MAX_LEAF_SIZE_ = 10 * 1024 * 1024;\n/**\r\n * @param {*} key\r\n * @return {boolean}\r\n */\nvar isValidKey = function isValidKey(key) {\n return typeof key === 'string' && key.length !== 0 && !INVALID_KEY_REGEX_.test(key);\n};\n/**\r\n * @param {string} pathString\r\n * @return {boolean}\r\n */\nvar isValidPathString = function isValidPathString(pathString) {\n return typeof pathString === 'string' && pathString.length !== 0 && !INVALID_PATH_REGEX_.test(pathString);\n};\n/**\r\n * @param {string} pathString\r\n * @return {boolean}\r\n */\nvar isValidRootPathString = function isValidRootPathString(pathString) {\n if (pathString) {\n // Allow '/.info/' at the beginning.\n pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\n }\n return isValidPathString(pathString);\n};\n/**\r\n * @param {*} priority\r\n * @return {boolean}\r\n */\nvar isValidPriority = function isValidPriority(priority) {\n return priority === null || typeof priority === 'string' || typeof priority === 'number' && !Object(__WEBPACK_IMPORTED_MODULE_2__util__[\"q\" /* isInvalidJSONNumber */])(priority) || priority && (typeof priority === 'undefined' ? 'undefined' : _typeof(priority)) === 'object' && Object(__WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"b\" /* contains */])(priority, '.sv');\n};\n/**\r\n * Pre-validate a datum passed as an argument to Firebase function.\r\n *\r\n * @param {string} fnName\r\n * @param {number} argumentNumber\r\n * @param {*} data\r\n * @param {!Path} path\r\n * @param {boolean} optional\r\n */\nvar validateFirebaseDataArg = function validateFirebaseDataArg(fnName, argumentNumber, data, path, optional) {\n if (optional && data === undefined) return;\n validateFirebaseData(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional), data, path);\n};\n/**\r\n * Validate a data object client-side before sending to server.\r\n *\r\n * @param {string} errorPrefix\r\n * @param {*} data\r\n * @param {!Path|!ValidationPath} path_\r\n */\nvar validateFirebaseData = function validateFirebaseData(errorPrefix, data, path_) {\n var path = path_ instanceof __WEBPACK_IMPORTED_MODULE_0__Path__[\"a\" /* Path */] ? new __WEBPACK_IMPORTED_MODULE_0__Path__[\"b\" /* ValidationPath */](path_, errorPrefix) : path_;\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() + ' with contents = ' + data.toString());\n }\n if (Object(__WEBPACK_IMPORTED_MODULE_2__util__[\"q\" /* isInvalidJSONNumber */])(data)) {\n throw new Error(errorPrefix + 'contains ' + data.toString() + ' ' + path.toErrorString());\n }\n // Check max leaf size, but try to avoid the utf8 conversion if we can.\n if (typeof data === 'string' && data.length > MAX_LEAF_SIZE_ / 3 && Object(__WEBPACK_IMPORTED_MODULE_4__utils_utf8__[\"a\" /* stringLength */])(data) > MAX_LEAF_SIZE_) {\n throw new Error(errorPrefix + 'contains a string greater than ' + MAX_LEAF_SIZE_ + ' utf8 bytes ' + path.toErrorString() + \" ('\" + data.substring(0, 50) + \"...')\");\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 === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {\n var hasDotValue_1 = false,\n hasActualChild_1 = false;\n Object(__WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"f\" /* forEach */])(data, function (key, value) {\n if (key === '.value') {\n hasDotValue_1 = true;\n } else if (key !== '.priority' && key !== '.sv') {\n hasActualChild_1 = true;\n if (!isValidKey(key)) {\n throw new Error(errorPrefix + ' contains an invalid key (' + key + ') ' + path.toErrorString() + '. Keys must be non-empty strings ' + 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"');\n }\n }\n path.push(key);\n validateFirebaseData(errorPrefix, value, path);\n path.pop();\n });\n if (hasDotValue_1 && hasActualChild_1) {\n throw new Error(errorPrefix + ' contains \".value\" child ' + path.toErrorString() + ' in addition to actual children.');\n }\n }\n};\n/**\r\n * Pre-validate paths passed in the firebase function.\r\n *\r\n * @param {string} errorPrefix\r\n * @param {Array} mergePaths\r\n */\nvar validateFirebaseMergePaths = function validateFirebaseMergePaths(errorPrefix, mergePaths) {\n var i, curPath;\n for (i = 0; i < mergePaths.length; i++) {\n curPath = mergePaths[i];\n var keys = curPath.slice();\n for (var 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 ' + curPath.toString() + '. Keys must be non-empty strings ' + 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"');\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(__WEBPACK_IMPORTED_MODULE_0__Path__[\"a\" /* Path */].comparePaths);\n var prevPath = 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() + ' that is ancestor of another path ' + curPath.toString());\n }\n prevPath = curPath;\n }\n};\n/**\r\n * pre-validate an object passed as an argument to firebase function (\r\n * must be an object - e.g. for firebase.update()).\r\n *\r\n * @param {string} fnName\r\n * @param {number} argumentNumber\r\n * @param {*} data\r\n * @param {!Path} path\r\n * @param {boolean} optional\r\n */\nvar validateFirebaseMergeDataArg = function validateFirebaseMergeDataArg(fnName, argumentNumber, data, path, optional) {\n if (optional && data === undefined) return;\n var errorPrefix = Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional);\n if (!(data && (typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') || Array.isArray(data)) {\n throw new Error(errorPrefix + ' must be an object containing the children to replace.');\n }\n var mergePaths = [];\n Object(__WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"f\" /* forEach */])(data, function (key, value) {\n var curPath = new __WEBPACK_IMPORTED_MODULE_0__Path__[\"a\" /* Path */](key);\n validateFirebaseData(errorPrefix, value, path.child(curPath));\n if (curPath.getBack() === '.priority') {\n if (!isValidPriority(value)) {\n throw new Error(errorPrefix + \"contains an invalid value for '\" + curPath.toString() + \"', which must be a valid \" + 'Firebase priority (a string, finite number, server value, or null).');\n }\n }\n mergePaths.push(curPath);\n });\n validateFirebaseMergePaths(errorPrefix, mergePaths);\n};\nvar validatePriority = function validatePriority(fnName, argumentNumber, priority, optional) {\n if (optional && priority === undefined) return;\n if (Object(__WEBPACK_IMPORTED_MODULE_2__util__[\"q\" /* isInvalidJSONNumber */])(priority)) throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'is ' + priority.toString() + ', but must be a valid Firebase priority (a string, finite number, ' + 'server value, or null).');\n // Special case to allow importing data with a .sv.\n if (!isValidPriority(priority)) throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must be a valid Firebase priority ' + '(a string, finite number, server value, or null).');\n};\nvar validateEventType = function validateEventType(fnName, argumentNumber, eventType, optional) {\n if (optional && eventType === undefined) return;\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(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must be a valid event type = \"value\", \"child_added\", \"child_removed\", ' + '\"child_changed\", or \"child_moved\".');\n }\n};\nvar validateKey = function validateKey(fnName, argumentNumber, key, optional) {\n if (optional && key === undefined) return;\n if (!isValidKey(key)) throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'was an invalid key = \"' + key + '\". Firebase keys must be non-empty strings and ' + 'can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\").');\n};\nvar validatePathString = function validatePathString(fnName, argumentNumber, pathString, optional) {\n if (optional && pathString === undefined) return;\n if (!isValidPathString(pathString)) throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'was an invalid path = \"' + pathString + '\". Paths must be non-empty strings and ' + 'can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\"');\n};\nvar validateRootPathString = function validateRootPathString(fnName, argumentNumber, pathString, optional) {\n if (pathString) {\n // Allow '/.info/' at the beginning.\n pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\n }\n validatePathString(fnName, argumentNumber, pathString, optional);\n};\nvar validateWritablePath = function validateWritablePath(fnName, path) {\n if (path.getFront() === '.info') {\n throw new Error(fnName + \" failed = Can't modify data under /.info/\");\n }\n};\nvar validateUrl = function validateUrl(fnName, argumentNumber, parsedUrl) {\n // TODO = Validate server better.\n var pathString = parsedUrl.path.toString();\n if (!(typeof parsedUrl.repoInfo.host === 'string') || parsedUrl.repoInfo.host.length === 0 || !isValidKey(parsedUrl.repoInfo.namespace) || pathString.length !== 0 && !isValidRootPathString(pathString)) {\n throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, false) + 'must be a valid firebase URL and ' + 'the path can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\".');\n }\n};\nvar validateCredential = function validateCredential(fnName, argumentNumber, cred, optional) {\n if (optional && cred === undefined) return;\n if (!(typeof cred === 'string')) throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must be a valid credential (a string).');\n};\nvar validateBoolean = function validateBoolean(fnName, argumentNumber, bool, optional) {\n if (optional && bool === undefined) return;\n if (typeof bool !== 'boolean') throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must be a boolean.');\n};\nvar validateString = function validateString(fnName, argumentNumber, string, optional) {\n if (optional && string === undefined) return;\n if (!(typeof string === 'string')) {\n throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must be a valid string.');\n }\n};\nvar validateObject = function validateObject(fnName, argumentNumber, obj, optional) {\n if (optional && obj === undefined) return;\n if (!(obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') || obj === null) {\n throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must be a valid object.');\n }\n};\nvar validateObjectContainsKey = function validateObjectContainsKey(fnName, argumentNumber, obj, key, optional, opt_type) {\n var objectContainsKey = obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && Object(__WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"b\" /* contains */])(obj, key);\n if (!objectContainsKey) {\n if (optional) {\n return;\n } else {\n throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must contain the key \"' + key + '\"');\n }\n }\n if (opt_type) {\n var val = Object(__WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"l\" /* safeGet */])(obj, key);\n if (opt_type === 'number' && !(typeof val === 'number') || opt_type === 'string' && !(typeof val === 'string') || opt_type === 'boolean' && !(typeof val === 'boolean') || opt_type === 'function' && !(typeof val === 'function') || opt_type === 'object' && !((typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object') && val) {\n if (optional) {\n throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'contains invalid value for key \"' + key + '\" (must be of type \"' + opt_type + '\")');\n } else {\n throw new Error(Object(__WEBPACK_IMPORTED_MODULE_3__utils_validation__[\"a\" /* errorPrefix */])(fnName, argumentNumber, optional) + 'must contain the key \"' + key + '\" with type \"' + opt_type + '\"');\n }\n }\n }\n};\n\n/***/ }),\n/* 12 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return OperationType; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return OperationSource; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__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/**\r\n *\r\n * @enum\r\n */\nvar OperationType;\n(function (OperationType) {\n OperationType[OperationType[\"OVERWRITE\"] = 0] = \"OVERWRITE\";\n OperationType[OperationType[\"MERGE\"] = 1] = \"MERGE\";\n OperationType[OperationType[\"ACK_USER_WRITE\"] = 2] = \"ACK_USER_WRITE\";\n OperationType[OperationType[\"LISTEN_COMPLETE\"] = 3] = \"LISTEN_COMPLETE\";\n})(OperationType || (OperationType = {}));\n/**\r\n * @param {boolean} fromUser\r\n * @param {boolean} fromServer\r\n * @param {?string} queryId\r\n * @param {boolean} tagged\r\n * @constructor\r\n */\nvar OperationSource = /** @class */function () {\n function OperationSource(fromUser, fromServer, queryId, tagged) {\n this.fromUser = fromUser;\n this.fromServer = fromServer;\n this.queryId = queryId;\n this.tagged = tagged;\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(!tagged || fromServer, 'Tagged queries must be from server.');\n }\n /**\r\n * @const\r\n * @type {!OperationSource}\r\n */\n OperationSource.User = new OperationSource(\n /*fromUser=*/true, false, null,\n /*tagged=*/false);\n /**\r\n * @const\r\n * @type {!OperationSource}\r\n */\n OperationSource.Server = new OperationSource(false,\n /*fromServer=*/true, null,\n /*tagged=*/false);\n /**\r\n * @param {string} queryId\r\n * @return {!OperationSource}\r\n */\n OperationSource.forServerTaggedQuery = function (queryId) {\n return new OperationSource(false,\n /*fromServer=*/true, queryId,\n /*tagged=*/true);\n };\n return OperationSource;\n}();\n\n\n/***/ }),\n/* 13 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* unused harmony export getUA */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return isMobileCordova; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return isReactNative; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return isNodeSdk; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__constants__ = __webpack_require__(17);\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\n/**\r\n * Returns navigator.userAgent string or '' if it's not defined.\r\n * @return {string} user agent string\r\n */\nvar getUA = function getUA() {\n if (typeof navigator !== 'undefined' && typeof navigator['userAgent'] === 'string') {\n return navigator['userAgent'];\n } else {\n return '';\n }\n};\n/**\r\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\r\n *\r\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap in the Ripple emulator) nor\r\n * Cordova `onDeviceReady`, which would normally wait for a callback.\r\n *\r\n * @return {boolean} isMobileCordova\r\n */\nvar isMobileCordova = function isMobileCordova() {\n return typeof window !== 'undefined' && !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA());\n};\n/**\r\n * Detect React Native.\r\n *\r\n * @return {boolean} True if ReactNative environment is detected.\r\n */\nvar isReactNative = function isReactNative() {\n return (typeof navigator === 'undefined' ? 'undefined' : _typeof(navigator)) === 'object' && navigator['product'] === 'ReactNative';\n};\n/**\r\n * Detect Node.js.\r\n *\r\n * @return {boolean} True if Node.js environment is detected.\r\n */\nvar isNodeSdk = function isNodeSdk() {\n return __WEBPACK_IMPORTED_MODULE_0__constants__[\"a\" /* CONSTANTS */].NODE_CLIENT === true || __WEBPACK_IMPORTED_MODULE_0__constants__[\"a\" /* CONSTANTS */].NODE_ADMIN === true;\n};\n\n/***/ }),\n/* 14 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Change; });\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 * @constructor\r\n * @struct\r\n * @param {!string} type The event type\r\n * @param {!Node} snapshotNode The data\r\n * @param {string=} childName The name for this child, if it's a child event\r\n * @param {Node=} oldSnap Used for intermediate processing of child changed events\r\n * @param {string=} prevName The name for the previous child, if applicable\r\n */\nvar Change = /** @class */function () {\n function Change(type, snapshotNode, childName, oldSnap, prevName) {\n this.type = type;\n this.snapshotNode = snapshotNode;\n this.childName = childName;\n this.oldSnap = oldSnap;\n this.prevName = prevName;\n }\n /**\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\n Change.valueChange = function (snapshot) {\n return new Change(Change.VALUE, snapshot);\n };\n /**\r\n * @param {string} childKey\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\n Change.childAddedChange = function (childKey, snapshot) {\n return new Change(Change.CHILD_ADDED, snapshot, childKey);\n };\n /**\r\n * @param {string} childKey\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\n Change.childRemovedChange = function (childKey, snapshot) {\n return new Change(Change.CHILD_REMOVED, snapshot, childKey);\n };\n /**\r\n * @param {string} childKey\r\n * @param {!Node} newSnapshot\r\n * @param {!Node} oldSnapshot\r\n * @return {!Change}\r\n */\n Change.childChangedChange = function (childKey, newSnapshot, oldSnapshot) {\n return new Change(Change.CHILD_CHANGED, newSnapshot, childKey, oldSnapshot);\n };\n /**\r\n * @param {string} childKey\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\n Change.childMovedChange = function (childKey, snapshot) {\n return new Change(Change.CHILD_MOVED, snapshot, childKey);\n };\n //event types\n /** Event type for a child added */\n Change.CHILD_ADDED = 'child_added';\n /** Event type for a child removed */\n Change.CHILD_REMOVED = 'child_removed';\n /** Event type for a child changed */\n Change.CHILD_CHANGED = 'child_changed';\n /** Event type for a child moved */\n Change.CHILD_MOVED = 'child_moved';\n /** Event type for a value change */\n Change.VALUE = 'value';\n return Change;\n}();\n\n\n/***/ }),\n/* 15 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return KeyIndex; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return KEY_INDEX; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Index__ = __webpack_require__(20);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_util__ = __webpack_require__(1);\n/* harmony import */ var __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 */\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\nvar __EMPTY_NODE;\nvar KeyIndex = /** @class */function (_super) {\n __extends(KeyIndex, _super);\n function KeyIndex() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n Object.defineProperty(KeyIndex, \"__EMPTY_NODE\", {\n get: function get() {\n return __EMPTY_NODE;\n },\n set: function set(val) {\n __EMPTY_NODE = val;\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * @inheritDoc\r\n */\n KeyIndex.prototype.compare = function (a, b) {\n return Object(__WEBPACK_IMPORTED_MODULE_2__util_util__[\"v\" /* nameCompare */])(a.name, b.name);\n };\n /**\r\n * @inheritDoc\r\n */\n KeyIndex.prototype.isDefinedOn = function (node) {\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 Object(__WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"b\" /* assertionError */])('KeyIndex.isDefinedOn not expected to be called.');\n };\n /**\r\n * @inheritDoc\r\n */\n KeyIndex.prototype.indexedValueChanged = function (oldNode, newNode) {\n return false; // The key for a node never changes.\n };\n /**\r\n * @inheritDoc\r\n */\n KeyIndex.prototype.minPost = function () {\n return __WEBPACK_IMPORTED_MODULE_1__Node__[\"a\" /* NamedNode */].MIN;\n };\n /**\r\n * @inheritDoc\r\n */\n KeyIndex.prototype.maxPost = function () {\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 __WEBPACK_IMPORTED_MODULE_1__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_2__util_util__[\"b\" /* MAX_NAME */], __EMPTY_NODE);\n };\n /**\r\n * @param {*} indexValue\r\n * @param {string} name\r\n * @return {!NamedNode}\r\n */\n KeyIndex.prototype.makePost = function (indexValue, name) {\n Object(__WEBPACK_IMPORTED_MODULE_3__utils_assert__[\"a\" /* 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 __WEBPACK_IMPORTED_MODULE_1__Node__[\"a\" /* NamedNode */](indexValue, __EMPTY_NODE);\n };\n /**\r\n * @return {!string} String representation for inclusion in a query spec\r\n */\n KeyIndex.prototype.toString = function () {\n return '.key';\n };\n return KeyIndex;\n}(__WEBPACK_IMPORTED_MODULE_0__Index__[\"a\" /* Index */]);\n\nvar KEY_INDEX = new KeyIndex();\n\n/***/ }),\n/* 16 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = nodeFromJSON;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ChildrenNode__ = __webpack_require__(6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__LeafNode__ = __webpack_require__(21);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__childSet__ = __webpack_require__(43);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__comparators__ = __webpack_require__(44);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__IndexMap__ = __webpack_require__(42);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__indexes_PriorityIndex__ = __webpack_require__(5);\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\n\n\n\n\n\n\n\n\nvar USE_HINZE = true;\n/**\r\n * Constructs a snapshot node representing the passed JSON and returns it.\r\n * @param {*} json JSON to create a node for.\r\n * @param {?string|?number=} priority Optional priority to use. This will be ignored if the\r\n * passed JSON contains a .priority property.\r\n * @return {!Node}\r\n */\nfunction nodeFromJSON(json, priority) {\n if (priority === void 0) {\n priority = null;\n }\n if (json === null) {\n return __WEBPACK_IMPORTED_MODULE_0__ChildrenNode__[\"a\" /* ChildrenNode */].EMPTY_NODE;\n }\n if ((typeof json === 'undefined' ? 'undefined' : _typeof(json)) === 'object' && '.priority' in json) {\n priority = json['.priority'];\n }\n Object(__WEBPACK_IMPORTED_MODULE_4__utils_assert__[\"a\" /* assert */])(priority === null || typeof priority === 'string' || typeof priority === 'number' || (typeof priority === 'undefined' ? 'undefined' : _typeof(priority)) === 'object' && '.sv' in priority, 'Invalid priority type found: ' + (typeof priority === 'undefined' ? 'undefined' : _typeof(priority)));\n if ((typeof json === 'undefined' ? 'undefined' : _typeof(json)) === 'object' && '.value' in json && json['.value'] !== null) {\n json = json['.value'];\n }\n // Valid leaf nodes include non-objects or server-value wrapper objects\n if ((typeof json === 'undefined' ? 'undefined' : _typeof(json)) !== 'object' || '.sv' in json) {\n var jsonLeaf = json;\n return new __WEBPACK_IMPORTED_MODULE_1__LeafNode__[\"a\" /* LeafNode */](jsonLeaf, nodeFromJSON(priority));\n }\n if (!(json instanceof Array) && USE_HINZE) {\n var children_1 = [];\n var childrenHavePriority_1 = false;\n var hinzeJsonObj_1 = json;\n Object(__WEBPACK_IMPORTED_MODULE_3__utils_obj__[\"f\" /* forEach */])(hinzeJsonObj_1, function (key, child) {\n if (typeof key !== 'string' || key.substring(0, 1) !== '.') {\n // Ignore metadata nodes\n var childNode = nodeFromJSON(hinzeJsonObj_1[key]);\n if (!childNode.isEmpty()) {\n childrenHavePriority_1 = childrenHavePriority_1 || !childNode.getPriority().isEmpty();\n children_1.push(new __WEBPACK_IMPORTED_MODULE_2__Node__[\"a\" /* NamedNode */](key, childNode));\n }\n }\n });\n if (children_1.length == 0) {\n return __WEBPACK_IMPORTED_MODULE_0__ChildrenNode__[\"a\" /* ChildrenNode */].EMPTY_NODE;\n }\n var childSet = Object(__WEBPACK_IMPORTED_MODULE_5__childSet__[\"a\" /* buildChildSet */])(children_1, __WEBPACK_IMPORTED_MODULE_6__comparators__[\"b\" /* NAME_ONLY_COMPARATOR */], function (namedNode) {\n return namedNode.name;\n }, __WEBPACK_IMPORTED_MODULE_6__comparators__[\"a\" /* NAME_COMPARATOR */]);\n if (childrenHavePriority_1) {\n var sortedChildSet = Object(__WEBPACK_IMPORTED_MODULE_5__childSet__[\"a\" /* buildChildSet */])(children_1, __WEBPACK_IMPORTED_MODULE_8__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */].getCompare());\n return new __WEBPACK_IMPORTED_MODULE_0__ChildrenNode__[\"a\" /* ChildrenNode */](childSet, nodeFromJSON(priority), new __WEBPACK_IMPORTED_MODULE_7__IndexMap__[\"a\" /* IndexMap */]({ '.priority': sortedChildSet }, { '.priority': __WEBPACK_IMPORTED_MODULE_8__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */] }));\n } else {\n return new __WEBPACK_IMPORTED_MODULE_0__ChildrenNode__[\"a\" /* ChildrenNode */](childSet, nodeFromJSON(priority), __WEBPACK_IMPORTED_MODULE_7__IndexMap__[\"a\" /* IndexMap */].Default);\n }\n } else {\n var node_1 = __WEBPACK_IMPORTED_MODULE_0__ChildrenNode__[\"a\" /* ChildrenNode */].EMPTY_NODE;\n var jsonObj_1 = json;\n Object(__WEBPACK_IMPORTED_MODULE_3__utils_obj__[\"f\" /* forEach */])(jsonObj_1, function (key, childData) {\n if (Object(__WEBPACK_IMPORTED_MODULE_3__utils_obj__[\"b\" /* contains */])(jsonObj_1, key)) {\n if (key.substring(0, 1) !== '.') {\n // ignore metadata nodes.\n var childNode = nodeFromJSON(childData);\n if (childNode.isLeafNode() || !childNode.isEmpty()) node_1 = node_1.updateImmediateChild(key, childNode);\n }\n }\n });\n return node_1.updatePriority(nodeFromJSON(priority));\n }\n}\nObject(__WEBPACK_IMPORTED_MODULE_8__indexes_PriorityIndex__[\"c\" /* setNodeFromJSON */])(nodeFromJSON);\n\n/***/ }),\n/* 17 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return CONSTANTS; });\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 Firebase constants. Some of these (@defines) can be overridden at compile-time.\r\n */\nvar CONSTANTS = {\n /**\r\n * @define {boolean} Whether this is the client Node.js SDK.\r\n */\n NODE_CLIENT: false,\n /**\r\n * @define {boolean} Whether this is the Admin Node.js SDK.\r\n */\n NODE_ADMIN: false,\n /**\r\n * Firebase SDK Version\r\n */\n SDK_VERSION: '4.5.0'\n};\n\n/***/ }),\n/* 18 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// CONCATENATED MODULE: ./src/database/core/storage/DOMStorageWrapper.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 * Wraps a DOM Storage object and:\r\n * - automatically encode objects as JSON strings before storing them to allow us to store arbitrary types.\r\n * - prefixes names with \"firebase:\" to avoid collisions with app data.\r\n *\r\n * We automatically (see storage.js) create two such wrappers, one for sessionStorage,\r\n * and one for localStorage.\r\n *\r\n * @constructor\r\n */\nvar DOMStorageWrapper_DOMStorageWrapper = /** @class */function () {\n /**\r\n * @param {Storage} domStorage_ The underlying storage object (e.g. localStorage or sessionStorage)\r\n */\n function DOMStorageWrapper(domStorage_) {\n this.domStorage_ = domStorage_;\n // Use a prefix to avoid collisions with other stuff saved by the app.\n this.prefix_ = 'firebase:';\n }\n /**\r\n * @param {string} key The key to save the value under\r\n * @param {?Object} value The value being stored, or null to remove the key.\r\n */\n DOMStorageWrapper.prototype.set = function (key, value) {\n if (value == null) {\n this.domStorage_.removeItem(this.prefixedName_(key));\n } else {\n this.domStorage_.setItem(this.prefixedName_(key), Object(json[\"b\" /* stringify */])(value));\n }\n };\n /**\r\n * @param {string} key\r\n * @return {*} The value that was stored under this key, or null\r\n */\n DOMStorageWrapper.prototype.get = function (key) {\n var storedVal = this.domStorage_.getItem(this.prefixedName_(key));\n if (storedVal == null) {\n return null;\n } else {\n return Object(json[\"a\" /* jsonEval */])(storedVal);\n }\n };\n /**\r\n * @param {string} key\r\n */\n DOMStorageWrapper.prototype.remove = function (key) {\n this.domStorage_.removeItem(this.prefixedName_(key));\n };\n /**\r\n * @param {string} name\r\n * @return {string}\r\n */\n DOMStorageWrapper.prototype.prefixedName_ = function (name) {\n return this.prefix_ + name;\n };\n DOMStorageWrapper.prototype.toString = function () {\n return this.domStorage_.toString();\n };\n return DOMStorageWrapper;\n}();\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar obj = __webpack_require__(2);\n\n// CONCATENATED MODULE: ./src/database/core/storage/MemoryStorage.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 * An in-memory storage implementation that matches the API of DOMStorageWrapper\r\n * (TODO: create interface for both to implement).\r\n *\r\n * @constructor\r\n */\nvar MemoryStorage_MemoryStorage = /** @class */function () {\n function MemoryStorage() {\n this.cache_ = {};\n this.isInMemoryStorage = true;\n }\n MemoryStorage.prototype.set = function (key, value) {\n if (value == null) {\n delete this.cache_[key];\n } else {\n this.cache_[key] = value;\n }\n };\n MemoryStorage.prototype.get = function (key) {\n if (Object(obj[\"b\" /* contains */])(this.cache_, key)) {\n return this.cache_[key];\n }\n return null;\n };\n MemoryStorage.prototype.remove = function (key) {\n delete this.cache_[key];\n };\n return MemoryStorage;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/storage/storage.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return PersistentStorage; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return SessionStorage; });\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 * Helper to create a DOMStorageWrapper or else fall back to MemoryStorage.\r\n * TODO: Once MemoryStorage and DOMStorageWrapper have a shared interface this method annotation should change\r\n * to reflect this type\r\n *\r\n * @param {string} domStorageName Name of the underlying storage object\r\n * (e.g. 'localStorage' or 'sessionStorage').\r\n * @return {?} Turning off type information until a common interface is defined.\r\n */\nvar storage_createStoragefor = function createStoragefor(domStorageName) {\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 var domStorage = window[domStorageName];\n domStorage.setItem('firebase:sentinel', 'cache');\n domStorage.removeItem('firebase:sentinel');\n return new DOMStorageWrapper_DOMStorageWrapper(domStorage);\n }\n } catch (e) {}\n // Failed to create wrapper. Just return in-memory storage.\n // TODO: log?\n return new MemoryStorage_MemoryStorage();\n};\n/** A storage object that lasts across sessions */\nvar PersistentStorage = storage_createStoragefor('localStorage');\n/** A storage object that only lasts one session */\nvar SessionStorage = storage_createStoragefor('sessionStorage');\n\n/***/ }),\n/* 19 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"e\", function() { return PROTOCOL_VERSION; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"h\", function() { return VERSION_PARAM; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"g\", function() { return TRANSPORT_SESSION_PARAM; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"f\", function() { return REFERER_PARAM; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return FORGE_REF; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return FORGE_DOMAIN; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return LAST_SESSION_PARAM; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"i\", function() { return WEBSOCKET; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return LONG_POLLING; });\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 PROTOCOL_VERSION = '5';\nvar VERSION_PARAM = 'v';\nvar TRANSPORT_SESSION_PARAM = 's';\nvar REFERER_PARAM = 'r';\nvar FORGE_REF = 'f';\nvar FORGE_DOMAIN = 'firebaseio.com';\nvar LAST_SESSION_PARAM = 'ls';\nvar WEBSOCKET = 'websocket';\nvar LONG_POLLING = 'long_polling';\n\n/***/ }),\n/* 20 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Index; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__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/**\r\n *\r\n * @constructor\r\n */\nvar Index = /** @class */function () {\n function Index() {}\n /**\r\n * @return {function(!NamedNode, !NamedNode):number} A standalone comparison function for\r\n * this index\r\n */\n Index.prototype.getCompare = function () {\n return this.compare.bind(this);\n };\n /**\r\n * Given a before and after value for a node, determine if the indexed value has changed. Even if they are different,\r\n * it's possible that the changes are isolated to parts of the snapshot that are not indexed.\r\n *\r\n * @param {!Node} oldNode\r\n * @param {!Node} newNode\r\n * @return {boolean} True if the portion of the snapshot being indexed changed between oldNode and newNode\r\n */\n Index.prototype.indexedValueChanged = function (oldNode, newNode) {\n var oldWrapped = new __WEBPACK_IMPORTED_MODULE_0__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_1__util_util__[\"c\" /* MIN_NAME */], oldNode);\n var newWrapped = new __WEBPACK_IMPORTED_MODULE_0__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_1__util_util__[\"c\" /* MIN_NAME */], newNode);\n return this.compare(oldWrapped, newWrapped) !== 0;\n };\n /**\r\n * @return {!NamedNode} a node wrapper that will sort equal to or less than\r\n * any other node wrapper, using this index\r\n */\n Index.prototype.minPost = function () {\n return __WEBPACK_IMPORTED_MODULE_0__Node__[\"a\" /* NamedNode */].MIN;\n };\n return Index;\n}();\n\n\n/***/ }),\n/* 21 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return LeafNode; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__snap__ = __webpack_require__(40);\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\n\n\nvar __childrenNodeConstructor;\n/**\r\n * LeafNode is a class for storing leaf nodes in a DataSnapshot. It\r\n * implements Node and stores the value of the node (a string,\r\n * number, or boolean) accessible via getValue().\r\n */\nvar LeafNode = /** @class */function () {\n /**\r\n * @implements {Node}\r\n * @param {!(string|number|boolean|Object)} value_ The value to store in this leaf node.\r\n * The object type is possible in the event of a deferred value\r\n * @param {!Node=} priorityNode_ The priority of this node.\r\n */\n function LeafNode(value_, priorityNode_) {\n if (priorityNode_ === void 0) {\n priorityNode_ = LeafNode.__childrenNodeConstructor.EMPTY_NODE;\n }\n this.value_ = value_;\n this.priorityNode_ = priorityNode_;\n this.lazyHash_ = null;\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(this.value_ !== undefined && this.value_ !== null, \"LeafNode shouldn't be created with null/undefined value.\");\n Object(__WEBPACK_IMPORTED_MODULE_2__snap__[\"c\" /* validatePriorityNode */])(this.priorityNode_);\n }\n Object.defineProperty(LeafNode, \"__childrenNodeConstructor\", {\n get: function get() {\n return __childrenNodeConstructor;\n },\n set: function set(val) {\n __childrenNodeConstructor = val;\n },\n enumerable: true,\n configurable: true\n });\n /** @inheritDoc */\n LeafNode.prototype.isLeafNode = function () {\n return true;\n };\n /** @inheritDoc */\n LeafNode.prototype.getPriority = function () {\n return this.priorityNode_;\n };\n /** @inheritDoc */\n LeafNode.prototype.updatePriority = function (newPriorityNode) {\n return new LeafNode(this.value_, newPriorityNode);\n };\n /** @inheritDoc */\n LeafNode.prototype.getImmediateChild = function (childName) {\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 /** @inheritDoc */\n LeafNode.prototype.getChild = function (path) {\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 /**\r\n * @inheritDoc\r\n */\n LeafNode.prototype.hasChild = function () {\n return false;\n };\n /** @inheritDoc */\n LeafNode.prototype.getPredecessorChildName = function (childName, childNode) {\n return null;\n };\n /** @inheritDoc */\n LeafNode.prototype.updateImmediateChild = function (childName, newChildNode) {\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.updateImmediateChild(childName, newChildNode).updatePriority(this.priorityNode_);\n }\n };\n /** @inheritDoc */\n LeafNode.prototype.updateChild = function (path, newChildNode) {\n var front = path.getFront();\n if (front === null) {\n return newChildNode;\n } else if (newChildNode.isEmpty() && front !== '.priority') {\n return this;\n } else {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(front !== '.priority' || path.getLength() === 1, '.priority must be the last token in a path');\n return this.updateImmediateChild(front, LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(path.popFront(), newChildNode));\n }\n };\n /** @inheritDoc */\n LeafNode.prototype.isEmpty = function () {\n return false;\n };\n /** @inheritDoc */\n LeafNode.prototype.numChildren = function () {\n return 0;\n };\n /** @inheritDoc */\n LeafNode.prototype.forEachChild = function (index, action) {\n return false;\n };\n /**\r\n * @inheritDoc\r\n */\n LeafNode.prototype.val = function (exportFormat) {\n if (exportFormat && !this.getPriority().isEmpty()) return {\n '.value': this.getValue(),\n '.priority': this.getPriority().val()\n };else return this.getValue();\n };\n /** @inheritDoc */\n LeafNode.prototype.hash = function () {\n if (this.lazyHash_ === null) {\n var toHash = '';\n if (!this.priorityNode_.isEmpty()) toHash += 'priority:' + Object(__WEBPACK_IMPORTED_MODULE_2__snap__[\"a\" /* priorityHashText */])(this.priorityNode_.val()) + ':';\n var type = _typeof(this.value_);\n toHash += type + ':';\n if (type === 'number') {\n toHash += Object(__WEBPACK_IMPORTED_MODULE_1__util_util__[\"h\" /* doubleToIEEE754String */])(this.value_);\n } else {\n toHash += this.value_;\n }\n this.lazyHash_ = Object(__WEBPACK_IMPORTED_MODULE_1__util_util__[\"y\" /* sha1 */])(toHash);\n }\n return this.lazyHash_;\n };\n /**\r\n * Returns the value of the leaf node.\r\n * @return {Object|string|number|boolean} The value of the node.\r\n */\n LeafNode.prototype.getValue = function () {\n return this.value_;\n };\n /**\r\n * @inheritDoc\r\n */\n LeafNode.prototype.compareTo = function (other) {\n if (other === LeafNode.__childrenNodeConstructor.EMPTY_NODE) {\n return 1;\n } else if (other instanceof LeafNode.__childrenNodeConstructor) {\n return -1;\n } else {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(other.isLeafNode(), 'Unknown node type');\n return this.compareToLeafNode_(other);\n }\n };\n /**\r\n * Comparison specifically for two leaf nodes\r\n * @param {!LeafNode} otherLeaf\r\n * @return {!number}\r\n * @private\r\n */\n LeafNode.prototype.compareToLeafNode_ = function (otherLeaf) {\n var otherLeafType = _typeof(otherLeaf.value_);\n var thisLeafType = _typeof(this.value_);\n var otherIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(otherLeafType);\n var thisIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(thisLeafType);\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(otherIndex >= 0, 'Unknown leaf type: ' + otherLeafType);\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* 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 /**\r\n * @inheritDoc\r\n */\n LeafNode.prototype.withIndex = function () {\n return this;\n };\n /**\r\n * @inheritDoc\r\n */\n LeafNode.prototype.isIndexed = function () {\n return true;\n };\n /**\r\n * @inheritDoc\r\n */\n LeafNode.prototype.equals = function (other) {\n /**\r\n * @inheritDoc\r\n */\n if (other === this) {\n return true;\n } else if (other.isLeafNode()) {\n var otherLeaf = other;\n return this.value_ === otherLeaf.value_ && this.priorityNode_.equals(otherLeaf.priorityNode_);\n } else {\n return false;\n }\n };\n /**\r\n * The sort order for comparing leaf nodes of different types. If two leaf nodes have\r\n * the same type, the comparison falls back to their value\r\n * @type {Array.}\r\n * @const\r\n */\n LeafNode.VALUE_TYPE_ORDER = ['object', 'boolean', 'number', 'string'];\n return LeafNode;\n}();\n\n\n/***/ }),\n/* 22 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* unused harmony export SortedMapIterator */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return LLRBNode; });\n/* unused harmony export LLRBEmptyNode */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return SortedMap; });\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 * An iterator over an LLRBNode.\r\n */\nvar SortedMapIterator = /** @class */function () {\n /**\r\n * @template K, V, T\r\n * @param {LLRBNode|LLRBEmptyNode} node Node to iterate.\r\n * @param {?K} startKey\r\n * @param {function(K, K): number} comparator\r\n * @param {boolean} isReverse_ Whether or not to iterate in reverse\r\n * @param {(function(K, V):T)=} resultGenerator_\r\n */\n function SortedMapIterator(node, startKey, comparator, isReverse_, resultGenerator_) {\n if (resultGenerator_ === void 0) {\n resultGenerator_ = null;\n }\n this.isReverse_ = isReverse_;\n this.resultGenerator_ = resultGenerator_;\n /** @private\r\n * @type {Array.}\r\n */\n this.nodeStack_ = [];\n var cmp = 1;\n while (!node.isEmpty()) {\n node = node;\n cmp = startKey ? comparator(node.key, startKey) : 1;\n // flip the comparison if we're going in reverse\n if (isReverse_) cmp *= -1;\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 SortedMapIterator.prototype.getNext = function () {\n if (this.nodeStack_.length === 0) return null;\n var node = this.nodeStack_.pop();\n var result;\n if (this.resultGenerator_) result = this.resultGenerator_(node.key, node.value);else result = { key: node.key, value: node.value };\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 return result;\n };\n SortedMapIterator.prototype.hasNext = function () {\n return this.nodeStack_.length > 0;\n };\n SortedMapIterator.prototype.peek = function () {\n if (this.nodeStack_.length === 0) return null;\n var 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 };\n }\n };\n return SortedMapIterator;\n}();\n\n/**\r\n * Represents a node in a Left-leaning Red-Black tree.\r\n */\nvar LLRBNode = /** @class */function () {\n /**\r\n * @template K, V\r\n * @param {!K} key Key associated with this node.\r\n * @param {!V} value Value associated with this node.\r\n * @param {?boolean} color Whether this node is red.\r\n * @param {?(LLRBNode|LLRBEmptyNode)=} left Left child.\r\n * @param {?(LLRBNode|LLRBEmptyNode)=} right Right child.\r\n */\n function LLRBNode(key, value, color, left, right) {\n this.key = key;\n this.value = value;\n this.color = color != null ? color : LLRBNode.RED;\n this.left = left != null ? left : SortedMap.EMPTY_NODE;\n this.right = right != null ? right : SortedMap.EMPTY_NODE;\n }\n /**\r\n * Returns a copy of the current node, optionally replacing pieces of it.\r\n *\r\n * @param {?K} key New key for the node, or null.\r\n * @param {?V} value New value for the node, or null.\r\n * @param {?boolean} color New color for the node, or null.\r\n * @param {?LLRBNode|LLRBEmptyNode} left New left child for the node, or null.\r\n * @param {?LLRBNode|LLRBEmptyNode} right New right child for the node, or null.\r\n * @return {!LLRBNode} The node copy.\r\n */\n LLRBNode.prototype.copy = function (key, value, color, left, right) {\n return new LLRBNode(key != null ? key : this.key, value != null ? value : this.value, color != null ? color : this.color, left != null ? left : this.left, right != null ? right : this.right);\n };\n /**\r\n * @return {number} The total number of nodes in the tree.\r\n */\n LLRBNode.prototype.count = function () {\n return this.left.count() + 1 + this.right.count();\n };\n /**\r\n * @return {boolean} True if the tree is empty.\r\n */\n LLRBNode.prototype.isEmpty = function () {\n return false;\n };\n /**\r\n * Traverses the tree in key order and calls the specified action function\r\n * for each node.\r\n *\r\n * @param {function(!K, !V):*} action Callback function to be called for each\r\n * node. If it returns true, traversal is aborted.\r\n * @return {*} The first truthy value returned by action, or the last falsey\r\n * value returned by action\r\n */\n LLRBNode.prototype.inorderTraversal = function (action) {\n return this.left.inorderTraversal(action) || action(this.key, this.value) || this.right.inorderTraversal(action);\n };\n /**\r\n * Traverses the tree in reverse key order and calls the specified action function\r\n * for each node.\r\n *\r\n * @param {function(!Object, !Object)} action Callback function to be called for each\r\n * node. If it returns true, traversal is aborted.\r\n * @return {*} True if traversal was aborted.\r\n */\n LLRBNode.prototype.reverseTraversal = function (action) {\n return this.right.reverseTraversal(action) || action(this.key, this.value) || this.left.reverseTraversal(action);\n };\n /**\r\n * @return {!Object} The minimum node in the tree.\r\n * @private\r\n */\n LLRBNode.prototype.min_ = function () {\n if (this.left.isEmpty()) {\n return this;\n } else {\n return this.left.min_();\n }\n };\n /**\r\n * @return {!K} The maximum key in the tree.\r\n */\n LLRBNode.prototype.minKey = function () {\n return this.min_().key;\n };\n /**\r\n * @return {!K} The maximum key in the tree.\r\n */\n LLRBNode.prototype.maxKey = function () {\n if (this.right.isEmpty()) {\n return this.key;\n } else {\n return this.right.maxKey();\n }\n };\n /**\r\n *\r\n * @param {!Object} key Key to insert.\r\n * @param {!Object} value Value to insert.\r\n * @param {Comparator} comparator Comparator.\r\n * @return {!LLRBNode} New tree, with the key/value added.\r\n */\n LLRBNode.prototype.insert = function (key, value, comparator) {\n var 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 /**\r\n * @private\r\n * @return {!LLRBNode|LLRBEmptyNode} New tree, with the minimum key removed.\r\n */\n LLRBNode.prototype.removeMin_ = function () {\n if (this.left.isEmpty()) {\n return SortedMap.EMPTY_NODE;\n }\n var n = this;\n if (!n.left.isRed_() && !n.left.left.isRed_()) n = n.moveRedLeft_();\n n = n.copy(null, null, null, n.left.removeMin_(), null);\n return n.fixUp_();\n };\n /**\r\n * @param {!Object} key The key of the item to remove.\r\n * @param {Comparator} comparator Comparator.\r\n * @return {!LLRBNode|LLRBEmptyNode} New tree, with the specified item removed.\r\n */\n LLRBNode.prototype.remove = function (key, comparator) {\n var 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;\n } else {\n smallest = n.right.min_();\n n = n.copy(smallest.key, smallest.value, null, null, n.right.removeMin_());\n }\n }\n n = n.copy(null, null, null, null, n.right.remove(key, comparator));\n }\n return n.fixUp_();\n };\n /**\r\n * @private\r\n * @return {boolean} Whether this is a RED node.\r\n */\n LLRBNode.prototype.isRed_ = function () {\n return this.color;\n };\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree after performing any needed rotations.\r\n */\n LLRBNode.prototype.fixUp_ = function () {\n var n = this;\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 /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after moveRedLeft.\r\n */\n LLRBNode.prototype.moveRedLeft_ = function () {\n var n = this.colorFlip_();\n if (n.right.left.isRed_()) {\n n = n.copy(null, null, null, null, n.right.rotateRight_());\n n = n.rotateLeft_();\n n = n.colorFlip_();\n }\n return n;\n };\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after moveRedRight.\r\n */\n LLRBNode.prototype.moveRedRight_ = function () {\n var n = this.colorFlip_();\n if (n.left.left.isRed_()) {\n n = n.rotateRight_();\n n = n.colorFlip_();\n }\n return n;\n };\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after rotateLeft.\r\n */\n LLRBNode.prototype.rotateLeft_ = function () {\n var nl = this.copy(null, null, LLRBNode.RED, null, this.right.left);\n return this.right.copy(null, null, this.color, nl, null);\n };\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after rotateRight.\r\n */\n LLRBNode.prototype.rotateRight_ = function () {\n var nr = this.copy(null, null, LLRBNode.RED, this.left.right, null);\n return this.left.copy(null, null, this.color, null, nr);\n };\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after colorFlip.\r\n */\n LLRBNode.prototype.colorFlip_ = function () {\n var left = this.left.copy(null, null, !this.left.color, null, null);\n var right = this.right.copy(null, null, !this.right.color, null, null);\n return this.copy(null, null, !this.color, left, right);\n };\n /**\r\n * For testing.\r\n *\r\n * @private\r\n * @return {boolean} True if all is well.\r\n */\n LLRBNode.prototype.checkMaxDepth_ = function () {\n var blackDepth = this.check_();\n return Math.pow(2.0, blackDepth) <= this.count() + 1;\n };\n /**\r\n * @private\r\n * @return {number} Not sure what this returns exactly. :-).\r\n */\n LLRBNode.prototype.check_ = function () {\n var blackDepth;\n if (this.isRed_() && this.left.isRed_()) {\n throw new Error('Red node has red child(' + this.key + ',' + this.value + ')');\n }\n if (this.right.isRed_()) {\n throw new Error('Right child of (' + this.key + ',' + 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 LLRBNode.RED = true;\n LLRBNode.BLACK = false;\n return LLRBNode;\n}();\n\n/**\r\n * Represents an empty node (a leaf node in the Red-Black Tree).\r\n */\nvar LLRBEmptyNode = /** @class */function () {\n function LLRBEmptyNode() {}\n /**\r\n * Returns a copy of the current node.\r\n *\r\n * @return {!LLRBEmptyNode} The node copy.\r\n */\n LLRBEmptyNode.prototype.copy = function (key, value, color, left, right) {\n return this;\n };\n /**\r\n * Returns a copy of the tree, with the specified key/value added.\r\n *\r\n * @param {!K} key Key to be added.\r\n * @param {!V} value Value to be added.\r\n * @param {Comparator} comparator Comparator.\r\n * @return {!LLRBNode} New tree, with item added.\r\n */\n LLRBEmptyNode.prototype.insert = function (key, value, comparator) {\n return new LLRBNode(key, value, null);\n };\n /**\r\n * Returns a copy of the tree, with the specified key removed.\r\n *\r\n * @param {!K} key The key to remove.\r\n * @param {Comparator} comparator Comparator.\r\n * @return {!LLRBEmptyNode} New tree, with item removed.\r\n */\n LLRBEmptyNode.prototype.remove = function (key, comparator) {\n return this;\n };\n /**\r\n * @return {number} The total number of nodes in the tree.\r\n */\n LLRBEmptyNode.prototype.count = function () {\n return 0;\n };\n /**\r\n * @return {boolean} True if the tree is empty.\r\n */\n LLRBEmptyNode.prototype.isEmpty = function () {\n return true;\n };\n /**\r\n * Traverses the tree in key order and calls the specified action function\r\n * for each node.\r\n *\r\n * @param {function(!K, !V):*} action Callback function to be called for each\r\n * node. If it returns true, traversal is aborted.\r\n * @return {boolean} True if traversal was aborted.\r\n */\n LLRBEmptyNode.prototype.inorderTraversal = function (action) {\n return false;\n };\n /**\r\n * Traverses the tree in reverse key order and calls the specified action function\r\n * for each node.\r\n *\r\n * @param {function(!K, !V)} action Callback function to be called for each\r\n * node. If it returns true, traversal is aborted.\r\n * @return {boolean} True if traversal was aborted.\r\n */\n LLRBEmptyNode.prototype.reverseTraversal = function (action) {\n return false;\n };\n /**\r\n * @return {null}\r\n */\n LLRBEmptyNode.prototype.minKey = function () {\n return null;\n };\n /**\r\n * @return {null}\r\n */\n LLRBEmptyNode.prototype.maxKey = function () {\n return null;\n };\n /**\r\n * @private\r\n * @return {number} Not sure what this returns exactly. :-).\r\n */\n LLRBEmptyNode.prototype.check_ = function () {\n return 0;\n };\n /**\r\n * @private\r\n * @return {boolean} Whether this node is red.\r\n */\n LLRBEmptyNode.prototype.isRed_ = function () {\n return false;\n };\n return LLRBEmptyNode;\n}();\n\n/**\r\n * An immutable sorted map implementation, based on a Left-leaning Red-Black\r\n * tree.\r\n */\nvar SortedMap = /** @class */function () {\n /**\r\n * @template K, V\r\n * @param {function(K, K):number} comparator_ Key comparator.\r\n * @param {LLRBNode=} root_ (Optional) Root node for the map.\r\n */\n function SortedMap(comparator_, root_) {\n if (root_ === void 0) {\n root_ = SortedMap.EMPTY_NODE;\n }\n this.comparator_ = comparator_;\n this.root_ = root_;\n }\n /**\r\n * Returns a copy of the map, with the specified key/value added or replaced.\r\n * (TODO: We should perhaps rename this method to 'put')\r\n *\r\n * @param {!K} key Key to be added.\r\n * @param {!V} value Value to be added.\r\n * @return {!SortedMap.} New map, with item added.\r\n */\n SortedMap.prototype.insert = function (key, value) {\n return new SortedMap(this.comparator_, this.root_.insert(key, value, this.comparator_).copy(null, null, LLRBNode.BLACK, null, null));\n };\n /**\r\n * Returns a copy of the map, with the specified key removed.\r\n *\r\n * @param {!K} key The key to remove.\r\n * @return {!SortedMap.} New map, with item removed.\r\n */\n SortedMap.prototype.remove = function (key) {\n return new SortedMap(this.comparator_, this.root_.remove(key, this.comparator_).copy(null, null, LLRBNode.BLACK, null, null));\n };\n /**\r\n * Returns the value of the node with the given key, or null.\r\n *\r\n * @param {!K} key The key to look up.\r\n * @return {?V} The value of the node with the given key, or null if the\r\n * key doesn't exist.\r\n */\n SortedMap.prototype.get = function (key) {\n var cmp;\n var 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 /**\r\n * Returns the key of the item *before* the specified key, or null if key is the first item.\r\n * @param {K} key The key to find the predecessor of\r\n * @return {?K} The predecessor key.\r\n */\n SortedMap.prototype.getPredecessorKey = function (key) {\n var cmp,\n node = this.root_,\n 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 throw new Error('Attempted to find predecessor key for a nonexistent key. What gives?');\n };\n /**\r\n * @return {boolean} True if the map is empty.\r\n */\n SortedMap.prototype.isEmpty = function () {\n return this.root_.isEmpty();\n };\n /**\r\n * @return {number} The total number of nodes in the map.\r\n */\n SortedMap.prototype.count = function () {\n return this.root_.count();\n };\n /**\r\n * @return {?K} The minimum key in the map.\r\n */\n SortedMap.prototype.minKey = function () {\n return this.root_.minKey();\n };\n /**\r\n * @return {?K} The maximum key in the map.\r\n */\n SortedMap.prototype.maxKey = function () {\n return this.root_.maxKey();\n };\n /**\r\n * Traverses the map in key order and calls the specified action function\r\n * for each key/value pair.\r\n *\r\n * @param {function(!K, !V):*} action Callback function to be called\r\n * for each key/value pair. If action returns true, traversal is aborted.\r\n * @return {*} The first truthy value returned by action, or the last falsey\r\n * value returned by action\r\n */\n SortedMap.prototype.inorderTraversal = function (action) {\n return this.root_.inorderTraversal(action);\n };\n /**\r\n * Traverses the map in reverse key order and calls the specified action function\r\n * for each key/value pair.\r\n *\r\n * @param {function(!Object, !Object)} action Callback function to be called\r\n * for each key/value pair. If action returns true, traversal is aborted.\r\n * @return {*} True if the traversal was aborted.\r\n */\n SortedMap.prototype.reverseTraversal = function (action) {\n return this.root_.reverseTraversal(action);\n };\n /**\r\n * Returns an iterator over the SortedMap.\r\n * @template T\r\n * @param {(function(K, V):T)=} resultGenerator\r\n * @return {SortedMapIterator.} The iterator.\r\n */\n SortedMap.prototype.getIterator = function (resultGenerator) {\n return new SortedMapIterator(this.root_, null, this.comparator_, false, resultGenerator);\n };\n SortedMap.prototype.getIteratorFrom = function (key, resultGenerator) {\n return new SortedMapIterator(this.root_, key, this.comparator_, false, resultGenerator);\n };\n SortedMap.prototype.getReverseIteratorFrom = function (key, resultGenerator) {\n return new SortedMapIterator(this.root_, key, this.comparator_, true, resultGenerator);\n };\n SortedMap.prototype.getReverseIterator = function (resultGenerator) {\n return new SortedMapIterator(this.root_, null, this.comparator_, true, resultGenerator);\n };\n /**\r\n * Always use the same empty node, to reduce memory.\r\n * @const\r\n */\n SortedMap.EMPTY_NODE = new LLRBEmptyNode();\n return SortedMap;\n}();\n\n\n/***/ }),\n/* 23 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/database/core/util/ServerValues.ts\nvar ServerValues = __webpack_require__(47);\n\n// EXTERNAL MODULE: ./src/database/core/snap/nodeFromJSON.ts\nvar nodeFromJSON = __webpack_require__(16);\n\n// EXTERNAL MODULE: ./src/database/core/util/Path.ts\nvar Path = __webpack_require__(4);\n\n// EXTERNAL MODULE: ./src/database/core/SparseSnapshotTree.ts\nvar SparseSnapshotTree = __webpack_require__(48);\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/database/core/operation/Operation.ts\nvar Operation = __webpack_require__(12);\n\n// CONCATENATED MODULE: ./src/database/core/operation/AckUserWrite.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\nvar AckUserWrite_AckUserWrite = /** @class */function () {\n /**\r\n *\r\n * @param {!Path} path\r\n * @param {!ImmutableTree} affectedTree A tree containing true for each affected path. Affected paths can't overlap.\r\n * @param {!boolean} revert\r\n */\n function AckUserWrite(\n /**@inheritDoc */path,\n /**@inheritDoc */affectedTree,\n /**@inheritDoc */revert) {\n this.path = path;\n this.affectedTree = affectedTree;\n this.revert = revert;\n /** @inheritDoc */\n this.type = Operation[\"b\" /* OperationType */].ACK_USER_WRITE;\n /** @inheritDoc */\n this.source = Operation[\"a\" /* OperationSource */].User;\n }\n /**\r\n * @inheritDoc\r\n */\n AckUserWrite.prototype.operationForChild = function (childName) {\n if (!this.path.isEmpty()) {\n Object(assert[\"a\" /* 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 Object(assert[\"a\" /* assert */])(this.affectedTree.children.isEmpty(), '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 var childTree = this.affectedTree.subtree(new Path[\"a\" /* Path */](childName));\n return new AckUserWrite(Path[\"a\" /* Path */].Empty, childTree, this.revert);\n }\n };\n return AckUserWrite;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/snap/ChildrenNode.ts\nvar ChildrenNode = __webpack_require__(6);\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar obj = __webpack_require__(2);\n\n// EXTERNAL MODULE: ./src/database/core/util/ImmutableTree.ts\nvar ImmutableTree = __webpack_require__(27);\n\n// CONCATENATED MODULE: ./src/database/core/operation/ListenComplete.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 * @param {!OperationSource} source\r\n * @param {!Path} path\r\n * @constructor\r\n * @implements {Operation}\r\n */\nvar ListenComplete_ListenComplete = /** @class */function () {\n function ListenComplete(source, path) {\n this.source = source;\n this.path = path;\n /** @inheritDoc */\n this.type = Operation[\"b\" /* OperationType */].LISTEN_COMPLETE;\n }\n ListenComplete.prototype.operationForChild = function (childName) {\n if (this.path.isEmpty()) {\n return new ListenComplete(this.source, Path[\"a\" /* Path */].Empty);\n } else {\n return new ListenComplete(this.source, this.path.popFront());\n }\n };\n return ListenComplete;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/operation/Overwrite.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 * @param {!OperationSource} source\r\n * @param {!Path} path\r\n * @param {!Node} snap\r\n * @constructor\r\n * @implements {Operation}\r\n */\nvar Overwrite_Overwrite = /** @class */function () {\n function Overwrite(source, path, snap) {\n this.source = source;\n this.path = path;\n this.snap = snap;\n /** @inheritDoc */\n this.type = Operation[\"b\" /* OperationType */].OVERWRITE;\n }\n Overwrite.prototype.operationForChild = function (childName) {\n if (this.path.isEmpty()) {\n return new Overwrite(this.source, Path[\"a\" /* Path */].Empty, this.snap.getImmediateChild(childName));\n } else {\n return new Overwrite(this.source, this.path.popFront(), this.snap);\n }\n };\n return Overwrite;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/operation/Merge.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 * @param {!OperationSource} source\r\n * @param {!Path} path\r\n * @param {!ImmutableTree.} children\r\n * @constructor\r\n * @implements {Operation}\r\n */\nvar Merge_Merge = /** @class */function () {\n function Merge(\n /**@inheritDoc */source,\n /**@inheritDoc */path,\n /**@inheritDoc */children) {\n this.source = source;\n this.path = path;\n this.children = children;\n /** @inheritDoc */\n this.type = Operation[\"b\" /* OperationType */].MERGE;\n }\n /**\r\n * @inheritDoc\r\n */\n Merge.prototype.operationForChild = function (childName) {\n if (this.path.isEmpty()) {\n var childTree = this.children.subtree(new Path[\"a\" /* 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_Overwrite(this.source, Path[\"a\" /* Path */].Empty, childTree.value);\n } else {\n // This is a merge at a deeper level\n return new Merge(this.source, Path[\"a\" /* Path */].Empty, childTree);\n }\n } else {\n Object(assert[\"a\" /* assert */])(this.path.getFront() === childName, \"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 /**\r\n * @inheritDoc\r\n */\n Merge.prototype.toString = function () {\n return 'Operation(' + this.path + ': ' + this.source.toString() + ' merge: ' + this.children.toString() + ')';\n };\n return Merge;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/SyncPoint.ts + 7 modules\nvar SyncPoint = __webpack_require__(50);\n\n// EXTERNAL MODULE: ./src/database/core/snap/Node.ts\nvar Node = __webpack_require__(7);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/PriorityIndex.ts\nvar PriorityIndex = __webpack_require__(5);\n\n// CONCATENATED MODULE: ./src/database/core/CompoundWrite.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 * This class holds a collection of writes that can be applied to nodes in unison. It abstracts away the logic with\r\n * dealing with priority writes and multiple nested writes. At any given path there is only allowed to be one write\r\n * modifying that path. Any write to an existing path or shadowing an existing path will modify that existing write\r\n * to reflect the write added.\r\n *\r\n * @constructor\r\n * @param {!ImmutableTree.} writeTree\r\n */\nvar CompoundWrite_CompoundWrite = /** @class */function () {\n function CompoundWrite(writeTree_) {\n this.writeTree_ = writeTree_;\n }\n /**\r\n * @param {!Path} path\r\n * @param {!Node} node\r\n * @return {!CompoundWrite}\r\n */\n CompoundWrite.prototype.addWrite = function (path, node) {\n if (path.isEmpty()) {\n return new CompoundWrite(new ImmutableTree[\"a\" /* ImmutableTree */](node));\n } else {\n var rootmost = this.writeTree_.findRootMostValueAndPath(path);\n if (rootmost != null) {\n var rootMostPath = rootmost.path;\n var value = rootmost.value;\n var relativePath = Path[\"a\" /* Path */].relativePath(rootMostPath, path);\n value = value.updateChild(relativePath, node);\n return new CompoundWrite(this.writeTree_.set(rootMostPath, value));\n } else {\n var subtree = new ImmutableTree[\"a\" /* ImmutableTree */](node);\n var newWriteTree = this.writeTree_.setTree(path, subtree);\n return new CompoundWrite(newWriteTree);\n }\n }\n };\n /**\r\n * @param {!Path} path\r\n * @param {!Object.} updates\r\n * @return {!CompoundWrite}\r\n */\n CompoundWrite.prototype.addWrites = function (path, updates) {\n var newWrite = this;\n Object(obj[\"f\" /* forEach */])(updates, function (childKey, node) {\n newWrite = newWrite.addWrite(path.child(childKey), node);\n });\n return newWrite;\n };\n /**\r\n * Will remove a write at the given path and deeper paths. This will not modify a write at a higher\r\n * location, which must be removed by calling this method with that path.\r\n *\r\n * @param {!Path} path The path at which a write and all deeper writes should be removed\r\n * @return {!CompoundWrite} The new CompoundWrite with the removed path\r\n */\n CompoundWrite.prototype.removeWrite = function (path) {\n if (path.isEmpty()) {\n return CompoundWrite.Empty;\n } else {\n var newWriteTree = this.writeTree_.setTree(path, ImmutableTree[\"a\" /* ImmutableTree */].Empty);\n return new CompoundWrite(newWriteTree);\n }\n };\n /**\r\n * Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be\r\n * considered \"complete\".\r\n *\r\n * @param {!Path} path The path to check for\r\n * @return {boolean} Whether there is a complete write at that path\r\n */\n CompoundWrite.prototype.hasCompleteWrite = function (path) {\n return this.getCompleteNode(path) != null;\n };\n /**\r\n * Returns a node for a path if and only if the node is a \"complete\" overwrite at that path. This will not aggregate\r\n * writes from deeper paths, but will return child nodes from a more shallow path.\r\n *\r\n * @param {!Path} path The path to get a complete write\r\n * @return {?Node} The node if complete at that path, or null otherwise.\r\n */\n CompoundWrite.prototype.getCompleteNode = function (path) {\n var rootmost = this.writeTree_.findRootMostValueAndPath(path);\n if (rootmost != null) {\n return this.writeTree_.get(rootmost.path).getChild(Path[\"a\" /* Path */].relativePath(rootmost.path, path));\n } else {\n return null;\n }\n };\n /**\r\n * Returns all children that are guaranteed to be a complete overwrite.\r\n *\r\n * @return {!Array.} A list of all complete children.\r\n */\n CompoundWrite.prototype.getCompleteChildren = function () {\n var children = [];\n var 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.forEachChild(PriorityIndex[\"a\" /* PRIORITY_INDEX */], function (childName, childNode) {\n children.push(new Node[\"a\" /* NamedNode */](childName, childNode));\n });\n }\n } else {\n this.writeTree_.children.inorderTraversal(function (childName, childTree) {\n if (childTree.value != null) {\n children.push(new Node[\"a\" /* NamedNode */](childName, childTree.value));\n }\n });\n }\n return children;\n };\n /**\r\n * @param {!Path} path\r\n * @return {!CompoundWrite}\r\n */\n CompoundWrite.prototype.childCompoundWrite = function (path) {\n if (path.isEmpty()) {\n return this;\n } else {\n var shadowingNode = this.getCompleteNode(path);\n if (shadowingNode != null) {\n return new CompoundWrite(new ImmutableTree[\"a\" /* ImmutableTree */](shadowingNode));\n } else {\n return new CompoundWrite(this.writeTree_.subtree(path));\n }\n }\n };\n /**\r\n * Returns true if this CompoundWrite is empty and therefore does not modify any nodes.\r\n * @return {boolean} Whether this CompoundWrite is empty\r\n */\n CompoundWrite.prototype.isEmpty = function () {\n return this.writeTree_.isEmpty();\n };\n /**\r\n * Applies this CompoundWrite to a node. The node is returned with all writes from this CompoundWrite applied to the\r\n * node\r\n * @param {!Node} node The node to apply this CompoundWrite to\r\n * @return {!Node} The node with all writes applied\r\n */\n CompoundWrite.prototype.apply = function (node) {\n return CompoundWrite.applySubtreeWrite_(Path[\"a\" /* Path */].Empty, this.writeTree_, node);\n };\n /**\r\n * @type {!CompoundWrite}\r\n */\n CompoundWrite.Empty = new CompoundWrite(new ImmutableTree[\"a\" /* ImmutableTree */](null));\n /**\r\n * @param {!Path} relativePath\r\n * @param {!ImmutableTree.} writeTree\r\n * @param {!Node} node\r\n * @return {!Node}\r\n * @private\r\n */\n CompoundWrite.applySubtreeWrite_ = function (relativePath, writeTree, 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 var priorityWrite_1 = 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 Object(assert[\"a\" /* assert */])(childTree.value !== null, 'Priority writes must always be leaf nodes');\n priorityWrite_1 = 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_1 !== null) {\n node = node.updateChild(relativePath.child('.priority'), priorityWrite_1);\n }\n return node;\n }\n };\n return CompoundWrite;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/WriteTree.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 * WriteTree tracks all pending user-initiated writes and has methods to calculate the result of merging them\r\n * with underlying server data (to create \"event cache\" data). Pending writes are added with addOverwrite()\r\n * and addMerge(), and removed with removeWrite().\r\n *\r\n * @constructor\r\n */\nvar WriteTree_WriteTree = /** @class */function () {\n function WriteTree() {\n /**\r\n * A tree tracking the result of applying all visible writes. This does not include transactions with\r\n * applyLocally=false or writes that are completely shadowed by other writes.\r\n *\r\n * @type {!CompoundWrite}\r\n * @private\r\n */\n this.visibleWrites_ = CompoundWrite_CompoundWrite.Empty;\n /**\r\n * A list of all pending writes, regardless of visibility and shadowed-ness. Used to calculate arbitrary\r\n * sets of the changed data, such as hidden writes (from transactions) or changes with certain writes excluded (also\r\n * used by transactions).\r\n *\r\n * @type {!Array.}\r\n * @private\r\n */\n this.allWrites_ = [];\n this.lastWriteId_ = -1;\n }\n /**\r\n * Create a new WriteTreeRef for the given path. For use with a new sync point at the given path.\r\n *\r\n * @param {!Path} path\r\n * @return {!WriteTreeRef}\r\n */\n WriteTree.prototype.childWrites = function (path) {\n return new WriteTreeRef(path, this);\n };\n /**\r\n * Record a new overwrite from user code.\r\n *\r\n * @param {!Path} path\r\n * @param {!Node} snap\r\n * @param {!number} writeId\r\n * @param {boolean=} visible This is set to false by some transactions. It should be excluded from event caches\r\n */\n WriteTree.prototype.addOverwrite = function (path, snap, writeId, visible) {\n Object(assert[\"a\" /* 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({\n path: path,\n snap: snap,\n writeId: writeId,\n visible: visible\n });\n if (visible) {\n this.visibleWrites_ = this.visibleWrites_.addWrite(path, snap);\n }\n this.lastWriteId_ = writeId;\n };\n /**\r\n * Record a new merge from user code.\r\n *\r\n * @param {!Path} path\r\n * @param {!Object.} changedChildren\r\n * @param {!number} writeId\r\n */\n WriteTree.prototype.addMerge = function (path, changedChildren, writeId) {\n Object(assert[\"a\" /* assert */])(writeId > this.lastWriteId_, 'Stacking an older merge on top of newer ones');\n this.allWrites_.push({\n path: path,\n children: changedChildren,\n writeId: writeId,\n visible: true\n });\n this.visibleWrites_ = this.visibleWrites_.addWrites(path, changedChildren);\n this.lastWriteId_ = writeId;\n };\n /**\r\n * @param {!number} writeId\r\n * @return {?WriteRecord}\r\n */\n WriteTree.prototype.getWrite = function (writeId) {\n for (var i = 0; i < this.allWrites_.length; i++) {\n var record = this.allWrites_[i];\n if (record.writeId === writeId) {\n return record;\n }\n }\n return null;\n };\n /**\r\n * Remove a write (either an overwrite or merge) that has been successfully acknowledge by the server. Recalculates\r\n * the tree if necessary. We return true if it may have been visible, meaning views need to reevaluate.\r\n *\r\n * @param {!number} writeId\r\n * @return {boolean} true if the write may have been visible (meaning we'll need to reevaluate / raise\r\n * events as a result).\r\n */\n WriteTree.prototype.removeWrite = function (writeId) {\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 var _this = this;\n var idx = this.allWrites_.findIndex(function (s) {\n return s.writeId === writeId;\n });\n Object(assert[\"a\" /* assert */])(idx >= 0, 'removeWrite called with nonexistent writeId.');\n var writeToRemove = this.allWrites_[idx];\n this.allWrites_.splice(idx, 1);\n var removedWriteWasVisible = writeToRemove.visible;\n var removedWriteOverlapsWithOtherWrites = false;\n var i = this.allWrites_.length - 1;\n while (removedWriteWasVisible && i >= 0) {\n var 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 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 var children = writeToRemove.children;\n Object(obj[\"f\" /* forEach */])(children, function (childName) {\n _this.visibleWrites_ = _this.visibleWrites_.removeWrite(writeToRemove.path.child(childName));\n });\n }\n return true;\n }\n };\n /**\r\n * Return a complete snapshot for the given path if there's visible write data at that path, else null.\r\n * No server data is considered.\r\n *\r\n * @param {!Path} path\r\n * @return {?Node}\r\n */\n WriteTree.prototype.getCompleteWriteData = function (path) {\n return this.visibleWrites_.getCompleteNode(path);\n };\n /**\r\n * Given optional, underlying server data, and an optional set of constraints (exclude some sets, include hidden\r\n * writes), attempt to calculate a complete snapshot for the given path\r\n *\r\n * @param {!Path} treePath\r\n * @param {?Node} completeServerCache\r\n * @param {Array.=} writeIdsToExclude An optional set to be excluded\r\n * @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false\r\n * @return {?Node}\r\n */\n WriteTree.prototype.calcCompleteEventCache = function (treePath, completeServerCache, writeIdsToExclude, includeHiddenWrites) {\n if (!writeIdsToExclude && !includeHiddenWrites) {\n var shadowingNode = this.visibleWrites_.getCompleteNode(treePath);\n if (shadowingNode != null) {\n return shadowingNode;\n } else {\n var subMerge = this.visibleWrites_.childCompoundWrite(treePath);\n if (subMerge.isEmpty()) {\n return completeServerCache;\n } else if (completeServerCache == null && !subMerge.hasCompleteWrite(Path[\"a\" /* 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 var layeredCache = completeServerCache || ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n return subMerge.apply(layeredCache);\n }\n }\n } else {\n var 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[\"a\" /* Path */].Empty)) {\n return null;\n } else {\n var filter = function filter(write) {\n return (write.visible || includeHiddenWrites) && (!writeIdsToExclude || !~writeIdsToExclude.indexOf(write.writeId)) && (write.path.contains(treePath) || treePath.contains(write.path));\n };\n var mergeAtPath = WriteTree.layerTree_(this.allWrites_, filter, treePath);\n var layeredCache = completeServerCache || ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n return mergeAtPath.apply(layeredCache);\n }\n }\n }\n };\n /**\r\n * With optional, underlying server data, attempt to return a children node of children that we have complete data for.\r\n * Used when creating new views, to pre-fill their complete event children snapshot.\r\n *\r\n * @param {!Path} treePath\r\n * @param {?ChildrenNode} completeServerChildren\r\n * @return {!ChildrenNode}\r\n */\n WriteTree.prototype.calcCompleteEventChildren = function (treePath, completeServerChildren) {\n var completeChildren = ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n var topLevelSet = this.visibleWrites_.getCompleteNode(treePath);\n if (topLevelSet) {\n if (!topLevelSet.isLeafNode()) {\n // we're shadowing everything. Return the children.\n topLevelSet.forEachChild(PriorityIndex[\"a\" /* 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 var merge_1 = this.visibleWrites_.childCompoundWrite(treePath);\n completeServerChildren.forEachChild(PriorityIndex[\"a\" /* PRIORITY_INDEX */], function (childName, childNode) {\n var node = merge_1.childCompoundWrite(new Path[\"a\" /* Path */](childName)).apply(childNode);\n completeChildren = completeChildren.updateImmediateChild(childName, node);\n });\n // Add any complete children we have from the set\n merge_1.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 var 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 /**\r\n * Given that the underlying server data has updated, determine what, if anything, needs to be\r\n * applied to the event cache.\r\n *\r\n * Possibilities:\r\n *\r\n * 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data\r\n *\r\n * 2. Some write is completely shadowing. No events to be raised\r\n *\r\n * 3. Is partially shadowed. Events\r\n *\r\n * Either existingEventSnap or existingServerSnap must exist\r\n *\r\n * @param {!Path} treePath\r\n * @param {!Path} childPath\r\n * @param {?Node} existingEventSnap\r\n * @param {?Node} existingServerSnap\r\n * @return {?Node}\r\n */\n WriteTree.prototype.calcEventCacheAfterServerOverwrite = function (treePath, childPath, existingEventSnap, existingServerSnap) {\n Object(assert[\"a\" /* assert */])(existingEventSnap || existingServerSnap, 'Either existingEventSnap or existingServerSnap must exist');\n var 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 var 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 /**\r\n * Returns a complete child for a given server snap after applying all user writes or null if there is no\r\n * complete child for this ChildKey.\r\n *\r\n * @param {!Path} treePath\r\n * @param {!string} childKey\r\n * @param {!CacheNode} existingServerSnap\r\n * @return {?Node}\r\n */\n WriteTree.prototype.calcCompleteChild = function (treePath, childKey, existingServerSnap) {\n var path = treePath.child(childKey);\n var shadowingNode = this.visibleWrites_.getCompleteNode(path);\n if (shadowingNode != null) {\n return shadowingNode;\n } else {\n if (existingServerSnap.isCompleteForChild(childKey)) {\n var childMerge = this.visibleWrites_.childCompoundWrite(path);\n return childMerge.apply(existingServerSnap.getNode().getImmediateChild(childKey));\n } else {\n return null;\n }\n }\n };\n /**\r\n * Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at\r\n * a higher path, this will return the child of that write relative to the write and this path.\r\n * Returns null if there is no write at this path.\r\n *\r\n * @param {!Path} path\r\n * @return {?Node}\r\n */\n WriteTree.prototype.shadowingWrite = function (path) {\n return this.visibleWrites_.getCompleteNode(path);\n };\n /**\r\n * This method is used when processing child remove events on a query. If we can, we pull in children that were outside\r\n * the window, but may now be in the window.\r\n *\r\n * @param {!Path} treePath\r\n * @param {?Node} completeServerData\r\n * @param {!NamedNode} startPost\r\n * @param {!number} count\r\n * @param {boolean} reverse\r\n * @param {!Index} index\r\n * @return {!Array.}\r\n */\n WriteTree.prototype.calcIndexedSlice = function (treePath, completeServerData, startPost, count, reverse, index) {\n var toIterate;\n var merge = this.visibleWrites_.childCompoundWrite(treePath);\n var shadowingNode = merge.getCompleteNode(Path[\"a\" /* 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 var nodes = [];\n var cmp = index.getCompare();\n var iter = reverse ? toIterate.getReverseIteratorFrom(startPost, index) : toIterate.getIteratorFrom(startPost, index);\n var 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 /**\r\n * @param {!WriteRecord} writeRecord\r\n * @param {!Path} path\r\n * @return {boolean}\r\n * @private\r\n */\n WriteTree.prototype.recordContainsPath_ = function (writeRecord, path) {\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 !!Object(obj[\"d\" /* findKey */])(writeRecord.children, function (childSnap, childName) {\n return writeRecord.path.child(childName).contains(path);\n });\n }\n };\n /**\r\n * Re-layer the writes and merges into a tree so we can efficiently calculate event snapshots\r\n * @private\r\n */\n WriteTree.prototype.resetTree_ = function () {\n this.visibleWrites_ = WriteTree.layerTree_(this.allWrites_, WriteTree.DefaultFilter_, Path[\"a\" /* 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 /**\r\n * The default filter used when constructing the tree. Keep everything that's visible.\r\n *\r\n * @param {!WriteRecord} write\r\n * @return {boolean}\r\n * @private\r\n */\n WriteTree.DefaultFilter_ = function (write) {\n return write.visible;\n };\n /**\r\n * Static method. Given an array of WriteRecords, a filter for which ones to include, and a path, construct the tree of\r\n * event data at that path.\r\n *\r\n * @param {!Array.} writes\r\n * @param {!function(!WriteRecord):boolean} filter\r\n * @param {!Path} treeRoot\r\n * @return {!CompoundWrite}\r\n * @private\r\n */\n WriteTree.layerTree_ = function (writes, filter, treeRoot) {\n var compoundWrite = CompoundWrite_CompoundWrite.Empty;\n for (var i = 0; i < writes.length; ++i) {\n var 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 var writePath = write.path;\n var relativePath = void 0;\n if (write.snap) {\n if (treeRoot.contains(writePath)) {\n relativePath = Path[\"a\" /* Path */].relativePath(treeRoot, writePath);\n compoundWrite = compoundWrite.addWrite(relativePath, write.snap);\n } else if (writePath.contains(treeRoot)) {\n relativePath = Path[\"a\" /* Path */].relativePath(writePath, treeRoot);\n compoundWrite = compoundWrite.addWrite(Path[\"a\" /* 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[\"a\" /* Path */].relativePath(treeRoot, writePath);\n compoundWrite = compoundWrite.addWrites(relativePath, write.children);\n } else if (writePath.contains(treeRoot)) {\n relativePath = Path[\"a\" /* Path */].relativePath(writePath, treeRoot);\n if (relativePath.isEmpty()) {\n compoundWrite = compoundWrite.addWrites(Path[\"a\" /* Path */].Empty, write.children);\n } else {\n var child = Object(obj[\"l\" /* safeGet */])(write.children, relativePath.getFront());\n if (child) {\n // There exists a child in this node that matches the root path\n var deepNode = child.getChild(relativePath.popFront());\n compoundWrite = compoundWrite.addWrite(Path[\"a\" /* 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 Object(assert[\"b\" /* assertionError */])('WriteRecord should have .snap or .children');\n }\n }\n }\n return compoundWrite;\n };\n return WriteTree;\n}();\n\n/**\r\n * A WriteTreeRef wraps a WriteTree and a path, for convenient access to a particular subtree. All of the methods\r\n * just proxy to the underlying WriteTree.\r\n *\r\n * @constructor\r\n */\nvar WriteTreeRef = /** @class */function () {\n /**\r\n * @param {!Path} path\r\n * @param {!WriteTree} writeTree\r\n */\n function WriteTreeRef(path, writeTree) {\n this.treePath_ = path;\n this.writeTree_ = writeTree;\n }\n /**\r\n * If possible, returns a complete event cache, using the underlying server data if possible. In addition, can be used\r\n * to get a cache that includes hidden writes, and excludes arbitrary writes. Note that customizing the returned node\r\n * can lead to a more expensive calculation.\r\n *\r\n * @param {?Node} completeServerCache\r\n * @param {Array.=} writeIdsToExclude Optional writes to exclude.\r\n * @param {boolean=} includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false\r\n * @return {?Node}\r\n */\n WriteTreeRef.prototype.calcCompleteEventCache = function (completeServerCache, writeIdsToExclude, includeHiddenWrites) {\n return this.writeTree_.calcCompleteEventCache(this.treePath_, completeServerCache, writeIdsToExclude, includeHiddenWrites);\n };\n /**\r\n * If possible, returns a children node containing all of the complete children we have data for. The returned data is a\r\n * mix of the given server data and write data.\r\n *\r\n * @param {?ChildrenNode} completeServerChildren\r\n * @return {!ChildrenNode}\r\n */\n WriteTreeRef.prototype.calcCompleteEventChildren = function (completeServerChildren) {\n return this.writeTree_.calcCompleteEventChildren(this.treePath_, completeServerChildren);\n };\n /**\r\n * Given that either the underlying server data has updated or the outstanding writes have updated, determine what,\r\n * if anything, needs to be applied to the event cache.\r\n *\r\n * Possibilities:\r\n *\r\n * 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data\r\n *\r\n * 2. Some write is completely shadowing. No events to be raised\r\n *\r\n * 3. Is partially shadowed. Events should be raised\r\n *\r\n * Either existingEventSnap or existingServerSnap must exist, this is validated via an assert\r\n *\r\n * @param {!Path} path\r\n * @param {?Node} existingEventSnap\r\n * @param {?Node} existingServerSnap\r\n * @return {?Node}\r\n */\n WriteTreeRef.prototype.calcEventCacheAfterServerOverwrite = function (path, existingEventSnap, existingServerSnap) {\n return this.writeTree_.calcEventCacheAfterServerOverwrite(this.treePath_, path, existingEventSnap, existingServerSnap);\n };\n /**\r\n * Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at\r\n * a higher path, this will return the child of that write relative to the write and this path.\r\n * Returns null if there is no write at this path.\r\n *\r\n * @param {!Path} path\r\n * @return {?Node}\r\n */\n WriteTreeRef.prototype.shadowingWrite = function (path) {\n return this.writeTree_.shadowingWrite(this.treePath_.child(path));\n };\n /**\r\n * This method is used when processing child remove events on a query. If we can, we pull in children that were outside\r\n * the window, but may now be in the window\r\n *\r\n * @param {?Node} completeServerData\r\n * @param {!NamedNode} startPost\r\n * @param {!number} count\r\n * @param {boolean} reverse\r\n * @param {!Index} index\r\n * @return {!Array.}\r\n */\n WriteTreeRef.prototype.calcIndexedSlice = function (completeServerData, startPost, count, reverse, index) {\n return this.writeTree_.calcIndexedSlice(this.treePath_, completeServerData, startPost, count, reverse, index);\n };\n /**\r\n * Returns a complete child for a given server snap after applying all user writes or null if there is no\r\n * complete child for this ChildKey.\r\n *\r\n * @param {!string} childKey\r\n * @param {!CacheNode} existingServerCache\r\n * @return {?Node}\r\n */\n WriteTreeRef.prototype.calcCompleteChild = function (childKey, existingServerCache) {\n return this.writeTree_.calcCompleteChild(this.treePath_, childKey, existingServerCache);\n };\n /**\r\n * Return a WriteTreeRef for a child.\r\n *\r\n * @param {string} childName\r\n * @return {!WriteTreeRef}\r\n */\n WriteTreeRef.prototype.child = function (childName) {\n return new WriteTreeRef(this.treePath_.child(childName), this.writeTree_);\n };\n return WriteTreeRef;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/SyncTree.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\n\n\n\n\n/**\r\n * SyncTree is the central class for managing event callback registration, data caching, views\r\n * (query processing), and event generation. There are typically two SyncTree instances for\r\n * each Repo, one for the normal Firebase data, and one for the .info data.\r\n *\r\n * It has a number of responsibilities, including:\r\n * - Tracking all user event callbacks (registered via addEventRegistration() and removeEventRegistration()).\r\n * - Applying and caching data changes for user set(), transaction(), and update() calls\r\n * (applyUserOverwrite(), applyUserMerge()).\r\n * - Applying and caching data changes for server data changes (applyServerOverwrite(),\r\n * applyServerMerge()).\r\n * - Generating user-facing events for server and user changes (all of the apply* methods\r\n * return the set of events that need to be raised as a result).\r\n * - Maintaining the appropriate set of server listens to ensure we are always subscribed\r\n * to the correct set of paths and queries to satisfy the current set of user event\r\n * callbacks (listens are started/stopped using the provided listenProvider).\r\n *\r\n * NOTE: Although SyncTree tracks event callbacks and calculates events to raise, the actual\r\n * events are returned to the caller rather than raised synchronously.\r\n *\r\n * @constructor\r\n */\nvar SyncTree_SyncTree = /** @class */function () {\n /**\r\n * @param {!ListenProvider} listenProvider_ Used by SyncTree to start / stop listening\r\n * to server data.\r\n */\n function SyncTree(listenProvider_) {\n this.listenProvider_ = listenProvider_;\n /**\r\n * Tree of SyncPoints. There's a SyncPoint at any location that has 1 or more views.\r\n * @type {!ImmutableTree.}\r\n * @private\r\n */\n this.syncPointTree_ = ImmutableTree[\"a\" /* ImmutableTree */].Empty;\n /**\r\n * A tree of all pending user writes (user-initiated set()'s, transaction()'s, update()'s, etc.).\r\n * @type {!WriteTree}\r\n * @private\r\n */\n this.pendingWriteTree_ = new WriteTree_WriteTree();\n this.tagToQueryMap_ = {};\n this.queryToTagMap_ = {};\n }\n /**\r\n * Apply the data changes for a user-generated set() or transaction() call.\r\n *\r\n * @param {!Path} path\r\n * @param {!Node} newData\r\n * @param {number} writeId\r\n * @param {boolean=} visible\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyUserOverwrite = function (path, newData, writeId, visible) {\n // Record pending write.\n this.pendingWriteTree_.addOverwrite(path, newData, writeId, visible);\n if (!visible) {\n return [];\n } else {\n return this.applyOperationToSyncPoints_(new Overwrite_Overwrite(Operation[\"a\" /* OperationSource */].User, path, newData));\n }\n };\n /**\r\n * Apply the data from a user-generated update() call\r\n *\r\n * @param {!Path} path\r\n * @param {!Object.} changedChildren\r\n * @param {!number} writeId\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyUserMerge = function (path, changedChildren, writeId) {\n // Record pending merge.\n this.pendingWriteTree_.addMerge(path, changedChildren, writeId);\n var changeTree = ImmutableTree[\"a\" /* ImmutableTree */].fromObject(changedChildren);\n return this.applyOperationToSyncPoints_(new Merge_Merge(Operation[\"a\" /* OperationSource */].User, path, changeTree));\n };\n /**\r\n * Acknowledge a pending user write that was previously registered with applyUserOverwrite() or applyUserMerge().\r\n *\r\n * @param {!number} writeId\r\n * @param {boolean=} revert True if the given write failed and needs to be reverted\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.ackUserWrite = function (writeId, revert) {\n if (revert === void 0) {\n revert = false;\n }\n var write = this.pendingWriteTree_.getWrite(writeId);\n var needToReevaluate = this.pendingWriteTree_.removeWrite(writeId);\n if (!needToReevaluate) {\n return [];\n } else {\n var affectedTree_1 = ImmutableTree[\"a\" /* ImmutableTree */].Empty;\n if (write.snap != null) {\n // overwrite\n affectedTree_1 = affectedTree_1.set(Path[\"a\" /* Path */].Empty, true);\n } else {\n Object(obj[\"f\" /* forEach */])(write.children, function (pathString, node) {\n affectedTree_1 = affectedTree_1.set(new Path[\"a\" /* Path */](pathString), node);\n });\n }\n return this.applyOperationToSyncPoints_(new AckUserWrite_AckUserWrite(write.path, affectedTree_1, revert));\n }\n };\n /**\r\n * Apply new server data for the specified path..\r\n *\r\n * @param {!Path} path\r\n * @param {!Node} newData\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyServerOverwrite = function (path, newData) {\n return this.applyOperationToSyncPoints_(new Overwrite_Overwrite(Operation[\"a\" /* OperationSource */].Server, path, newData));\n };\n /**\r\n * Apply new server data to be merged in at the specified path.\r\n *\r\n * @param {!Path} path\r\n * @param {!Object.} changedChildren\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyServerMerge = function (path, changedChildren) {\n var changeTree = ImmutableTree[\"a\" /* ImmutableTree */].fromObject(changedChildren);\n return this.applyOperationToSyncPoints_(new Merge_Merge(Operation[\"a\" /* OperationSource */].Server, path, changeTree));\n };\n /**\r\n * Apply a listen complete for a query\r\n *\r\n * @param {!Path} path\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyListenComplete = function (path) {\n return this.applyOperationToSyncPoints_(new ListenComplete_ListenComplete(Operation[\"a\" /* OperationSource */].Server, path));\n };\n /**\r\n * Apply new server data for the specified tagged query.\r\n *\r\n * @param {!Path} path\r\n * @param {!Node} snap\r\n * @param {!number} tag\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyTaggedQueryOverwrite = function (path, snap, tag) {\n var queryKey = this.queryKeyForTag_(tag);\n if (queryKey != null) {\n var r = SyncTree.parseQueryKey_(queryKey);\n var queryPath = r.path,\n queryId = r.queryId;\n var relativePath = Path[\"a\" /* Path */].relativePath(queryPath, path);\n var op = new Overwrite_Overwrite(Operation[\"a\" /* OperationSource */].forServerTaggedQuery(queryId), relativePath, snap);\n return this.applyTaggedOperation_(queryPath, op);\n } else {\n // Query must have been removed already\n return [];\n }\n };\n /**\r\n * Apply server data to be merged in for the specified tagged query.\r\n *\r\n * @param {!Path} path\r\n * @param {!Object.} changedChildren\r\n * @param {!number} tag\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyTaggedQueryMerge = function (path, changedChildren, tag) {\n var queryKey = this.queryKeyForTag_(tag);\n if (queryKey) {\n var r = SyncTree.parseQueryKey_(queryKey);\n var queryPath = r.path,\n queryId = r.queryId;\n var relativePath = Path[\"a\" /* Path */].relativePath(queryPath, path);\n var changeTree = ImmutableTree[\"a\" /* ImmutableTree */].fromObject(changedChildren);\n var op = new Merge_Merge(Operation[\"a\" /* OperationSource */].forServerTaggedQuery(queryId), 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 /**\r\n * Apply a listen complete for a tagged query\r\n *\r\n * @param {!Path} path\r\n * @param {!number} tag\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.applyTaggedListenComplete = function (path, tag) {\n var queryKey = this.queryKeyForTag_(tag);\n if (queryKey) {\n var r = SyncTree.parseQueryKey_(queryKey);\n var queryPath = r.path,\n queryId = r.queryId;\n var relativePath = Path[\"a\" /* Path */].relativePath(queryPath, path);\n var op = new ListenComplete_ListenComplete(Operation[\"a\" /* OperationSource */].forServerTaggedQuery(queryId), 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 /**\r\n * Add an event callback for the specified query.\r\n *\r\n * @param {!Query} query\r\n * @param {!EventRegistration} eventRegistration\r\n * @return {!Array.} Events to raise.\r\n */\n SyncTree.prototype.addEventRegistration = function (query, eventRegistration) {\n var path = query.path;\n var serverCache = null;\n var 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 var relativePath = Path[\"a\" /* Path */].relativePath(pathToSyncPoint, path);\n serverCache = serverCache || sp.getCompleteServerCache(relativePath);\n foundAncestorDefaultView = foundAncestorDefaultView || sp.hasCompleteView();\n });\n var syncPoint = this.syncPointTree_.get(path);\n if (!syncPoint) {\n syncPoint = new SyncPoint[\"a\" /* SyncPoint */]();\n this.syncPointTree_ = this.syncPointTree_.set(path, syncPoint);\n } else {\n foundAncestorDefaultView = foundAncestorDefaultView || syncPoint.hasCompleteView();\n serverCache = serverCache || syncPoint.getCompleteServerCache(Path[\"a\" /* Path */].Empty);\n }\n var serverCacheComplete;\n if (serverCache != null) {\n serverCacheComplete = true;\n } else {\n serverCacheComplete = false;\n serverCache = ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n var subtree = this.syncPointTree_.subtree(path);\n subtree.foreachChild(function (childName, childSyncPoint) {\n var completeCache = childSyncPoint.getCompleteServerCache(Path[\"a\" /* Path */].Empty);\n if (completeCache) {\n serverCache = serverCache.updateImmediateChild(childName, completeCache);\n }\n });\n }\n var viewAlreadyExists = syncPoint.viewExistsForQuery(query);\n if (!viewAlreadyExists && !query.getQueryParams().loadsAllData()) {\n // We need to track a tag for this query\n var queryKey = SyncTree.makeQueryKey_(query);\n Object(assert[\"a\" /* assert */])(!(queryKey in this.queryToTagMap_), 'View does not exist, but we have a tag');\n var tag = SyncTree.getNextQueryTag_();\n this.queryToTagMap_[queryKey] = tag;\n // Coerce to string to avoid sparse arrays.\n this.tagToQueryMap_['_' + tag] = queryKey;\n }\n var writesCache = this.pendingWriteTree_.childWrites(path);\n var events = syncPoint.addEventRegistration(query, eventRegistration, writesCache, serverCache, serverCacheComplete);\n if (!viewAlreadyExists && !foundAncestorDefaultView) {\n var view /** @type !View */ = syncPoint.viewForQuery(query);\n events = events.concat(this.setupListener_(query, view));\n }\n return events;\n };\n /**\r\n * Remove event callback(s).\r\n *\r\n * If query is the default query, we'll check all queries for the specified eventRegistration.\r\n * If eventRegistration is null, we'll remove all callbacks for the specified query/queries.\r\n *\r\n * @param {!Query} query\r\n * @param {?EventRegistration} eventRegistration If null, all callbacks are removed.\r\n * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\r\n * @return {!Array.} Cancel events, if cancelError was provided.\r\n */\n SyncTree.prototype.removeEventRegistration = function (query, eventRegistration, cancelError) {\n var _this = this;\n // Find the syncPoint first. Then deal with whether or not it has matching listeners\n var path = query.path;\n var maybeSyncPoint = this.syncPointTree_.get(path);\n var cancelEvents = [];\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 /**\r\n * @type {{removed: !Array., events: !Array.}}\r\n */\n var removedAndEvents = maybeSyncPoint.removeEventRegistration(query, eventRegistration, cancelError);\n if (maybeSyncPoint.isEmpty()) {\n this.syncPointTree_ = this.syncPointTree_.remove(path);\n }\n var 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 var removingDefault = -1 !== removed.findIndex(function (query) {\n return query.getQueryParams().loadsAllData();\n });\n var covered = this.syncPointTree_.findOnPath(path, function (relativePath, parentSyncPoint) {\n return parentSyncPoint.hasCompleteView();\n });\n if (removingDefault && !covered) {\n var 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 var newViews = this.collectDistinctViewsForSubTree_(subtree);\n // Ok, we've collected all the listens we need. Set them up.\n for (var i = 0; i < newViews.length; ++i) {\n var view = newViews[i],\n newQuery = view.getQuery();\n var listener = this.createListenerForView_(view);\n this.listenProvider_.startListening(SyncTree.queryForListening_(newQuery), this.tagForQuery_(newQuery), 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 var defaultTag = null;\n this.listenProvider_.stopListening(SyncTree.queryForListening_(query), defaultTag);\n } else {\n removed.forEach(function (queryToRemove) {\n var 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 /**\r\n * Returns a complete cache, if we have one, of the data at a particular path. The location must have a listener above\r\n * it, but as this is only used by transaction code, that should always be the case anyways.\r\n *\r\n * Note: this method will *include* hidden writes from transaction with applyLocally set to false.\r\n * @param {!Path} path The path to the data we want\r\n * @param {Array.=} writeIdsToExclude A specific set to be excluded\r\n * @return {?Node}\r\n */\n SyncTree.prototype.calcCompleteEventCache = function (path, writeIdsToExclude) {\n var includeHiddenSets = true;\n var writeTree = this.pendingWriteTree_;\n var serverCache = this.syncPointTree_.findOnPath(path, function (pathSoFar, syncPoint) {\n var relativePath = Path[\"a\" /* Path */].relativePath(pathSoFar, path);\n var serverCache = syncPoint.getCompleteServerCache(relativePath);\n if (serverCache) {\n return serverCache;\n }\n });\n return writeTree.calcCompleteEventCache(path, serverCache, writeIdsToExclude, includeHiddenSets);\n };\n /**\r\n * This collapses multiple unfiltered views into a single view, since we only need a single\r\n * listener for them.\r\n *\r\n * @param {!ImmutableTree.} subtree\r\n * @return {!Array.}\r\n * @private\r\n */\n SyncTree.prototype.collectDistinctViewsForSubTree_ = function (subtree) {\n return subtree.fold(function (relativePath, maybeChildSyncPoint, childMap) {\n if (maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {\n var completeView = maybeChildSyncPoint.getCompleteView();\n return [completeView];\n } else {\n // No complete view here, flatten any deeper listens into an array\n var views_1 = [];\n if (maybeChildSyncPoint) {\n views_1 = maybeChildSyncPoint.getQueryViews();\n }\n Object(obj[\"f\" /* forEach */])(childMap, function (key, childViews) {\n views_1 = views_1.concat(childViews);\n });\n return views_1;\n }\n });\n };\n /**\r\n * @param {!Array.} queries\r\n * @private\r\n */\n SyncTree.prototype.removeTags_ = function (queries) {\n for (var j = 0; j < queries.length; ++j) {\n var removedQuery = queries[j];\n if (!removedQuery.getQueryParams().loadsAllData()) {\n // We should have a tag for this\n var removedQueryKey = SyncTree.makeQueryKey_(removedQuery);\n var removedQueryTag = this.queryToTagMap_[removedQueryKey];\n delete this.queryToTagMap_[removedQueryKey];\n delete this.tagToQueryMap_['_' + removedQueryTag];\n }\n }\n };\n /**\r\n * Normalizes a query to a query we send the server for listening\r\n * @param {!Query} query\r\n * @return {!Query} The normalized query\r\n * @private\r\n */\n SyncTree.queryForListening_ = function (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 );\n } else {\n return query;\n }\n };\n /**\r\n * For a given new listen, manage the de-duplication of outstanding subscriptions.\r\n *\r\n * @param {!Query} query\r\n * @param {!View} view\r\n * @return {!Array.} This method can return events to support synchronous data sources\r\n * @private\r\n */\n SyncTree.prototype.setupListener_ = function (query, view) {\n var path = query.path;\n var tag = this.tagForQuery_(query);\n var listener = this.createListenerForView_(view);\n var events = this.listenProvider_.startListening(SyncTree.queryForListening_(query), tag, listener.hashFn, listener.onComplete);\n var 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 Object(assert[\"a\" /* 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 var 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 var queries_1 = [];\n if (maybeChildSyncPoint) {\n queries_1 = queries_1.concat(maybeChildSyncPoint.getQueryViews().map(function (view) {\n return view.getQuery();\n }));\n }\n Object(obj[\"f\" /* forEach */])(childMap, function (key, childQueries) {\n queries_1 = queries_1.concat(childQueries);\n });\n return queries_1;\n }\n });\n for (var i = 0; i < queriesToStop.length; ++i) {\n var queryToStop = queriesToStop[i];\n this.listenProvider_.stopListening(SyncTree.queryForListening_(queryToStop), this.tagForQuery_(queryToStop));\n }\n }\n return events;\n };\n /**\r\n *\r\n * @param {!View} view\r\n * @return {{hashFn: function(), onComplete: function(!string, *)}}\r\n * @private\r\n */\n SyncTree.prototype.createListenerForView_ = function (view) {\n var _this = this;\n var query = view.getQuery();\n var tag = this.tagForQuery_(query);\n return {\n hashFn: function hashFn() {\n var cache = view.getServerCache() || ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n return cache.hash();\n },\n onComplete: function onComplete(status) {\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 var error = Object(util[\"l\" /* errorForServerCode */])(status, query);\n return _this.removeEventRegistration(query,\n /*eventRegistration*/null, error);\n }\n }\n };\n };\n /**\r\n * Given a query, computes a \"queryKey\" suitable for use in our queryToTagMap_.\r\n * @private\r\n * @param {!Query} query\r\n * @return {string}\r\n */\n SyncTree.makeQueryKey_ = function (query) {\n return query.path.toString() + '$' + query.queryIdentifier();\n };\n /**\r\n * Given a queryKey (created by makeQueryKey), parse it back into a path and queryId.\r\n * @private\r\n * @param {!string} queryKey\r\n * @return {{queryId: !string, path: !Path}}\r\n */\n SyncTree.parseQueryKey_ = function (queryKey) {\n var splitIndex = queryKey.indexOf('$');\n Object(assert[\"a\" /* assert */])(splitIndex !== -1 && splitIndex < queryKey.length - 1, 'Bad queryKey.');\n return {\n queryId: queryKey.substr(splitIndex + 1),\n path: new Path[\"a\" /* Path */](queryKey.substr(0, splitIndex))\n };\n };\n /**\r\n * Return the query associated with the given tag, if we have one\r\n * @param {!number} tag\r\n * @return {?string}\r\n * @private\r\n */\n SyncTree.prototype.queryKeyForTag_ = function (tag) {\n return this.tagToQueryMap_['_' + tag];\n };\n /**\r\n * Return the tag associated with the given query.\r\n * @param {!Query} query\r\n * @return {?number}\r\n * @private\r\n */\n SyncTree.prototype.tagForQuery_ = function (query) {\n var queryKey = SyncTree.makeQueryKey_(query);\n return Object(obj[\"l\" /* safeGet */])(this.queryToTagMap_, queryKey);\n };\n /**\r\n * Static accessor for query tags.\r\n * @return {number}\r\n * @private\r\n */\n SyncTree.getNextQueryTag_ = function () {\n return SyncTree.nextQueryTag_++;\n };\n /**\r\n * A helper method to apply tagged operations\r\n *\r\n * @param {!Path} queryPath\r\n * @param {!Operation} operation\r\n * @return {!Array.}\r\n * @private\r\n */\n SyncTree.prototype.applyTaggedOperation_ = function (queryPath, operation) {\n var syncPoint = this.syncPointTree_.get(queryPath);\n Object(assert[\"a\" /* assert */])(syncPoint, \"Missing sync point for query tag that we're tracking\");\n var writesCache = this.pendingWriteTree_.childWrites(queryPath);\n return syncPoint.applyOperation(operation, writesCache,\n /*serverCache=*/null);\n };\n /**\r\n * A helper method that visits all descendant and ancestor SyncPoints, applying the operation.\r\n *\r\n * NOTES:\r\n * - Descendant SyncPoints will be visited first (since we raise events depth-first).\r\n * - We call applyOperation() on each SyncPoint passing three things:\r\n * 1. A version of the Operation that has been made relative to the SyncPoint location.\r\n * 2. A WriteTreeRef of any writes we have cached at the SyncPoint location.\r\n * 3. A snapshot Node with cached server data, if we have it.\r\n * - We concatenate all of the events returned by each SyncPoint and return the result.\r\n *\r\n * @param {!Operation} operation\r\n * @return {!Array.}\r\n * @private\r\n */\n SyncTree.prototype.applyOperationToSyncPoints_ = function (operation) {\n return this.applyOperationHelper_(operation, this.syncPointTree_,\n /*serverCache=*/null, this.pendingWriteTree_.childWrites(Path[\"a\" /* Path */].Empty));\n };\n /**\r\n * Recursive helper for applyOperationToSyncPoints_\r\n *\r\n * @private\r\n * @param {!Operation} operation\r\n * @param {ImmutableTree.} syncPointTree\r\n * @param {?Node} serverCache\r\n * @param {!WriteTreeRef} writesCache\r\n * @return {!Array.}\r\n */\n SyncTree.prototype.applyOperationHelper_ = function (operation, syncPointTree, serverCache, writesCache) {\n if (operation.path.isEmpty()) {\n return this.applyOperationDescendantsHelper_(operation, syncPointTree, serverCache, writesCache);\n } else {\n var syncPoint = syncPointTree.get(Path[\"a\" /* Path */].Empty);\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[\"a\" /* Path */].Empty);\n }\n var events = [];\n var childName = operation.path.getFront();\n var childOperation = operation.operationForChild(childName);\n var childTree = syncPointTree.children.get(childName);\n if (childTree && childOperation) {\n var childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null;\n var childWritesCache = writesCache.child(childName);\n events = events.concat(this.applyOperationHelper_(childOperation, childTree, childServerCache, childWritesCache));\n }\n if (syncPoint) {\n events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));\n }\n return events;\n }\n };\n /**\r\n * Recursive helper for applyOperationToSyncPoints_\r\n *\r\n * @private\r\n * @param {!Operation} operation\r\n * @param {ImmutableTree.} syncPointTree\r\n * @param {?Node} serverCache\r\n * @param {!WriteTreeRef} writesCache\r\n * @return {!Array.}\r\n */\n SyncTree.prototype.applyOperationDescendantsHelper_ = function (operation, syncPointTree, serverCache, writesCache) {\n var _this = this;\n var syncPoint = syncPointTree.get(Path[\"a\" /* Path */].Empty);\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[\"a\" /* Path */].Empty);\n }\n var events = [];\n syncPointTree.children.inorderTraversal(function (childName, childTree) {\n var childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null;\n var childWritesCache = writesCache.child(childName);\n var childOperation = operation.operationForChild(childName);\n if (childOperation) {\n events = events.concat(_this.applyOperationDescendantsHelper_(childOperation, childTree, childServerCache, childWritesCache));\n }\n });\n if (syncPoint) {\n events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));\n }\n return events;\n };\n /**\r\n * Static tracker for next query tag.\r\n * @type {number}\r\n * @private\r\n */\n SyncTree.nextQueryTag_ = 1;\n return SyncTree;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/SnapshotHolder.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 * Mutable object which basically just stores a reference to the \"latest\" immutable snapshot.\r\n *\r\n * @constructor\r\n */\nvar SnapshotHolder_SnapshotHolder = /** @class */function () {\n function SnapshotHolder() {\n this.rootNode_ = ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n }\n SnapshotHolder.prototype.getNode = function (path) {\n return this.rootNode_.getChild(path);\n };\n SnapshotHolder.prototype.updateSnapshot = function (path, newSnapshotNode) {\n this.rootNode_ = this.rootNode_.updateChild(path, newSnapshotNode);\n };\n return SnapshotHolder;\n}();\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// CONCATENATED MODULE: ./src/database/core/AuthTokenProvider.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 * Abstraction around FirebaseApp's token fetching capabilities.\r\n */\nvar AuthTokenProvider_AuthTokenProvider = /** @class */function () {\n /**\r\n * @param {!FirebaseApp} app_\r\n */\n function AuthTokenProvider(app_) {\n this.app_ = app_;\n }\n /**\r\n * @param {boolean} forceRefresh\r\n * @return {!Promise}\r\n */\n AuthTokenProvider.prototype.getToken = function (forceRefresh) {\n return this.app_['INTERNAL']['getToken'](forceRefresh).then(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 Object(util[\"s\" /* 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 AuthTokenProvider.prototype.addTokenChangeListener = function (listener) {\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 AuthTokenProvider.prototype.removeTokenChangeListener = function (listener) {\n this.app_['INTERNAL']['removeAuthTokenListener'](listener);\n };\n AuthTokenProvider.prototype.notifyForInvalidToken = function () {\n var errorMessage = 'Provided authentication credentials for the app named \"' + this.app_.name + '\" are invalid. This usually indicates your app was not ' + 'initialized correctly. ';\n if ('credential' in this.app_.options) {\n errorMessage += 'Make sure the \"credential\" property provided to initializeApp() ' + 'is authorized to access the specified \"databaseURL\" and is from the correct ' + 'project.';\n } else if ('serviceAccount' in this.app_.options) {\n errorMessage += 'Make sure the \"serviceAccount\" property provided to initializeApp() ' + 'is authorized to access the specified \"databaseURL\" and is from the correct ' + 'project.';\n } else {\n errorMessage += 'Make sure the \"apiKey\" and \"databaseURL\" properties provided to ' + 'initializeApp() match the values provided for your app at ' + 'https://console.firebase.google.com/.';\n }\n Object(util[\"B\" /* warn */])(errorMessage);\n };\n return AuthTokenProvider;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/stats/StatsManager.ts + 1 modules\nvar StatsManager = __webpack_require__(29);\n\n// CONCATENATED MODULE: ./src/database/core/stats/StatsListener.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 delta from the previous call to get stats.\r\n *\r\n * @param collection_ The collection to \"listen\" to.\r\n * @constructor\r\n */\nvar StatsListener_StatsListener = /** @class */function () {\n function StatsListener(collection_) {\n this.collection_ = collection_;\n this.last_ = null;\n }\n StatsListener.prototype.get = function () {\n var newStats = this.collection_.get();\n var delta = Object(obj[\"a\" /* clone */])(newStats);\n if (this.last_) {\n Object(obj[\"f\" /* forEach */])(this.last_, function (stat, value) {\n delta[stat] = delta[stat] - value;\n });\n }\n this.last_ = newStats;\n return delta;\n };\n return StatsListener;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/stats/StatsReporter.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// 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.\nvar FIRST_STATS_MIN_TIME = 10 * 1000;\nvar FIRST_STATS_MAX_TIME = 30 * 1000;\n// We'll continue to report stats on average every 5 minutes.\nvar REPORT_STATS_INTERVAL = 5 * 60 * 1000;\n/**\r\n * @constructor\r\n */\nvar StatsReporter_StatsReporter = /** @class */function () {\n /**\r\n * @param collection\r\n * @param server_\r\n */\n function StatsReporter(collection, server_) {\n this.server_ = server_;\n this.statsToReport_ = {};\n this.statsListener_ = new StatsListener_StatsListener(collection);\n var timeout = FIRST_STATS_MIN_TIME + (FIRST_STATS_MAX_TIME - FIRST_STATS_MIN_TIME) * Math.random();\n Object(util[\"x\" /* setTimeoutNonBlocking */])(this.reportStats_.bind(this), Math.floor(timeout));\n }\n StatsReporter.prototype.includeStat = function (stat) {\n this.statsToReport_[stat] = true;\n };\n StatsReporter.prototype.reportStats_ = function () {\n var _this = this;\n var stats = this.statsListener_.get();\n var reportedStats = {};\n var haveStatsToReport = false;\n Object(obj[\"f\" /* forEach */])(stats, function (stat, value) {\n if (value > 0 && Object(obj[\"b\" /* contains */])(_this.statsToReport_, stat)) {\n reportedStats[stat] = value;\n haveStatsToReport = true;\n }\n });\n if (haveStatsToReport) {\n this.server_.reportStats(reportedStats);\n }\n // queue our next run.\n Object(util[\"x\" /* setTimeoutNonBlocking */])(this.reportStats_.bind(this), Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL));\n };\n return StatsReporter;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/view/EventQueue.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 * The event queue serves a few purposes:\r\n * 1. It ensures we maintain event order in the face of event callbacks doing operations that result in more\r\n * events being queued.\r\n * 2. raiseQueuedEvents() handles being called reentrantly nicely. That is, if in the course of raising events,\r\n * raiseQueuedEvents() is called again, the \"inner\" call will pick up raising events where the \"outer\" call\r\n * left off, ensuring that the events are still raised synchronously and in order.\r\n * 3. You can use raiseEventsAtPath and raiseEventsForChangedPath to ensure only relevant previously-queued\r\n * events are raised synchronously.\r\n *\r\n * NOTE: This can all go away if/when we move to async events.\r\n *\r\n * @constructor\r\n */\nvar EventQueue = /** @class */function () {\n function EventQueue() {\n /**\r\n * @private\r\n * @type {!Array.}\r\n */\n this.eventLists_ = [];\n /**\r\n * Tracks recursion depth of raiseQueuedEvents_, for debugging purposes.\r\n * @private\r\n * @type {!number}\r\n */\n this.recursionDepth_ = 0;\n }\n /**\r\n * @param {!Array.} eventDataList The new events to queue.\r\n */\n EventQueue.prototype.queueEvents = function (eventDataList) {\n // We group events by path, storing them in a single EventList, to make it easier to skip over them quickly.\n var currList = null;\n for (var i = 0; i < eventDataList.length; i++) {\n var eventData = eventDataList[i];\n var eventPath = eventData.getPath();\n if (currList !== null && !eventPath.equals(currList.getPath())) {\n this.eventLists_.push(currList);\n currList = null;\n }\n if (currList === null) {\n currList = new EventQueue_EventList(eventPath);\n }\n currList.add(eventData);\n }\n if (currList) {\n this.eventLists_.push(currList);\n }\n };\n /**\r\n * Queues the specified events and synchronously raises all events (including previously queued ones)\r\n * for the specified path.\r\n *\r\n * It is assumed that the new events are all for the specified path.\r\n *\r\n * @param {!Path} path The path to raise events for.\r\n * @param {!Array.} eventDataList The new events to raise.\r\n */\n EventQueue.prototype.raiseEventsAtPath = function (path, eventDataList) {\n this.queueEvents(eventDataList);\n this.raiseQueuedEventsMatchingPredicate_(function (eventPath) {\n return eventPath.equals(path);\n });\n };\n /**\r\n * Queues the specified events and synchronously raises all events (including previously queued ones) for\r\n * locations related to the specified change path (i.e. all ancestors and descendants).\r\n *\r\n * It is assumed that the new events are all related (ancestor or descendant) to the specified path.\r\n *\r\n * @param {!Path} changedPath The path to raise events for.\r\n * @param {!Array.} eventDataList The events to raise\r\n */\n EventQueue.prototype.raiseEventsForChangedPath = function (changedPath, eventDataList) {\n this.queueEvents(eventDataList);\n this.raiseQueuedEventsMatchingPredicate_(function (eventPath) {\n return eventPath.contains(changedPath) || changedPath.contains(eventPath);\n });\n };\n /**\r\n * @param {!function(!Path):boolean} predicate\r\n * @private\r\n */\n EventQueue.prototype.raiseQueuedEventsMatchingPredicate_ = function (predicate) {\n this.recursionDepth_++;\n var sentAll = true;\n for (var i = 0; i < this.eventLists_.length; i++) {\n var eventList = this.eventLists_[i];\n if (eventList) {\n var 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 if (sentAll) {\n this.eventLists_ = [];\n }\n this.recursionDepth_--;\n };\n return EventQueue;\n}();\n\n/**\r\n * @param {!Path} path\r\n * @constructor\r\n */\nvar EventQueue_EventList = /** @class */function () {\n function EventList(path_) {\n this.path_ = path_;\n /**\r\n * @type {!Array.}\r\n * @private\r\n */\n this.events_ = [];\n }\n /**\r\n * @param {!Event} eventData\r\n */\n EventList.prototype.add = function (eventData) {\n this.events_.push(eventData);\n };\n /**\r\n * Iterates through the list and raises each event\r\n */\n EventList.prototype.raise = function () {\n for (var i = 0; i < this.events_.length; i++) {\n var eventData = this.events_[i];\n if (eventData !== null) {\n this.events_[i] = null;\n var eventFn = eventData.getEventRunner();\n if (util[\"u\" /* logger */]) {\n Object(util[\"s\" /* log */])('event: ' + eventData.toString());\n }\n Object(util[\"m\" /* exceptionGuard */])(eventFn);\n }\n }\n };\n /**\r\n * @return {!Path}\r\n */\n EventList.prototype.getPath = function () {\n return this.path_;\n };\n return EventList;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/PersistentConnection.ts + 4 modules\nvar PersistentConnection = __webpack_require__(51);\n\n// CONCATENATED MODULE: ./src/utils/util.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 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 util_querystring = function querystring(querystringParams) {\n var params = [];\n Object(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// EXTERNAL MODULE: ./src/database/core/ServerActions.ts\nvar ServerActions = __webpack_require__(55);\n\n// CONCATENATED MODULE: ./src/database/core/ReadonlyRestClient.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 __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 = /** @class */function (_super) {\n __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_ = Object(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 Object(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 (Object(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 + '?' + util_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 = Object(json[\"a\" /* jsonEval */])(xhr.responseText);\n } catch (e) {\n Object(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 Object(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[\"a\" /* ServerActions */]);\n\n// EXTERNAL MODULE: ./src/database/api/Database.ts\nvar Database = __webpack_require__(36);\n\n// CONCATENATED MODULE: ./src/database/core/Repo.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Repo_Repo; });\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\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 = /** @class */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[\"a\" /* 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_AuthTokenProvider(app);\n this.stats_ = StatsManager[\"a\" /* StatsManager */].getCollection(repoInfo_);\n if (forceRestClient || Object(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' : _typeof(authOverride)) !== 'object') {\n throw new Error('Only objects are supported for option databaseAuthVariableOverride');\n }\n try {\n Object(json[\"b\" /* stringify */])(authOverride);\n } catch (e) {\n throw new Error('Invalid authOverride provided: ' + e);\n }\n }\n this.persistentConnection_ = new PersistentConnection[\"a\" /* 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_ = 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[\"a\" /* 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 Object(ServerValues[\"a\" /* 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[\"a\" /* Path */](pathString);\n data = this.interceptServerDataCallback_ ? this.interceptServerDataCallback_(pathString, data) : data;\n var events = [];\n if (tag) {\n if (isMerge) {\n var taggedChildren = Object(obj[\"k\" /* map */])(data, function (raw) {\n return Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(raw);\n });\n events = this.serverSyncTree_.applyTaggedQueryMerge(path, taggedChildren, tag);\n } else {\n var taggedSnap = Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(data);\n events = this.serverSyncTree_.applyTaggedQueryOverwrite(path, taggedSnap, tag);\n }\n } else if (isMerge) {\n var changedChildren = Object(obj[\"k\" /* map */])(data, function (raw) {\n return Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(raw);\n });\n events = this.serverSyncTree_.applyServerMerge(path, changedChildren);\n } else {\n var snap = Object(nodeFromJSON[\"a\" /* 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 Object(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[\"a\" /* Path */]('/.info/' + pathString);\n var newNode = Object(nodeFromJSON[\"a\" /* 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', {\n path: path.toString(),\n value: newVal,\n 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 var serverValues = this.generateServerValues();\n var newNodeUnresolved = Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(newVal, newPriority);\n var newNode = Object(ServerValues[\"b\" /* 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 Object(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 Object(obj[\"f\" /* forEach */])(childrenToMerge, function (changedKey, changedValue) {\n empty = false;\n var newNodeUnresolved = Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(changedValue);\n changedChildren[changedKey] = Object(ServerValues[\"b\" /* 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 Object(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 Object(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 Object(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 = Object(ServerValues[\"c\" /* resolveDeferredValueTree */])(this.onDisconnect_, serverValues);\n var events = [];\n resolvedOnDisconnectTree.forEachTree(Path[\"a\" /* 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[\"a\" /* SparseSnapshotTree */]();\n this.eventQueue_.raiseEventsForChangedPath(Path[\"a\" /* 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 = Object(nodeFromJSON[\"a\" /* 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 = Object(nodeFromJSON[\"a\" /* 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 (Object(obj[\"j\" /* isEmpty */])(childrenToMerge)) {\n Object(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 Object(obj[\"f\" /* forEach */])(childrenToMerge, function (childName, childNode) {\n var newChildNode = Object(nodeFromJSON[\"a\" /* 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_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 Object(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 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 Object(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[\"a\" /* Database */](this));\n },\n enumerable: true,\n configurable: true\n });\n return Repo;\n}();\n\n\n/***/ }),\n/* 24 */,\n/* 25 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return stringToByteArray; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return stringLength; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__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// 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// 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/**\r\n * @param {string} str\r\n * @return {Array}\r\n */\nvar stringToByteArray = function stringToByteArray(str) {\n var out = [],\n p = 0;\n for (var i = 0; i < str.length; i++) {\n var c = str.charCodeAt(i);\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 Object(__WEBPACK_IMPORTED_MODULE_0__assert__[\"a\" /* 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 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/**\r\n * Calculate length without actually converting; useful for doing cheaper validation.\r\n * @param {string} str\r\n * @return {number}\r\n */\nvar stringLength = function stringLength(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/* 26 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/utils/validation.ts\nvar validation = __webpack_require__(10);\n\n// EXTERNAL MODULE: ./src/database/core/util/validation.ts\nvar util_validation = __webpack_require__(11);\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/utils/promise.ts\nvar utils_promise = __webpack_require__(3);\n\n// CONCATENATED MODULE: ./src/database/api/onDisconnect.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 * @constructor\r\n */\nvar onDisconnect_OnDisconnect = /** @class */function () {\n /**\r\n * @param {!Repo} repo_\r\n * @param {!Path} path_\r\n */\n function OnDisconnect(repo_, path_) {\n this.repo_ = repo_;\n this.path_ = path_;\n }\n /**\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\n OnDisconnect.prototype.cancel = function (onComplete) {\n Object(validation[\"b\" /* validateArgCount */])('OnDisconnect.cancel', 0, 1, arguments.length);\n Object(validation[\"c\" /* validateCallback */])('OnDisconnect.cancel', 1, onComplete, true);\n var deferred = new utils_promise[\"a\" /* Deferred */]();\n this.repo_.onDisconnectCancel(this.path_, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\n OnDisconnect.prototype.remove = function (onComplete) {\n Object(validation[\"b\" /* validateArgCount */])('OnDisconnect.remove', 0, 1, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('OnDisconnect.remove', this.path_);\n Object(validation[\"c\" /* validateCallback */])('OnDisconnect.remove', 1, onComplete, true);\n var deferred = new utils_promise[\"a\" /* Deferred */]();\n this.repo_.onDisconnectSet(this.path_, null, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {*} value\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\n OnDisconnect.prototype.set = function (value, onComplete) {\n Object(validation[\"b\" /* validateArgCount */])('OnDisconnect.set', 1, 2, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('OnDisconnect.set', this.path_);\n Object(util_validation[\"e\" /* validateFirebaseDataArg */])('OnDisconnect.set', 1, value, this.path_, false);\n Object(validation[\"c\" /* validateCallback */])('OnDisconnect.set', 2, onComplete, true);\n var deferred = new utils_promise[\"a\" /* Deferred */]();\n this.repo_.onDisconnectSet(this.path_, value, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {*} value\r\n * @param {number|string|null} priority\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\n OnDisconnect.prototype.setWithPriority = function (value, priority, onComplete) {\n Object(validation[\"b\" /* validateArgCount */])('OnDisconnect.setWithPriority', 2, 3, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('OnDisconnect.setWithPriority', this.path_);\n Object(util_validation[\"e\" /* validateFirebaseDataArg */])('OnDisconnect.setWithPriority', 1, value, this.path_, false);\n Object(util_validation[\"i\" /* validatePriority */])('OnDisconnect.setWithPriority', 2, priority, false);\n Object(validation[\"c\" /* validateCallback */])('OnDisconnect.setWithPriority', 3, onComplete, true);\n var deferred = new utils_promise[\"a\" /* Deferred */]();\n this.repo_.onDisconnectSetWithPriority(this.path_, value, priority, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n /**\r\n * @param {!Object} objectToMerge\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\n OnDisconnect.prototype.update = function (objectToMerge, onComplete) {\n Object(validation[\"b\" /* validateArgCount */])('OnDisconnect.update', 1, 2, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('OnDisconnect.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 Object(util[\"B\" /* warn */])('Passing an Array to firebase.database.onDisconnect().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 Object(util_validation[\"f\" /* validateFirebaseMergeDataArg */])('OnDisconnect.update', 1, objectToMerge, this.path_, false);\n Object(validation[\"c\" /* validateCallback */])('OnDisconnect.update', 2, onComplete, true);\n var deferred = new utils_promise[\"a\" /* Deferred */]();\n this.repo_.onDisconnectUpdate(this.path_, objectToMerge, deferred.wrapCallback(onComplete));\n return deferred.promise;\n };\n return OnDisconnect;\n}();\n\n// CONCATENATED MODULE: ./src/database/api/TransactionResult.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 TransactionResult_TransactionResult = /** @class */function () {\n /**\r\n * A type for the resolve value of Firebase.transaction.\r\n * @constructor\r\n * @dict\r\n * @param {boolean} committed\r\n * @param {DataSnapshot} snapshot\r\n */\n function TransactionResult(committed, snapshot) {\n this.committed = committed;\n this.snapshot = snapshot;\n }\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n // for end-users\n TransactionResult.prototype.toJSON = function () {\n Object(validation[\"b\" /* validateArgCount */])('TransactionResult.toJSON', 0, 1, arguments.length);\n return { committed: this.committed, snapshot: this.snapshot.toJSON() };\n };\n return TransactionResult;\n}();\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./src/database/core/util/NextPushId.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 * Fancy ID generator that creates 20-character string identifiers with the\r\n * following properties:\r\n *\r\n * 1. They're based on timestamp so that they sort *after* any existing ids.\r\n * 2. They contain 72-bits of random data after the timestamp so that IDs won't\r\n * collide with other clients' IDs.\r\n * 3. They sort *lexicographically* (so the timestamp is converted to characters\r\n * that will sort properly).\r\n * 4. They're monotonically increasing. Even if you generate more than one in\r\n * the same timestamp, the latter ones will sort after the former ones. We do\r\n * this by using the previous random bits but \"incrementing\" them by 1 (only\r\n * in the case of a timestamp collision).\r\n */\nvar nextPushId = function () {\n // Modeled after base64 web-safe chars, but ordered by ASCII.\n var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';\n // Timestamp of last push, used to prevent local collisions if you push twice\n // in one ms.\n var lastPushTime = 0;\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 var lastRandChars = [];\n return function (now) {\n var duplicateTime = now === lastPushTime;\n lastPushTime = now;\n var i;\n var 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 Object(assert[\"a\" /* assert */])(now === 0, 'Cannot push at time == 0');\n var id = timeStampChars.join('');\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 Object(assert[\"a\" /* assert */])(id.length === 20, 'nextPushId: Length should be 20.');\n return id;\n };\n}();\n// EXTERNAL MODULE: ./src/database/api/Query.ts + 2 modules\nvar Query = __webpack_require__(39);\n\n// EXTERNAL MODULE: ./src/database/core/Repo.ts + 14 modules\nvar Repo = __webpack_require__(23);\n\n// EXTERNAL MODULE: ./src/database/core/util/Path.ts\nvar Path = __webpack_require__(4);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/KeyIndex.ts\nvar KeyIndex = __webpack_require__(15);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/PriorityIndex.ts\nvar PriorityIndex = __webpack_require__(5);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/ValueIndex.ts\nvar ValueIndex = __webpack_require__(41);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/PathIndex.ts\nvar PathIndex = __webpack_require__(45);\n\n// EXTERNAL MODULE: ./src/database/core/view/filter/IndexedFilter.ts\nvar IndexedFilter = __webpack_require__(28);\n\n// EXTERNAL MODULE: ./src/database/core/snap/Node.ts\nvar Node = __webpack_require__(7);\n\n// EXTERNAL MODULE: ./src/database/core/snap/ChildrenNode.ts\nvar ChildrenNode = __webpack_require__(6);\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 = /** @class */function () {\n /**\r\n * @param {!QueryParams} params\r\n */\n function RangedFilter(params) {\n this.indexedFilter_ = new IndexedFilter[\"a\" /* 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 Node[\"a\" /* NamedNode */](key, newChild))) {\n newChild = ChildrenNode[\"a\" /* 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[\"a\" /* ChildrenNode */].EMPTY_NODE;\n }\n var filtered = newSnap.withIndex(this.index_);\n // Don't support priorities on queries\n filtered = filtered.updatePriority(ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE);\n var self = this;\n newSnap.forEachChild(PriorityIndex[\"a\" /* PRIORITY_INDEX */], function (key, childNode) {\n if (!self.matches(new Node[\"a\" /* NamedNode */](key, childNode))) {\n filtered = filtered.updateImmediateChild(key, ChildrenNode[\"a\" /* 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// EXTERNAL MODULE: ./src/database/core/view/Change.ts\nvar Change = __webpack_require__(14);\n\n// CONCATENATED MODULE: ./src/database/core/view/filter/LimitedFilter.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 * 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 = /** @class */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 Node[\"a\" /* NamedNode */](key, newChild))) {\n newChild = ChildrenNode[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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 Object(assert[\"a\" /* assert */])(oldEventCache.numChildren() == this.limit_, '');\n var newChildNamedNode = new Node[\"a\" /* 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[\"a\" /* Change */].childChangedChange(childKey, childSnap, oldChildSnap));\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap);\n } else {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change[\"a\" /* Change */].childRemovedChange(childKey, oldChildSnap));\n }\n var newEventCache = oldEventCache.updateImmediateChild(childKey, ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE);\n var nextChildInRange = nextChild != null && this.rangedFilter_.matches(nextChild);\n if (nextChildInRange) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(Change[\"a\" /* 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[\"a\" /* Change */].childRemovedChange(windowBoundary.name, windowBoundary.node));\n changeAccumulator.trackChildChange(Change[\"a\" /* Change */].childAddedChange(childKey, childSnap));\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap).updateImmediateChild(windowBoundary.name, ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE);\n } else {\n return snap;\n }\n } else {\n return snap;\n }\n };\n return LimitedFilter;\n}();\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// CONCATENATED MODULE: ./src/database/core/view/QueryParams.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\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 = /** @class */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_ = PriorityIndex[\"a\" /* 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 Object(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 Object(assert[\"a\" /* assert */])(this.startSet_, 'Only valid if start has been set');\n if (this.startNameSet_) {\n return this.indexStartName_;\n } else {\n return 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 Object(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 Object(assert[\"a\" /* assert */])(this.endSet_, 'Only valid if end has been set');\n if (this.endNameSet_) {\n return this.indexEndName_;\n } else {\n return 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 Object(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 /**\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 /**\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_ !== PriorityIndex[\"a\" /* 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_ == PriorityIndex[\"a\" /* PRIORITY_INDEX */];\n };\n /**\r\n * @return {!NodeFilter}\r\n */\n QueryParams.prototype.getNodeFilter = function () {\n if (this.loadsAllData()) {\n return new IndexedFilter[\"a\" /* 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_ === PriorityIndex[\"a\" /* PRIORITY_INDEX */]) {\n orderBy = REST_CONSTANTS.PRIORITY_INDEX;\n } else if (this.index_ === ValueIndex[\"a\" /* VALUE_INDEX */]) {\n orderBy = REST_CONSTANTS.VALUE_INDEX;\n } else if (this.index_ === KeyIndex[\"a\" /* KEY_INDEX */]) {\n orderBy = REST_CONSTANTS.KEY_INDEX;\n } else {\n Object(assert[\"a\" /* assert */])(this.index_ instanceof PathIndex[\"a\" /* PathIndex */], 'Unrecognized index type!');\n orderBy = this.index_.toString();\n }\n qs[REST_CONSTANTS.ORDER_BY] = Object(json[\"b\" /* stringify */])(orderBy);\n if (this.startSet_) {\n qs[REST_CONSTANTS.START_AT] = Object(json[\"b\" /* stringify */])(this.indexStartValue_);\n if (this.startNameSet_) {\n qs[REST_CONSTANTS.START_AT] += ',' + Object(json[\"b\" /* stringify */])(this.indexStartName_);\n }\n }\n if (this.endSet_) {\n qs[REST_CONSTANTS.END_AT] = Object(json[\"b\" /* stringify */])(this.indexEndValue_);\n if (this.endNameSet_) {\n qs[REST_CONSTANTS.END_AT] += ',' + Object(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 /**\r\n * Wire Protocol Constants\r\n * @const\r\n * @enum {string}\r\n * @private\r\n */\n 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 */\n 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 */\n QueryParams.DEFAULT = new QueryParams();\n return QueryParams;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/SyncPoint.ts + 7 modules\nvar SyncPoint = __webpack_require__(50);\n\n// CONCATENATED MODULE: ./src/database/api/Reference.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Reference_Reference; });\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 __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 = /** @class */function (_super) {\n __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[\"a\" /* 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 Object(validation[\"b\" /* 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 Object(validation[\"b\" /* validateArgCount */])('Reference.child', 1, 1, arguments.length);\n if (typeof pathString === 'number') {\n pathString = String(pathString);\n } else if (!(pathString instanceof Path[\"a\" /* Path */])) {\n if (this.path.getFront() === null) Object(util_validation[\"j\" /* validateRootPathString */])('Reference.child', 1, pathString, false);else Object(util_validation[\"h\" /* 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 Object(validation[\"b\" /* 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 Object(validation[\"b\" /* 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 Object(validation[\"b\" /* validateArgCount */])('Reference.set', 1, 2, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('Reference.set', this.path);\n Object(util_validation[\"e\" /* validateFirebaseDataArg */])('Reference.set', 1, newVal, this.path, false);\n Object(validation[\"c\" /* validateCallback */])('Reference.set', 2, onComplete, true);\n var deferred = new utils_promise[\"a\" /* Deferred */]();\n this.repo.setWithPriority(this.path, newVal,\n /*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 Object(validation[\"b\" /* validateArgCount */])('Reference.update', 1, 2, arguments.length);\n Object(util_validation[\"l\" /* 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 Object(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 Object(util_validation[\"f\" /* validateFirebaseMergeDataArg */])('Reference.update', 1, objectToMerge, this.path, false);\n Object(validation[\"c\" /* validateCallback */])('Reference.update', 2, onComplete, true);\n var deferred = new 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 Object(validation[\"b\" /* validateArgCount */])('Reference.setWithPriority', 2, 3, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('Reference.setWithPriority', this.path);\n Object(util_validation[\"e\" /* validateFirebaseDataArg */])('Reference.setWithPriority', 1, newVal, this.path, false);\n Object(util_validation[\"i\" /* validatePriority */])('Reference.setWithPriority', 2, newPriority, false);\n Object(validation[\"c\" /* 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 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 Object(validation[\"b\" /* validateArgCount */])('Reference.remove', 0, 1, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('Reference.remove', this.path);\n Object(validation[\"c\" /* 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 Object(validation[\"b\" /* validateArgCount */])('Reference.transaction', 1, 3, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('Reference.transaction', this.path);\n Object(validation[\"c\" /* validateCallback */])('Reference.transaction', 1, transactionUpdate, false);\n Object(validation[\"c\" /* 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 Object(util_validation[\"b\" /* 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 utils_promise[\"a\" /* Deferred */]();\n if (typeof onComplete === 'function') {\n Object(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_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 Object(validation[\"b\" /* validateArgCount */])('Reference.setPriority', 1, 2, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('Reference.setPriority', this.path);\n Object(util_validation[\"i\" /* validatePriority */])('Reference.setPriority', 1, priority, false);\n Object(validation[\"c\" /* validateCallback */])('Reference.setPriority', 2, onComplete, true);\n var deferred = new 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 Object(validation[\"b\" /* validateArgCount */])('Reference.push', 0, 2, arguments.length);\n Object(util_validation[\"l\" /* validateWritablePath */])('Reference.push', this.path);\n Object(util_validation[\"e\" /* validateFirebaseDataArg */])('Reference.push', 1, value, this.path, true);\n Object(validation[\"c\" /* 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 = 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 Object(utils_promise[\"c\" /* attachDummyErrorHandler */])(promise);\n }\n return thennablePushRef;\n };\n /**\r\n * @return {!OnDisconnect}\r\n */\n Reference.prototype.onDisconnect = function () {\n Object(util_validation[\"l\" /* 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[\"a\" /* 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[\"a\" /* Query */].__referenceConstructor = Reference_Reference;\nSyncPoint[\"a\" /* SyncPoint */].__referenceConstructor = Reference_Reference;\n\n/***/ }),\n/* 27 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return ImmutableTree; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__SortedMap__ = __webpack_require__(22);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util__ = __webpack_require__(1);\n/* harmony import */ var __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 */\n\n\n\n\nvar emptyChildrenSingleton;\n/**\r\n * Singleton empty children collection.\r\n *\r\n * @const\r\n * @type {!SortedMap.>}\r\n */\nvar EmptyChildren = function EmptyChildren() {\n if (!emptyChildrenSingleton) {\n emptyChildrenSingleton = new __WEBPACK_IMPORTED_MODULE_0__SortedMap__[\"b\" /* SortedMap */](__WEBPACK_IMPORTED_MODULE_2__util__[\"A\" /* stringCompare */]);\n }\n return emptyChildrenSingleton;\n};\n/**\r\n * A tree with immutable elements.\r\n */\nvar ImmutableTree = /** @class */function () {\n /**\r\n * @template T\r\n * @param {?T} value\r\n * @param {SortedMap.>=} children\r\n */\n function ImmutableTree(value, children) {\n if (children === void 0) {\n children = EmptyChildren();\n }\n this.value = value;\n this.children = children;\n }\n /**\r\n * @template T\r\n * @param {!Object.} obj\r\n * @return {!ImmutableTree.}\r\n */\n ImmutableTree.fromObject = function (obj) {\n var tree = ImmutableTree.Empty;\n Object(__WEBPACK_IMPORTED_MODULE_3__utils_obj__[\"f\" /* forEach */])(obj, function (childPath, childSnap) {\n tree = tree.set(new __WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */](childPath), childSnap);\n });\n return tree;\n };\n /**\r\n * True if the value is empty and there are no children\r\n * @return {boolean}\r\n */\n ImmutableTree.prototype.isEmpty = function () {\n return this.value === null && this.children.isEmpty();\n };\n /**\r\n * Given a path and predicate, return the first node and the path to that node\r\n * where the predicate returns true.\r\n *\r\n * TODO Do a perf test -- If we're creating a bunch of {path: value:} objects\r\n * on the way back out, it may be better to pass down a pathSoFar obj.\r\n *\r\n * @param {!Path} relativePath The remainder of the path\r\n * @param {function(T):boolean} predicate The predicate to satisfy to return a\r\n * node\r\n * @return {?{path:!Path, value:!T}}\r\n */\n ImmutableTree.prototype.findRootMostMatchingPathAndValue = function (relativePath, predicate) {\n if (this.value != null && predicate(this.value)) {\n return { path: __WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */].Empty, value: this.value };\n } else {\n if (relativePath.isEmpty()) {\n return null;\n } else {\n var front = relativePath.getFront();\n var child = this.children.get(front);\n if (child !== null) {\n var childExistingPathAndValue = child.findRootMostMatchingPathAndValue(relativePath.popFront(), predicate);\n if (childExistingPathAndValue != null) {\n var fullPath = new __WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* 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 /**\r\n * Find, if it exists, the shortest subpath of the given path that points a defined\r\n * value in the tree\r\n * @param {!Path} relativePath\r\n * @return {?{path: !Path, value: !T}}\r\n */\n ImmutableTree.prototype.findRootMostValueAndPath = function (relativePath) {\n return this.findRootMostMatchingPathAndValue(relativePath, function () {\n return true;\n });\n };\n /**\r\n * @param {!Path} relativePath\r\n * @return {!ImmutableTree.} The subtree at the given path\r\n */\n ImmutableTree.prototype.subtree = function (relativePath) {\n if (relativePath.isEmpty()) {\n return this;\n } else {\n var front = relativePath.getFront();\n var 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 /**\r\n * Sets a value at the specified path.\r\n *\r\n * @param {!Path} relativePath Path to set value at.\r\n * @param {?T} toSet Value to set.\r\n * @return {!ImmutableTree.} Resulting tree.\r\n */\n ImmutableTree.prototype.set = function (relativePath, toSet) {\n if (relativePath.isEmpty()) {\n return new ImmutableTree(toSet, this.children);\n } else {\n var front = relativePath.getFront();\n var child = this.children.get(front) || ImmutableTree.Empty;\n var newChild = child.set(relativePath.popFront(), toSet);\n var newChildren = this.children.insert(front, newChild);\n return new ImmutableTree(this.value, newChildren);\n }\n };\n /**\r\n * Removes the value at the specified path.\r\n *\r\n * @param {!Path} relativePath Path to value to remove.\r\n * @return {!ImmutableTree.} Resulting tree.\r\n */\n ImmutableTree.prototype.remove = function (relativePath) {\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 var front = relativePath.getFront();\n var child = this.children.get(front);\n if (child) {\n var newChild = child.remove(relativePath.popFront());\n var newChildren = void 0;\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 /**\r\n * Gets a value from the tree.\r\n *\r\n * @param {!Path} relativePath Path to get value for.\r\n * @return {?T} Value at path, or null.\r\n */\n ImmutableTree.prototype.get = function (relativePath) {\n if (relativePath.isEmpty()) {\n return this.value;\n } else {\n var front = relativePath.getFront();\n var child = this.children.get(front);\n if (child) {\n return child.get(relativePath.popFront());\n } else {\n return null;\n }\n }\n };\n /**\r\n * Replace the subtree at the specified path with the given new tree.\r\n *\r\n * @param {!Path} relativePath Path to replace subtree for.\r\n * @param {!ImmutableTree} newTree New tree.\r\n * @return {!ImmutableTree} Resulting tree.\r\n */\n ImmutableTree.prototype.setTree = function (relativePath, newTree) {\n if (relativePath.isEmpty()) {\n return newTree;\n } else {\n var front = relativePath.getFront();\n var child = this.children.get(front) || ImmutableTree.Empty;\n var newChild = child.setTree(relativePath.popFront(), newTree);\n var newChildren = void 0;\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 /**\r\n * Performs a depth first fold on this tree. Transforms a tree into a single\r\n * value, given a function that operates on the path to a node, an optional\r\n * current value, and a map of child names to folded subtrees\r\n * @template V\r\n * @param {function(Path, ?T, Object.):V} fn\r\n * @return {V}\r\n */\n ImmutableTree.prototype.fold = function (fn) {\n return this.fold_(__WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */].Empty, fn);\n };\n /**\r\n * Recursive helper for public-facing fold() method\r\n * @template V\r\n * @param {!Path} pathSoFar\r\n * @param {function(Path, ?T, Object.):V} fn\r\n * @return {V}\r\n * @private\r\n */\n ImmutableTree.prototype.fold_ = function (pathSoFar, fn) {\n var accum = {};\n this.children.inorderTraversal(function (childKey, childTree) {\n accum[childKey] = childTree.fold_(pathSoFar.child(childKey), fn);\n });\n return fn(pathSoFar, this.value, accum);\n };\n /**\r\n * Find the first matching value on the given path. Return the result of applying f to it.\r\n * @template V\r\n * @param {!Path} path\r\n * @param {!function(!Path, !T):?V} f\r\n * @return {?V}\r\n */\n ImmutableTree.prototype.findOnPath = function (path, f) {\n return this.findOnPath_(path, __WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */].Empty, f);\n };\n ImmutableTree.prototype.findOnPath_ = function (pathToFollow, pathSoFar, f) {\n var 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 var front = pathToFollow.getFront();\n var 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 /**\r\n *\r\n * @param {!Path} path\r\n * @param {!function(!Path, !T)} f\r\n * @returns {!ImmutableTree.}\r\n */\n ImmutableTree.prototype.foreachOnPath = function (path, f) {\n return this.foreachOnPath_(path, __WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */].Empty, f);\n };\n ImmutableTree.prototype.foreachOnPath_ = function (pathToFollow, currentRelativePath, f) {\n if (pathToFollow.isEmpty()) {\n return this;\n } else {\n if (this.value) {\n f(currentRelativePath, this.value);\n }\n var front = pathToFollow.getFront();\n var nextChild = this.children.get(front);\n if (nextChild) {\n return nextChild.foreachOnPath_(pathToFollow.popFront(), currentRelativePath.child(front), f);\n } else {\n return ImmutableTree.Empty;\n }\n }\n };\n /**\r\n * Calls the given function for each node in the tree that has a value.\r\n *\r\n * @param {function(!Path, !T)} f A function to be called with\r\n * the path from the root of the tree to a node, and the value at that node.\r\n * Called in depth-first order.\r\n */\n ImmutableTree.prototype.foreach = function (f) {\n this.foreach_(__WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */].Empty, f);\n };\n ImmutableTree.prototype.foreach_ = function (currentRelativePath, f) {\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 /**\r\n *\r\n * @param {function(string, !T)} f\r\n */\n ImmutableTree.prototype.foreachChild = function (f) {\n this.children.inorderTraversal(function (childName, childTree) {\n if (childTree.value) {\n f(childName, childTree.value);\n }\n });\n };\n ImmutableTree.Empty = new ImmutableTree(null);\n return ImmutableTree;\n}();\n\n\n/***/ }),\n/* 28 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return IndexedFilter; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Change__ = __webpack_require__(14);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__snap_ChildrenNode__ = __webpack_require__(6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__snap_indexes_PriorityIndex__ = __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/**\r\n * Doesn't really filter nodes but applies an index to the node and keeps track of any changes\r\n *\r\n * @constructor\r\n * @implements {NodeFilter}\r\n * @param {!Index} index\r\n */\nvar IndexedFilter = /** @class */function () {\n function IndexedFilter(index_) {\n this.index_ = index_;\n }\n IndexedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(snap.isIndexed(this.index_), 'A node must be indexed if only a child is updated');\n var 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 // 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 if (optChangeAccumulator != null) {\n if (newChild.isEmpty()) {\n if (snap.hasChild(key)) {\n optChangeAccumulator.trackChildChange(__WEBPACK_IMPORTED_MODULE_1__Change__[\"a\" /* Change */].childRemovedChange(key, oldChild));\n } else {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* 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(__WEBPACK_IMPORTED_MODULE_1__Change__[\"a\" /* Change */].childAddedChange(key, newChild));\n } else {\n optChangeAccumulator.trackChildChange(__WEBPACK_IMPORTED_MODULE_1__Change__[\"a\" /* 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 /**\r\n * @inheritDoc\r\n */\n IndexedFilter.prototype.updateFullNode = function (oldSnap, newSnap, optChangeAccumulator) {\n if (optChangeAccumulator != null) {\n if (!oldSnap.isLeafNode()) {\n oldSnap.forEachChild(__WEBPACK_IMPORTED_MODULE_3__snap_indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], function (key, childNode) {\n if (!newSnap.hasChild(key)) {\n optChangeAccumulator.trackChildChange(__WEBPACK_IMPORTED_MODULE_1__Change__[\"a\" /* Change */].childRemovedChange(key, childNode));\n }\n });\n }\n if (!newSnap.isLeafNode()) {\n newSnap.forEachChild(__WEBPACK_IMPORTED_MODULE_3__snap_indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], function (key, childNode) {\n if (oldSnap.hasChild(key)) {\n var oldChild = oldSnap.getImmediateChild(key);\n if (!oldChild.equals(childNode)) {\n optChangeAccumulator.trackChildChange(__WEBPACK_IMPORTED_MODULE_1__Change__[\"a\" /* Change */].childChangedChange(key, childNode, oldChild));\n }\n } else {\n optChangeAccumulator.trackChildChange(__WEBPACK_IMPORTED_MODULE_1__Change__[\"a\" /* Change */].childAddedChange(key, childNode));\n }\n });\n }\n }\n return newSnap.withIndex(this.index_);\n };\n /**\r\n * @inheritDoc\r\n */\n IndexedFilter.prototype.updatePriority = function (oldSnap, newPriority) {\n if (oldSnap.isEmpty()) {\n return __WEBPACK_IMPORTED_MODULE_2__snap_ChildrenNode__[\"a\" /* ChildrenNode */].EMPTY_NODE;\n } else {\n return oldSnap.updatePriority(newPriority);\n }\n };\n /**\r\n * @inheritDoc\r\n */\n IndexedFilter.prototype.filtersNodes = function () {\n return false;\n };\n /**\r\n * @inheritDoc\r\n */\n IndexedFilter.prototype.getIndexedFilter = function () {\n return this;\n };\n /**\r\n * @inheritDoc\r\n */\n IndexedFilter.prototype.getIndex = function () {\n return this.index_;\n };\n return IndexedFilter;\n}();\n\n\n/***/ }),\n/* 29 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/utils/deep_copy.ts\nvar deep_copy = __webpack_require__(35);\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar obj = __webpack_require__(2);\n\n// CONCATENATED MODULE: ./src/database/core/stats/StatsCollection.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 * Tracks a collection of stats.\r\n *\r\n * @constructor\r\n */\nvar StatsCollection_StatsCollection = /** @class */function () {\n function StatsCollection() {\n this.counters_ = {};\n }\n StatsCollection.prototype.incrementCounter = function (name, amount) {\n if (amount === void 0) {\n amount = 1;\n }\n if (!Object(obj[\"b\" /* contains */])(this.counters_, name)) this.counters_[name] = 0;\n this.counters_[name] += amount;\n };\n StatsCollection.prototype.get = function () {\n return Object(deep_copy[\"a\" /* deepCopy */])(this.counters_);\n };\n return StatsCollection;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/stats/StatsManager.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return StatsManager_StatsManager; });\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 StatsManager_StatsManager = /** @class */function () {\n function StatsManager() {}\n StatsManager.getCollection = function (repoInfo) {\n var hashString = repoInfo.toString();\n if (!this.collections_[hashString]) {\n this.collections_[hashString] = new StatsCollection_StatsCollection();\n }\n return this.collections_[hashString];\n };\n StatsManager.getOrCreateReporter = function (repoInfo, creatorFunction) {\n var hashString = repoInfo.toString();\n if (!this.reporters_[hashString]) {\n this.reporters_[hashString] = creatorFunction();\n }\n return this.reporters_[hashString];\n };\n StatsManager.collections_ = {};\n StatsManager.reporters_ = {};\n return StatsManager;\n}();\n\n\n/***/ }),\n/* 30 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar obj = __webpack_require__(2);\n\n// EXTERNAL MODULE: ./src/database/core/Repo.ts + 14 modules\nvar Repo = __webpack_require__(23);\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/database/core/util/libs/parser.ts\nvar parser = __webpack_require__(37);\n\n// EXTERNAL MODULE: ./src/database/core/util/validation.ts\nvar validation = __webpack_require__(11);\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// EXTERNAL MODULE: ./src/database/api/Reference.ts + 6 modules\nvar Reference = __webpack_require__(26);\n\n// EXTERNAL MODULE: ./src/database/api/DataSnapshot.ts\nvar DataSnapshot = __webpack_require__(46);\n\n// EXTERNAL MODULE: ./src/database/core/util/Path.ts\nvar Path = __webpack_require__(4);\n\n// CONCATENATED MODULE: ./src/database/core/util/Tree.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 * Node in a Tree.\r\n */\nvar TreeNode = /** @class */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 = /** @class */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[\"a\" /* Path */] ? pathObj : new Path[\"a\" /* Path */](pathObj);\n var child = this,\n next;\n while ((next = path.getFront()) !== null) {\n var childNode = Object(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 Object(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 Object(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[\"a\" /* 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 = Object(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// EXTERNAL MODULE: ./src/database/core/snap/indexes/PriorityIndex.ts\nvar PriorityIndex = __webpack_require__(5);\n\n// EXTERNAL MODULE: ./src/database/core/util/ServerValues.ts\nvar ServerValues = __webpack_require__(47);\n\n// EXTERNAL MODULE: ./src/database/core/snap/nodeFromJSON.ts\nvar nodeFromJSON = __webpack_require__(16);\n\n// EXTERNAL MODULE: ./src/database/core/snap/ChildrenNode.ts\nvar ChildrenNode = __webpack_require__(6);\n\n// CONCATENATED MODULE: ./src/database/core/Repo_transaction.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\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[\"a\" /* Repo */].MAX_TRANSACTION_RETRIES_ = 25;\n/**\r\n * Setup the transaction data structures\r\n * @private\r\n */\nRepo[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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: Object(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[\"a\" /* DataSnapshot */](transaction.currentInputSnapshot, new Reference[\"a\" /* Reference */](this, transaction.path), PriorityIndex[\"a\" /* PRIORITY_INDEX */]);\n transaction.onComplete(null, false, snapshot);\n }\n } else {\n Object(validation[\"d\" /* 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' : _typeof(newVal)) === 'object' && newVal !== null && Object(obj[\"b\" /* contains */])(newVal, '.priority')) {\n priorityForNode = Object(obj[\"l\" /* safeGet */])(newVal, '.priority');\n Object(assert[\"a\" /* assert */])(Object(validation[\"a\" /* 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[\"a\" /* ChildrenNode */].EMPTY_NODE;\n priorityForNode = currentNode.getPriority().val();\n }\n priorityForNode /** @type {null|number|string} */ = priorityForNode;\n var serverValues = this.generateServerValues();\n var newNodeUnresolved = Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(newVal, priorityForNode);\n var newNode = Object(ServerValues[\"b\" /* 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[\"a\" /* Repo */].prototype.getLatestState_ = function (path, excludeSets) {\n return this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) || ChildrenNode[\"a\" /* 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[\"a\" /* 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 Object(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[\"a\" /* 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 Object(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[\"a\" /* 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', {\n path: pathToSend.toString(),\n status: status\n });\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[\"a\" /* Reference */](_this, queue[i].path);\n var snapshot = new DataSnapshot[\"a\" /* DataSnapshot */](node, ref, PriorityIndex[\"a\" /* 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 Object(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 Object(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[\"a\" /* 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[\"a\" /* 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[\"a\" /* Path */].relativePath(path, transaction.path);\n var abortTransaction = false,\n abortReason = void 0;\n Object(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[\"a\" /* 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 Object(validation[\"d\" /* validateFirebaseData */])('transaction failed: Data returned ', newData, transaction.path);\n var newDataNode = Object(nodeFromJSON[\"a\" /* nodeFromJSON */])(newData);\n var hasExplicitPriority = (typeof newData === 'undefined' ? 'undefined' : _typeof(newData)) === 'object' && newData != null && Object(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 = Object(ServerValues[\"b\" /* 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[\"a\" /* Reference */](this, queue[i].path);\n // We set this field immediately, so it's safe to cast to an actual snapshot\n var lastInput /** @type {!Node} */ = queue[i].currentInputSnapshot;\n var snapshot = new DataSnapshot[\"a\" /* DataSnapshot */](lastInput, ref, PriorityIndex[\"a\" /* 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 Object(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[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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[\"a\" /* 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 Object(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 Object(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 Object(util[\"m\" /* exceptionGuard */])(callbacks[i]);\n }\n }\n};\n// CONCATENATED MODULE: ./src/database/core/RepoManager.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return RepoManager_RepoManager; });\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 = /** @class */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 appName in this.repos_) {\n for (var dbUrl in this.repos_[appName]) {\n this.repos_[appName][dbUrl].interrupt();\n }\n }\n };\n RepoManager.prototype.resume = function () {\n for (var appName in this.repos_) {\n for (var dbUrl in this.repos_[appName]) {\n this.repos_[appName][dbUrl].resume();\n }\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, url) {\n var dbUrl = url || app.options[DATABASE_URL_OPTION];\n if (dbUrl === undefined) {\n Object(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 = Object(parser[\"a\" /* parseRepoInfo */])(dbUrl);\n var repoInfo = parsedUrl.repoInfo;\n Object(validation[\"k\" /* validateUrl */])('Invalid Firebase Database URL', 1, parsedUrl);\n if (!parsedUrl.path.isEmpty()) {\n Object(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 var appRepos = Object(obj[\"l\" /* safeGet */])(this.repos_, repo.app.name);\n // This should never happen...\n if (!appRepos || Object(obj[\"l\" /* safeGet */])(appRepos, repo.repoInfo_.toURLString()) !== repo) {\n Object(util[\"o\" /* fatal */])(\"Database \" + repo.app.name + \"(\" + repo.repoInfo_ + \") has already been deleted.\");\n }\n repo.interrupt();\n delete appRepos[repo.repoInfo_.toURLString()];\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 appRepos = Object(obj[\"l\" /* safeGet */])(this.repos_, app.name);\n if (!appRepos) {\n appRepos = {};\n this.repos_[app.name] = appRepos;\n }\n var repo = Object(obj[\"l\" /* safeGet */])(appRepos, repoInfo.toURLString());\n if (repo) {\n Object(util[\"o\" /* fatal */])('Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.');\n }\n repo = new Repo[\"a\" /* Repo */](repoInfo, this.useRestClient_, app);\n appRepos[repoInfo.toURLString()] = 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\n/***/ }),\n/* 31 */,\n/* 32 */,\n/* 33 */,\n/* 34 */,\n/* 35 */,\n/* 36 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Database; });\n/* unused harmony export DatabaseInternals */\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_util_libs_parser__ = __webpack_require__(37);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util_Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_promise__ = __webpack_require__(3);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Reference__ = __webpack_require__(26);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__core_Repo__ = __webpack_require__(23);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_RepoManager__ = __webpack_require__(30);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__utils_validation__ = __webpack_require__(10);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__core_util_validation__ = __webpack_require__(11);\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 = /** @class */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 __WEBPACK_IMPORTED_MODULE_5__core_Repo__[\"a\" /* Repo */])) {\n Object(__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 __WEBPACK_IMPORTED_MODULE_4__Reference__[\"a\" /* Reference */](repo_, __WEBPACK_IMPORTED_MODULE_2__core_util_Path__[\"a\" /* Path */].Empty);\n this.INTERNAL = new 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 Object(__WEBPACK_IMPORTED_MODULE_7__utils_validation__[\"b\" /* 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 Object(__WEBPACK_IMPORTED_MODULE_7__utils_validation__[\"b\" /* validateArgCount */])(apiName, 1, 1, arguments.length);\n var parsedURL = Object(__WEBPACK_IMPORTED_MODULE_1__core_util_libs_parser__[\"a\" /* parseRepoInfo */])(url);\n Object(__WEBPACK_IMPORTED_MODULE_8__core_util_validation__[\"k\" /* validateUrl */])(apiName, 1, parsedURL);\n var repoInfo = parsedURL.repoInfo;\n if (repoInfo.host !== this.repo_.repoInfo_.host) {\n Object(__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 Object(__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 Object(__WEBPACK_IMPORTED_MODULE_7__utils_validation__[\"b\" /* validateArgCount */])('database.goOffline', 0, 0, arguments.length);\n this.checkDeleted_('goOffline');\n this.repo_.interrupt();\n };\n Database.prototype.goOnline = function () {\n Object(__WEBPACK_IMPORTED_MODULE_7__utils_validation__[\"b\" /* validateArgCount */])('database.goOnline', 0, 0, arguments.length);\n this.checkDeleted_('goOnline');\n this.repo_.resume();\n };\n Database.ServerValue = {\n TIMESTAMP: {\n '.sv': 'timestamp'\n }\n };\n return Database;\n}();\n\nvar DatabaseInternals = /** @class */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 __WEBPACK_IMPORTED_MODULE_6__core_RepoManager__[\"a\" /* 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 __WEBPACK_IMPORTED_MODULE_3__utils_promise__[\"b\" /* PromiseImpl */].resolve();\n };\n return DatabaseInternals;\n}();\n\n\n/***/ }),\n/* 37 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return parseRepoInfo; });\n/* unused harmony export parseURL */\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__RepoInfo__ = __webpack_require__(38);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__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 * @param {!string} pathString\r\n * @return {string}\r\n */\nfunction decodePath(pathString) {\n var pathStringDecoded = '';\n var pieces = pathString.split('/');\n for (var i = 0; i < pieces.length; i++) {\n if (pieces[i].length > 0) {\n var piece = pieces[i];\n try {\n piece = decodeURIComponent(piece.replace(/\\+/g, ' '));\n } catch (e) {}\n pathStringDecoded += '/' + piece;\n }\n }\n return pathStringDecoded;\n}\n/**\r\n *\r\n * @param {!string} dataURL\r\n * @return {{repoInfo: !RepoInfo, path: !Path}}\r\n */\nvar parseRepoInfo = function parseRepoInfo(dataURL) {\n var parsedUrl = parseURL(dataURL),\n namespace = parsedUrl.subdomain;\n if (parsedUrl.domain === 'firebase') {\n Object(__WEBPACK_IMPORTED_MODULE_2__util__[\"o\" /* fatal */])(parsedUrl.host + ' is no longer supported. ' + 'Please use .firebaseio.com instead');\n }\n // Catch common error of uninitialized namespace value.\n if (!namespace || namespace == 'undefined') {\n Object(__WEBPACK_IMPORTED_MODULE_2__util__[\"o\" /* fatal */])('Cannot parse Firebase url. Please use https://.firebaseio.com');\n }\n if (!parsedUrl.secure) {\n Object(__WEBPACK_IMPORTED_MODULE_2__util__[\"C\" /* warnIfPageIsSecure */])();\n }\n var webSocketOnly = parsedUrl.scheme === 'ws' || parsedUrl.scheme === 'wss';\n return {\n repoInfo: new __WEBPACK_IMPORTED_MODULE_1__RepoInfo__[\"a\" /* RepoInfo */](parsedUrl.host, parsedUrl.secure, namespace, webSocketOnly),\n path: new __WEBPACK_IMPORTED_MODULE_0__Path__[\"a\" /* Path */](parsedUrl.pathString)\n };\n};\n/**\r\n *\r\n * @param {!string} dataURL\r\n * @return {{host: string, port: number, domain: string, subdomain: string, secure: boolean, scheme: string, pathString: string}}\r\n */\nvar parseURL = function parseURL(dataURL) {\n // Default to empty strings in the event of a malformed string.\n var host = '',\n domain = '',\n subdomain = '',\n pathString = '';\n // Always default to SSL, unless otherwise specified.\n var secure = true,\n scheme = 'https',\n port = 443;\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 var colonInd = dataURL.indexOf('//');\n if (colonInd >= 0) {\n scheme = dataURL.substring(0, colonInd - 1);\n dataURL = dataURL.substring(colonInd + 2);\n }\n // Parse host and path.\n var 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 var 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 // 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 return {\n host: host,\n port: port,\n domain: domain,\n subdomain: subdomain,\n secure: secure,\n scheme: scheme,\n pathString: pathString\n };\n};\n\n/***/ }),\n/* 38 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return RepoInfo; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__storage_storage__ = __webpack_require__(18);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__realtime_Constants__ = __webpack_require__(19);\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\n\n\n\n/**\r\n * A class that holds metadata about a Repo object\r\n *\r\n * @constructor\r\n */\nvar RepoInfo = /** @class */function () {\n /**\r\n * @param {string} host Hostname portion of the url for the repo\r\n * @param {boolean} secure Whether or not this repo is accessed over ssl\r\n * @param {string} namespace The namespace represented by the repo\r\n * @param {boolean} webSocketOnly Whether to prefer websockets over all other transports (used by Nest).\r\n * @param {string=} persistenceKey Override the default session persistence storage key\r\n */\n function RepoInfo(host, secure, namespace, webSocketOnly, persistenceKey) {\n if (persistenceKey === void 0) {\n persistenceKey = '';\n }\n this.secure = secure;\n this.namespace = namespace;\n this.webSocketOnly = webSocketOnly;\n this.persistenceKey = persistenceKey;\n this.host = host.toLowerCase();\n this.domain = this.host.substr(this.host.indexOf('.') + 1);\n this.internalHost = __WEBPACK_IMPORTED_MODULE_2__storage_storage__[\"a\" /* PersistentStorage */].get('host:' + host) || this.host;\n }\n RepoInfo.prototype.needsQueryParam = function () {\n return this.host !== this.internalHost;\n };\n RepoInfo.prototype.isCacheableHost = function () {\n return this.internalHost.substr(0, 2) === 's-';\n };\n RepoInfo.prototype.isDemoHost = function () {\n return this.domain === 'firebaseio-demo.com';\n };\n RepoInfo.prototype.isCustomHost = function () {\n return this.domain !== 'firebaseio.com' && this.domain !== 'firebaseio-demo.com';\n };\n RepoInfo.prototype.updateHost = function (newHost) {\n if (newHost !== this.internalHost) {\n this.internalHost = newHost;\n if (this.isCacheableHost()) {\n __WEBPACK_IMPORTED_MODULE_2__storage_storage__[\"a\" /* PersistentStorage */].set('host:' + this.host, this.internalHost);\n }\n }\n };\n /**\r\n * Returns the websocket URL for this repo\r\n * @param {string} type of connection\r\n * @param {Object} params list\r\n * @return {string} The URL for this repo\r\n */\n RepoInfo.prototype.connectionURL = function (type, params) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(typeof type === 'string', 'typeof type must == string');\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])((typeof params === 'undefined' ? 'undefined' : _typeof(params)) === 'object', 'typeof params must == object');\n var connURL;\n if (type === __WEBPACK_IMPORTED_MODULE_3__realtime_Constants__[\"i\" /* WEBSOCKET */]) {\n connURL = (this.secure ? 'wss://' : 'ws://') + this.internalHost + '/.ws?';\n } else if (type === __WEBPACK_IMPORTED_MODULE_3__realtime_Constants__[\"d\" /* 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 var pairs = [];\n Object(__WEBPACK_IMPORTED_MODULE_1__utils_obj__[\"f\" /* forEach */])(params, function (key, value) {\n pairs.push(key + '=' + value);\n });\n return connURL + pairs.join('&');\n };\n /** @return {string} */\n RepoInfo.prototype.toString = function () {\n var str = this.toURLString();\n if (this.persistenceKey) {\n str += '<' + this.persistenceKey + '>';\n }\n return str;\n };\n /** @return {string} */\n RepoInfo.prototype.toURLString = function () {\n return (this.secure ? 'https://' : 'http://') + this.host;\n };\n return RepoInfo;\n}();\n\n\n/***/ }),\n/* 39 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/KeyIndex.ts\nvar KeyIndex = __webpack_require__(15);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/PriorityIndex.ts\nvar PriorityIndex = __webpack_require__(5);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/ValueIndex.ts\nvar ValueIndex = __webpack_require__(41);\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/PathIndex.ts\nvar PathIndex = __webpack_require__(45);\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/database/core/util/Path.ts\nvar Path = __webpack_require__(4);\n\n// EXTERNAL MODULE: ./src/database/core/util/validation.ts\nvar validation = __webpack_require__(11);\n\n// EXTERNAL MODULE: ./src/utils/validation.ts\nvar utils_validation = __webpack_require__(10);\n\n// EXTERNAL MODULE: ./src/database/api/DataSnapshot.ts\nvar DataSnapshot = __webpack_require__(46);\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// CONCATENATED MODULE: ./src/database/core/view/Event.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 * Encapsulates the data needed to raise an event\r\n * @implements {Event}\r\n */\nvar Event_DataEvent = /** @class */function () {\n /**\r\n * @param {!string} eventType One of: value, child_added, child_changed, child_moved, child_removed\r\n * @param {!EventRegistration} eventRegistration The function to call to with the event data. User provided\r\n * @param {!DataSnapshot} snapshot The data backing the event\r\n * @param {?string=} prevName Optional, the name of the previous child for child_* events.\r\n */\n function DataEvent(eventType, eventRegistration, snapshot, prevName) {\n this.eventType = eventType;\n this.eventRegistration = eventRegistration;\n this.snapshot = snapshot;\n this.prevName = prevName;\n }\n /**\r\n * @inheritDoc\r\n */\n DataEvent.prototype.getPath = function () {\n var ref = this.snapshot.getRef();\n if (this.eventType === 'value') {\n return ref.path;\n } else {\n return ref.getParent().path;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n DataEvent.prototype.getEventType = function () {\n return this.eventType;\n };\n /**\r\n * @inheritDoc\r\n */\n DataEvent.prototype.getEventRunner = function () {\n return this.eventRegistration.getEventRunner(this);\n };\n /**\r\n * @inheritDoc\r\n */\n DataEvent.prototype.toString = function () {\n return this.getPath().toString() + ':' + this.eventType + ':' + Object(json[\"b\" /* stringify */])(this.snapshot.exportVal());\n };\n return DataEvent;\n}();\n\nvar CancelEvent = /** @class */function () {\n /**\r\n * @param {EventRegistration} eventRegistration\r\n * @param {Error} error\r\n * @param {!Path} path\r\n */\n function CancelEvent(eventRegistration, error, path) {\n this.eventRegistration = eventRegistration;\n this.error = error;\n this.path = path;\n }\n /**\r\n * @inheritDoc\r\n */\n CancelEvent.prototype.getPath = function () {\n return this.path;\n };\n /**\r\n * @inheritDoc\r\n */\n CancelEvent.prototype.getEventType = function () {\n return 'cancel';\n };\n /**\r\n * @inheritDoc\r\n */\n CancelEvent.prototype.getEventRunner = function () {\n return this.eventRegistration.getEventRunner(this);\n };\n /**\r\n * @inheritDoc\r\n */\n CancelEvent.prototype.toString = function () {\n return this.path.toString() + ':cancel';\n };\n return CancelEvent;\n}();\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar utils_obj = __webpack_require__(2);\n\n// CONCATENATED MODULE: ./src/database/core/view/EventRegistration.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 * Represents registration for 'value' events.\r\n */\nvar EventRegistration_ValueEventRegistration = /** @class */function () {\n /**\r\n * @param {?function(!DataSnapshot)} callback_\r\n * @param {?function(Error)} cancelCallback_\r\n * @param {?Object} context_\r\n */\n function ValueEventRegistration(callback_, cancelCallback_, context_) {\n this.callback_ = callback_;\n this.cancelCallback_ = cancelCallback_;\n this.context_ = context_;\n }\n /**\r\n * @inheritDoc\r\n */\n ValueEventRegistration.prototype.respondsTo = function (eventType) {\n return eventType === 'value';\n };\n /**\r\n * @inheritDoc\r\n */\n ValueEventRegistration.prototype.createEvent = function (change, query) {\n var index = query.getQueryParams().getIndex();\n return new Event_DataEvent('value', this, new DataSnapshot[\"a\" /* DataSnapshot */](change.snapshotNode, query.getRef(), index));\n };\n /**\r\n * @inheritDoc\r\n */\n ValueEventRegistration.prototype.getEventRunner = function (eventData) {\n var ctx = this.context_;\n if (eventData.getEventType() === 'cancel') {\n Object(assert[\"a\" /* assert */])(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback');\n var cancelCB_1 = this.cancelCallback_;\n return function () {\n // We know that error exists, we checked above that this is a cancel event\n cancelCB_1.call(ctx, eventData.error);\n };\n } else {\n var cb_1 = this.callback_;\n return function () {\n cb_1.call(ctx, eventData.snapshot);\n };\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ValueEventRegistration.prototype.createCancelEvent = function (error, path) {\n if (this.cancelCallback_) {\n return new CancelEvent(this, error, path);\n } else {\n return null;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ValueEventRegistration.prototype.matches = function (other) {\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 /**\r\n * @inheritDoc\r\n */\n ValueEventRegistration.prototype.hasAnyCallback = function () {\n return this.callback_ !== null;\n };\n return ValueEventRegistration;\n}();\n\n/**\r\n * Represents the registration of 1 or more child_xxx events.\r\n *\r\n * Currently, it is always exactly 1 child_xxx event, but the idea is we might let you\r\n * register a group of callbacks together in the future.\r\n *\r\n * @constructor\r\n * @implements {EventRegistration}\r\n */\nvar EventRegistration_ChildEventRegistration = /** @class */function () {\n /**\r\n * @param {?Object.} callbacks_\r\n * @param {?function(Error)} cancelCallback_\r\n * @param {Object=} context_\r\n */\n function ChildEventRegistration(callbacks_, cancelCallback_, context_) {\n this.callbacks_ = callbacks_;\n this.cancelCallback_ = cancelCallback_;\n this.context_ = context_;\n }\n /**\r\n * @inheritDoc\r\n */\n ChildEventRegistration.prototype.respondsTo = function (eventType) {\n var eventToCheck = eventType === 'children_added' ? 'child_added' : eventType;\n eventToCheck = eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;\n return Object(utils_obj[\"b\" /* contains */])(this.callbacks_, eventToCheck);\n };\n /**\r\n * @inheritDoc\r\n */\n ChildEventRegistration.prototype.createCancelEvent = function (error, path) {\n if (this.cancelCallback_) {\n return new CancelEvent(this, error, path);\n } else {\n return null;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ChildEventRegistration.prototype.createEvent = function (change, query) {\n Object(assert[\"a\" /* assert */])(change.childName != null, 'Child events should have a childName.');\n var ref = query.getRef().child /** @type {!string} */(change.childName);\n var index = query.getQueryParams().getIndex();\n return new Event_DataEvent(change.type, this, new DataSnapshot[\"a\" /* DataSnapshot */](change.snapshotNode, ref, index), change.prevName);\n };\n /**\r\n * @inheritDoc\r\n */\n ChildEventRegistration.prototype.getEventRunner = function (eventData) {\n var ctx = this.context_;\n if (eventData.getEventType() === 'cancel') {\n Object(assert[\"a\" /* assert */])(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback');\n var cancelCB_2 = this.cancelCallback_;\n return function () {\n // We know that error exists, we checked above that this is a cancel event\n cancelCB_2.call(ctx, eventData.error);\n };\n } else {\n var cb_2 = this.callbacks_[eventData.eventType];\n return function () {\n cb_2.call(ctx, eventData.snapshot, eventData.prevName);\n };\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ChildEventRegistration.prototype.matches = function (other) {\n if (other instanceof ChildEventRegistration) {\n if (!this.callbacks_ || !other.callbacks_) {\n return true;\n } else if (this.context_ === other.context_) {\n var otherCount = Object(utils_obj[\"h\" /* getCount */])(other.callbacks_);\n var thisCount = Object(utils_obj[\"h\" /* 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 if (otherCount === 1) {\n var otherKey /** @type {!string} */ = Object(utils_obj[\"g\" /* getAnyKey */])(other.callbacks_);\n var thisKey /** @type {!string} */ = Object(utils_obj[\"g\" /* getAnyKey */])(this.callbacks_);\n return thisKey === otherKey && (!other.callbacks_[otherKey] || !this.callbacks_[thisKey] || other.callbacks_[otherKey] === this.callbacks_[thisKey]);\n } else {\n // Exact match on each key.\n return Object(utils_obj[\"c\" /* every */])(this.callbacks_, function (eventType, cb) {\n return other.callbacks_[eventType] === cb;\n });\n }\n }\n }\n }\n return false;\n };\n /**\r\n * @inheritDoc\r\n */\n ChildEventRegistration.prototype.hasAnyCallback = function () {\n return this.callbacks_ !== null;\n };\n return ChildEventRegistration;\n}();\n\n// EXTERNAL MODULE: ./src/utils/promise.ts\nvar promise = __webpack_require__(3);\n\n// CONCATENATED MODULE: ./src/database/api/Query.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Query_Query; });\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\n\n\n\n\n\n\n\n\n\n\nvar __referenceConstructor;\n/**\r\n * A Query represents a filter to be applied to a firebase location. This object purely represents the\r\n * query expression (and exposes our public API to build the query). The actual query logic is in ViewBase.js.\r\n *\r\n * Since every Firebase reference is a query, Firebase inherits from this object.\r\n */\nvar Query_Query = /** @class */function () {\n function Query(repo, path, queryParams_, orderByCalled_) {\n this.repo = repo;\n this.path = path;\n this.queryParams_ = queryParams_;\n this.orderByCalled_ = orderByCalled_;\n }\n Object.defineProperty(Query, \"__referenceConstructor\", {\n get: function get() {\n Object(assert[\"a\" /* assert */])(__referenceConstructor, 'Reference.ts has not been loaded');\n return __referenceConstructor;\n },\n set: function set(val) {\n __referenceConstructor = val;\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * Validates start/end values for queries.\r\n * @param {!QueryParams} params\r\n * @private\r\n */\n Query.validateQueryEndpoints_ = function (params) {\n var startNode = null;\n var endNode = null;\n if (params.hasStart()) {\n startNode = params.getIndexStartValue();\n }\n if (params.hasEnd()) {\n endNode = params.getIndexEndValue();\n }\n if (params.getIndex() === KeyIndex[\"a\" /* KEY_INDEX */]) {\n var tooManyArgsError = 'Query: When ordering by key, you may only pass one argument to ' + 'startAt(), endAt(), or equalTo().';\n var wrongArgTypeError = 'Query: When ordering by key, the argument passed to startAt(), endAt(),' + 'or equalTo() must be a string.';\n if (params.hasStart()) {\n var startName = params.getIndexStartName();\n if (startName != util[\"c\" /* 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 var endName = params.getIndexEndName();\n if (endName != util[\"b\" /* MAX_NAME */]) {\n throw new Error(tooManyArgsError);\n } else if (typeof endNode !== 'string') {\n throw new Error(wrongArgTypeError);\n }\n }\n } else if (params.getIndex() === PriorityIndex[\"a\" /* PRIORITY_INDEX */]) {\n if (startNode != null && !Object(validation[\"a\" /* isValidPriority */])(startNode) || endNode != null && !Object(validation[\"a\" /* isValidPriority */])(endNode)) {\n throw new Error('Query: When ordering by priority, the first argument passed to startAt(), ' + 'endAt(), or equalTo() must be a valid priority value (null, a number, or a string).');\n }\n } else {\n Object(assert[\"a\" /* assert */])(params.getIndex() instanceof PathIndex[\"a\" /* PathIndex */] || params.getIndex() === ValueIndex[\"a\" /* VALUE_INDEX */], 'unknown index type.');\n if (startNode != null && (typeof startNode === 'undefined' ? 'undefined' : _typeof(startNode)) === 'object' || endNode != null && (typeof endNode === 'undefined' ? 'undefined' : _typeof(endNode)) === 'object') {\n throw new Error('Query: First argument passed to startAt(), endAt(), or equalTo() cannot be ' + 'an object.');\n }\n }\n };\n /**\r\n * Validates that limit* has been called with the correct combination of parameters\r\n * @param {!QueryParams} params\r\n * @private\r\n */\n Query.validateLimit_ = function (params) {\n if (params.hasStart() && params.hasEnd() && params.hasLimit() && !params.hasAnchoredLimit()) {\n throw new Error(\"Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.\");\n }\n };\n /**\r\n * Validates that no other order by call has been made\r\n * @param {!string} fnName\r\n * @private\r\n */\n Query.prototype.validateNoPreviousOrderByCall_ = function (fnName) {\n if (this.orderByCalled_ === true) {\n throw new Error(fnName + \": You can't combine multiple orderBy calls.\");\n }\n };\n /**\r\n * @return {!QueryParams}\r\n */\n Query.prototype.getQueryParams = function () {\n return this.queryParams_;\n };\n /**\r\n * @return {!Reference}\r\n */\n Query.prototype.getRef = function () {\n Object(utils_validation[\"b\" /* 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);\n };\n /**\r\n * @param {!string} eventType\r\n * @param {!function(DataSnapshot, string=)} callback\r\n * @param {(function(Error)|Object)=} cancelCallbackOrContext\r\n * @param {Object=} context\r\n * @return {!function(DataSnapshot, string=)}\r\n */\n Query.prototype.on = function (eventType, callback, cancelCallbackOrContext, context) {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.on', 2, 4, arguments.length);\n Object(validation[\"c\" /* validateEventType */])('Query.on', 1, eventType, false);\n Object(utils_validation[\"c\" /* validateCallback */])('Query.on', 2, callback, false);\n var ret = Query.getCancelAndContextArgs_('Query.on', cancelCallbackOrContext, context);\n if (eventType === 'value') {\n this.onValueEvent(callback, ret.cancel, ret.context);\n } else {\n var callbacks = {};\n callbacks[eventType] = callback;\n this.onChildEvent(callbacks, ret.cancel, ret.context);\n }\n return callback;\n };\n /**\r\n * @param {!function(!DataSnapshot)} callback\r\n * @param {?function(Error)} cancelCallback\r\n * @param {?Object} context\r\n * @protected\r\n */\n Query.prototype.onValueEvent = function (callback, cancelCallback, context) {\n var container = new EventRegistration_ValueEventRegistration(callback, cancelCallback || null, context || null);\n this.repo.addEventCallbackForQuery(this, container);\n };\n /**\r\n * @param {!Object.} callbacks\r\n * @param {?function(Error)} cancelCallback\r\n * @param {?Object} context\r\n * @protected\r\n */\n Query.prototype.onChildEvent = function (callbacks, cancelCallback, context) {\n var container = new EventRegistration_ChildEventRegistration(callbacks, cancelCallback, context);\n this.repo.addEventCallbackForQuery(this, container);\n };\n /**\r\n * @param {string=} eventType\r\n * @param {(function(!DataSnapshot, ?string=))=} callback\r\n * @param {Object=} context\r\n */\n Query.prototype.off = function (eventType, callback, context) {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.off', 0, 3, arguments.length);\n Object(validation[\"c\" /* validateEventType */])('Query.off', 1, eventType, true);\n Object(utils_validation[\"c\" /* validateCallback */])('Query.off', 2, callback, true);\n Object(utils_validation[\"d\" /* validateContextObject */])('Query.off', 3, context, true);\n var container = null;\n var callbacks = null;\n if (eventType === 'value') {\n var valueCallback = callback || null;\n container = new EventRegistration_ValueEventRegistration(valueCallback, null, context || null);\n } else if (eventType) {\n if (callback) {\n callbacks = {};\n callbacks[eventType] = callback;\n }\n container = new EventRegistration_ChildEventRegistration(callbacks, null, context || null);\n }\n this.repo.removeEventCallbackForQuery(this, container);\n };\n /**\r\n * Attaches a listener, waits for the first event, and then removes the listener\r\n * @param {!string} eventType\r\n * @param {!function(!DataSnapshot, string=)} userCallback\r\n * @param cancelOrContext\r\n * @param context\r\n * @return {!firebase.Promise}\r\n */\n Query.prototype.once = function (eventType, userCallback, cancelOrContext, context) {\n var _this = this;\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.once', 1, 4, arguments.length);\n Object(validation[\"c\" /* validateEventType */])('Query.once', 1, eventType, false);\n Object(utils_validation[\"c\" /* validateCallback */])('Query.once', 2, userCallback, true);\n var ret = Query.getCancelAndContextArgs_('Query.once', cancelOrContext, context);\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 var firstCall = true;\n var deferred = new promise[\"a\" /* Deferred */]();\n Object(promise[\"c\" /* attachDummyErrorHandler */])(deferred.promise);\n var onceCallback = function onceCallback(snapshot) {\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 if (userCallback) {\n userCallback.bind(ret.context)(snapshot);\n }\n deferred.resolve(snapshot);\n }\n };\n this.on(eventType, onceCallback,\n /*cancel=*/function (err) {\n _this.off(eventType, onceCallback);\n if (ret.cancel) ret.cancel.bind(ret.context)(err);\n deferred.reject(err);\n });\n return deferred.promise;\n };\n /**\r\n * Set a limit and anchor it to the start of the window.\r\n * @param {!number} limit\r\n * @return {!Query}\r\n */\n Query.prototype.limitToFirst = function (limit) {\n Object(utils_validation[\"b\" /* 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, ' + 'limitToFirst, or limitToLast).');\n }\n return new Query(this.repo, this.path, this.queryParams_.limitToFirst(limit), this.orderByCalled_);\n };\n /**\r\n * Set a limit and anchor it to the end of the window.\r\n * @param {!number} limit\r\n * @return {!Query}\r\n */\n Query.prototype.limitToLast = function (limit) {\n Object(utils_validation[\"b\" /* 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, ' + 'limitToFirst, or limitToLast).');\n }\n return new Query(this.repo, this.path, this.queryParams_.limitToLast(limit), this.orderByCalled_);\n };\n /**\r\n * Given a child path, return a new query ordered by the specified grandchild path.\r\n * @param {!string} path\r\n * @return {!Query}\r\n */\n Query.prototype.orderByChild = function (path) {\n Object(utils_validation[\"b\" /* 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 Object(validation[\"h\" /* validatePathString */])('Query.orderByChild', 1, path, false);\n this.validateNoPreviousOrderByCall_('Query.orderByChild');\n var parsedPath = new Path[\"a\" /* Path */](path);\n if (parsedPath.isEmpty()) {\n throw new Error('Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.');\n }\n var index = new PathIndex[\"a\" /* PathIndex */](parsedPath);\n var newParams = this.queryParams_.orderBy(index);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n };\n /**\r\n * Return a new query ordered by the KeyIndex\r\n * @return {!Query}\r\n */\n Query.prototype.orderByKey = function () {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.orderByKey', 0, 0, arguments.length);\n this.validateNoPreviousOrderByCall_('Query.orderByKey');\n var newParams = this.queryParams_.orderBy(KeyIndex[\"a\" /* KEY_INDEX */]);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n };\n /**\r\n * Return a new query ordered by the PriorityIndex\r\n * @return {!Query}\r\n */\n Query.prototype.orderByPriority = function () {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.orderByPriority', 0, 0, arguments.length);\n this.validateNoPreviousOrderByCall_('Query.orderByPriority');\n var newParams = this.queryParams_.orderBy(PriorityIndex[\"a\" /* PRIORITY_INDEX */]);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n };\n /**\r\n * Return a new query ordered by the ValueIndex\r\n * @return {!Query}\r\n */\n Query.prototype.orderByValue = function () {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.orderByValue', 0, 0, arguments.length);\n this.validateNoPreviousOrderByCall_('Query.orderByValue');\n var newParams = this.queryParams_.orderBy(ValueIndex[\"a\" /* VALUE_INDEX */]);\n Query.validateQueryEndpoints_(newParams);\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/true);\n };\n /**\r\n * @param {number|string|boolean|null} value\r\n * @param {?string=} name\r\n * @return {!Query}\r\n */\n Query.prototype.startAt = function (value, name) {\n if (value === void 0) {\n value = null;\n }\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.startAt', 0, 2, arguments.length);\n Object(validation[\"e\" /* validateFirebaseDataArg */])('Query.startAt', 1, value, this.path, true);\n Object(validation[\"g\" /* validateKey */])('Query.startAt', 2, name, true);\n var 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 ' + 'or equalTo).');\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 /**\r\n * @param {number|string|boolean|null} value\r\n * @param {?string=} name\r\n * @return {!Query}\r\n */\n Query.prototype.endAt = function (value, name) {\n if (value === void 0) {\n value = null;\n }\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.endAt', 0, 2, arguments.length);\n Object(validation[\"e\" /* validateFirebaseDataArg */])('Query.endAt', 1, value, this.path, true);\n Object(validation[\"g\" /* validateKey */])('Query.endAt', 2, name, true);\n var 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 ' + 'equalTo).');\n }\n return new Query(this.repo, this.path, newParams, this.orderByCalled_);\n };\n /**\r\n * Load the selection of children with exactly the specified value, and, optionally,\r\n * the specified name.\r\n * @param {number|string|boolean|null} value\r\n * @param {string=} name\r\n * @return {!Query}\r\n */\n Query.prototype.equalTo = function (value, name) {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.equalTo', 1, 2, arguments.length);\n Object(validation[\"e\" /* validateFirebaseDataArg */])('Query.equalTo', 1, value, this.path, false);\n Object(validation[\"g\" /* 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 ' + 'equalTo).');\n }\n if (this.queryParams_.hasEnd()) {\n throw new Error('Query.equalTo: Ending point was already set (by another call to endAt or ' + 'equalTo).');\n }\n return this.startAt(value, name).endAt(value, name);\n };\n /**\r\n * @return {!string} URL for this location.\r\n */\n Query.prototype.toString = function () {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.toString', 0, 0, arguments.length);\n return this.repo.toString() + this.path.toUrlEncodedString();\n };\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n // for end-users.\n Query.prototype.toJSON = function () {\n // An optional spacer argument is unnecessary for a string.\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.toJSON', 0, 1, arguments.length);\n return this.toString();\n };\n /**\r\n * An object representation of the query parameters used by this Query.\r\n * @return {!Object}\r\n */\n Query.prototype.queryObject = function () {\n return this.queryParams_.getQueryObject();\n };\n /**\r\n * @return {!string}\r\n */\n Query.prototype.queryIdentifier = function () {\n var obj = this.queryObject();\n var id = Object(util[\"d\" /* ObjectToUniqueKey */])(obj);\n return id === '{}' ? 'default' : id;\n };\n /**\r\n * Return true if this query and the provided query are equivalent; otherwise, return false.\r\n * @param {Query} other\r\n * @return {boolean}\r\n */\n Query.prototype.isEqual = function (other) {\n Object(utils_validation[\"b\" /* validateArgCount */])('Query.isEqual', 1, 1, arguments.length);\n if (!(other instanceof Query)) {\n var error = 'Query.isEqual failed: First argument must be an instance of firebase.database.Query.';\n throw new Error(error);\n }\n var sameRepo = this.repo === other.repo;\n var samePath = this.path.equals(other.path);\n var sameQueryIdentifier = this.queryIdentifier() === other.queryIdentifier();\n return sameRepo && samePath && sameQueryIdentifier;\n };\n /**\r\n * Helper used by .on and .once to extract the context and or cancel arguments.\r\n * @param {!string} fnName The function name (on or once)\r\n * @param {(function(Error)|Object)=} cancelOrContext\r\n * @param {Object=} context\r\n * @return {{cancel: ?function(Error), context: ?Object}}\r\n * @private\r\n */\n Query.getCancelAndContextArgs_ = function (fnName, cancelOrContext, context) {\n var ret = { cancel: null, context: null };\n if (cancelOrContext && context) {\n ret.cancel = cancelOrContext;\n Object(utils_validation[\"c\" /* validateCallback */])(fnName, 3, ret.cancel, true);\n ret.context = context;\n Object(utils_validation[\"d\" /* validateContextObject */])(fnName, 4, ret.context, true);\n } else if (cancelOrContext) {\n // we have either a cancel callback or a context.\n if ((typeof cancelOrContext === 'undefined' ? 'undefined' : _typeof(cancelOrContext)) === 'object' && cancelOrContext !== null) {\n // it's a context!\n ret.context = cancelOrContext;\n } else if (typeof cancelOrContext === 'function') {\n ret.cancel = cancelOrContext;\n } else {\n throw new Error(Object(utils_validation[\"a\" /* errorPrefix */])(fnName, 3, true) + ' must either be a cancel callback or a context object.');\n }\n }\n return ret;\n };\n Object.defineProperty(Query.prototype, \"ref\", {\n get: function get() {\n return this.getRef();\n },\n enumerable: true,\n configurable: true\n });\n return Query;\n}();\n\n\n/***/ }),\n/* 40 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"b\"] = setMaxNode;\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return priorityHashText; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return validatePriorityNode; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_obj__ = __webpack_require__(2);\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\n\n\nvar MAX_NODE;\nfunction setMaxNode(val) {\n MAX_NODE = val;\n}\n/**\r\n * @param {(!string|!number)} priority\r\n * @return {!string}\r\n */\nvar priorityHashText = function priorityHashText(priority) {\n if (typeof priority === 'number') return 'number:' + Object(__WEBPACK_IMPORTED_MODULE_1__util_util__[\"h\" /* doubleToIEEE754String */])(priority);else return 'string:' + priority;\n};\n/**\r\n * Validates that a priority snapshot Node is valid.\r\n *\r\n * @param {!Node} priorityNode\r\n */\nvar validatePriorityNode = function validatePriorityNode(priorityNode) {\n if (priorityNode.isLeafNode()) {\n var val = priorityNode.val();\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(typeof val === 'string' || typeof val === 'number' || (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object' && Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"b\" /* contains */])(val, '.sv'), 'Priority must be a string or number.');\n } else {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(priorityNode === MAX_NODE || priorityNode.isEmpty(), 'priority of unexpected type.');\n }\n // Don't call getPriority() on MAX_NODE to avoid hitting assertion.\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(priorityNode === MAX_NODE || priorityNode.getPriority().isEmpty(), \"Priority nodes can't have a priority of their own.\");\n};\n\n/***/ }),\n/* 41 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* unused harmony export ValueIndex */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return VALUE_INDEX; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Index__ = __webpack_require__(20);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__nodeFromJSON__ = __webpack_require__(16);\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 __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/**\r\n * @constructor\r\n * @extends {Index}\r\n * @private\r\n */\nvar ValueIndex = /** @class */function (_super) {\n __extends(ValueIndex, _super);\n function ValueIndex() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n /**\r\n * @inheritDoc\r\n */\n ValueIndex.prototype.compare = function (a, b) {\n var indexCmp = a.node.compareTo(b.node);\n if (indexCmp === 0) {\n return Object(__WEBPACK_IMPORTED_MODULE_2__util_util__[\"v\" /* nameCompare */])(a.name, b.name);\n } else {\n return indexCmp;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n ValueIndex.prototype.isDefinedOn = function (node) {\n return true;\n };\n /**\r\n * @inheritDoc\r\n */\n ValueIndex.prototype.indexedValueChanged = function (oldNode, newNode) {\n return !oldNode.equals(newNode);\n };\n /**\r\n * @inheritDoc\r\n */\n ValueIndex.prototype.minPost = function () {\n return __WEBPACK_IMPORTED_MODULE_1__Node__[\"a\" /* NamedNode */].MIN;\n };\n /**\r\n * @inheritDoc\r\n */\n ValueIndex.prototype.maxPost = function () {\n return __WEBPACK_IMPORTED_MODULE_1__Node__[\"a\" /* NamedNode */].MAX;\n };\n /**\r\n * @param {*} indexValue\r\n * @param {string} name\r\n * @return {!NamedNode}\r\n */\n ValueIndex.prototype.makePost = function (indexValue, name) {\n var valueNode = Object(__WEBPACK_IMPORTED_MODULE_3__nodeFromJSON__[\"a\" /* nodeFromJSON */])(indexValue);\n return new __WEBPACK_IMPORTED_MODULE_1__Node__[\"a\" /* NamedNode */](name, valueNode);\n };\n /**\r\n * @return {!string} String representation for inclusion in a query spec\r\n */\n ValueIndex.prototype.toString = function () {\n return '.value';\n };\n return ValueIndex;\n}(__WEBPACK_IMPORTED_MODULE_0__Index__[\"a\" /* Index */]);\n\nvar VALUE_INDEX = new ValueIndex();\n\n/***/ }),\n/* 42 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return IndexMap; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__childSet__ = __webpack_require__(43);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_obj__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__indexes_PriorityIndex__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__indexes_KeyIndex__ = __webpack_require__(15);\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 _defaultIndexMap;\nvar fallbackObject = {};\n/**\r\n *\r\n * @param {Object.>} indexes\r\n * @param {Object.} indexSet\r\n * @constructor\r\n */\nvar IndexMap = /** @class */function () {\n function IndexMap(indexes_, indexSet_) {\n this.indexes_ = indexes_;\n this.indexSet_ = indexSet_;\n }\n Object.defineProperty(IndexMap, \"Default\", {\n /**\r\n * The default IndexMap for nodes without a priority\r\n * @type {!IndexMap}\r\n * @const\r\n */\n get: function get() {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(fallbackObject && __WEBPACK_IMPORTED_MODULE_4__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], 'ChildrenNode.ts has not been loaded');\n _defaultIndexMap = _defaultIndexMap || new IndexMap({ '.priority': fallbackObject }, { '.priority': __WEBPACK_IMPORTED_MODULE_4__indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */] });\n return _defaultIndexMap;\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n *\r\n * @param {!string} indexKey\r\n * @return {?SortedMap.}\r\n */\n IndexMap.prototype.get = function (indexKey) {\n var sortedMap = Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"l\" /* safeGet */])(this.indexes_, indexKey);\n if (!sortedMap) throw new Error('No index defined for ' + indexKey);\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 /**\r\n * @param {!Index} indexDefinition\r\n * @return {boolean}\r\n */\n IndexMap.prototype.hasIndex = function (indexDefinition) {\n return Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"b\" /* contains */])(this.indexSet_, indexDefinition.toString());\n };\n /**\r\n * @param {!Index} indexDefinition\r\n * @param {!SortedMap.} existingChildren\r\n * @return {!IndexMap}\r\n */\n IndexMap.prototype.addIndex = function (indexDefinition, existingChildren) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(indexDefinition !== __WEBPACK_IMPORTED_MODULE_5__indexes_KeyIndex__[\"a\" /* KEY_INDEX */], \"KeyIndex always exists and isn't meant to be added to the IndexMap.\");\n var childList = [];\n var sawIndexedValue = false;\n var iter = existingChildren.getIterator(__WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */].Wrap);\n var next = iter.getNext();\n while (next) {\n sawIndexedValue = sawIndexedValue || indexDefinition.isDefinedOn(next.node);\n childList.push(next);\n next = iter.getNext();\n }\n var newIndex;\n if (sawIndexedValue) {\n newIndex = Object(__WEBPACK_IMPORTED_MODULE_1__childSet__[\"a\" /* buildChildSet */])(childList, indexDefinition.getCompare());\n } else {\n newIndex = fallbackObject;\n }\n var indexName = indexDefinition.toString();\n var newIndexSet = Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"a\" /* clone */])(this.indexSet_);\n newIndexSet[indexName] = indexDefinition;\n var newIndexes = Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"a\" /* clone */])(this.indexes_);\n newIndexes[indexName] = newIndex;\n return new IndexMap(newIndexes, newIndexSet);\n };\n /**\r\n * Ensure that this node is properly tracked in any indexes that we're maintaining\r\n * @param {!NamedNode} namedNode\r\n * @param {!SortedMap.} existingChildren\r\n * @return {!IndexMap}\r\n */\n IndexMap.prototype.addToIndexes = function (namedNode, existingChildren) {\n var _this = this;\n var newIndexes = Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"k\" /* map */])(this.indexes_, function (indexedChildren, indexName) {\n var index = Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"l\" /* safeGet */])(_this.indexSet_, indexName);\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* 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 var childList = [];\n var iter = existingChildren.getIterator(__WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */].Wrap);\n var 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 Object(__WEBPACK_IMPORTED_MODULE_1__childSet__[\"a\" /* buildChildSet */])(childList, index.getCompare());\n } else {\n // No change, this remains a fallback\n return fallbackObject;\n }\n } else {\n var existingSnap = existingChildren.get(namedNode.name);\n var newChildren = indexedChildren;\n if (existingSnap) {\n newChildren = newChildren.remove(new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* NamedNode */](namedNode.name, existingSnap));\n }\n return newChildren.insert(namedNode, namedNode.node);\n }\n });\n return new IndexMap(newIndexes, this.indexSet_);\n };\n /**\r\n * Create a new IndexMap instance with the given value removed\r\n * @param {!NamedNode} namedNode\r\n * @param {!SortedMap.} existingChildren\r\n * @return {!IndexMap}\r\n */\n IndexMap.prototype.removeFromIndexes = function (namedNode, existingChildren) {\n var newIndexes = Object(__WEBPACK_IMPORTED_MODULE_2__utils_obj__[\"k\" /* map */])(this.indexes_, function (indexedChildren) {\n if (indexedChildren === fallbackObject) {\n // This is the fallback. Just return it, nothing to do in this case\n return indexedChildren;\n } else {\n var existingSnap = existingChildren.get(namedNode.name);\n if (existingSnap) {\n return indexedChildren.remove(new __WEBPACK_IMPORTED_MODULE_3__Node__[\"a\" /* 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 return IndexMap;\n}();\n\n\n/***/ }),\n/* 43 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return buildChildSet; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__ = __webpack_require__(22);\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 LOG_2 = Math.log(2);\n/**\r\n * @constructor\r\n */\nvar Base12Num = /** @class */function () {\n /**\r\n * @param {number} length\r\n */\n function Base12Num(length) {\n var logBase2 = function logBase2(num) {\n return parseInt(Math.log(num) / LOG_2, 10);\n };\n var bitMask = function bitMask(bits) {\n return parseInt(Array(bits + 1).join('1'), 2);\n };\n this.count = logBase2(length + 1);\n this.current_ = this.count - 1;\n var mask = bitMask(this.count);\n this.bits_ = length + 1 & mask;\n }\n /**\r\n * @return {boolean}\r\n */\n Base12Num.prototype.nextBitIsOne = function () {\n //noinspection JSBitwiseOperatorUsage\n var result = !(this.bits_ & 0x1 << this.current_);\n this.current_--;\n return result;\n };\n return Base12Num;\n}();\n/**\r\n * Takes a list of child nodes and constructs a SortedSet using the given comparison\r\n * function\r\n *\r\n * Uses the algorithm described in the paper linked here:\r\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.1458\r\n *\r\n * @template K, V\r\n * @param {Array.} childList Unsorted list of children\r\n * @param {function(!NamedNode, !NamedNode):number} cmp The comparison method to be used\r\n * @param {(function(NamedNode):K)=} keyFn An optional function to extract K from a node wrapper, if K's\r\n * type is not NamedNode\r\n * @param {(function(K, K):number)=} mapSortFn An optional override for comparator used by the generated sorted map\r\n * @return {SortedMap.}\r\n */\nvar buildChildSet = function buildChildSet(childList, cmp, keyFn, mapSortFn) {\n childList.sort(cmp);\n var buildBalancedTree = function buildBalancedTree(low, high) {\n var length = high - low;\n var namedNode;\n var key;\n if (length == 0) {\n return null;\n } else if (length == 1) {\n namedNode = childList[low];\n key = keyFn ? keyFn(namedNode) : namedNode;\n return new __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */](key, namedNode.node, __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */].BLACK, null, null);\n } else {\n var middle = parseInt(length / 2, 10) + low;\n var left = buildBalancedTree(low, middle);\n var right = buildBalancedTree(middle + 1, high);\n namedNode = childList[middle];\n key = keyFn ? keyFn(namedNode) : namedNode;\n return new __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */](key, namedNode.node, __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */].BLACK, left, right);\n }\n };\n var buildFrom12Array = function buildFrom12Array(base12) {\n var node = null;\n var root = null;\n var index = childList.length;\n var buildPennant = function buildPennant(chunkSize, color) {\n var low = index - chunkSize;\n var high = index;\n index -= chunkSize;\n var childTree = buildBalancedTree(low + 1, high);\n var namedNode = childList[low];\n var key = keyFn ? keyFn(namedNode) : namedNode;\n attachPennant(new __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */](key, namedNode.node, color, null, childTree));\n };\n var attachPennant = function attachPennant(pennant) {\n if (node) {\n node.left = pennant;\n node = pennant;\n } else {\n root = pennant;\n node = pennant;\n }\n };\n for (var i = 0; i < base12.count; ++i) {\n var isOne = base12.nextBitIsOne();\n // The number of nodes taken in each slice is 2^(arr.length - (i + 1))\n var chunkSize = Math.pow(2, base12.count - (i + 1));\n if (isOne) {\n buildPennant(chunkSize, __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */].BLACK);\n } else {\n // current == 2\n buildPennant(chunkSize, __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */].BLACK);\n buildPennant(chunkSize, __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"a\" /* LLRBNode */].RED);\n }\n }\n return root;\n };\n var base12 = new Base12Num(childList.length);\n var root = buildFrom12Array(base12);\n return new __WEBPACK_IMPORTED_MODULE_0__util_SortedMap__[\"b\" /* SortedMap */](mapSortFn || cmp, root);\n};\n\n/***/ }),\n/* 44 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"b\"] = NAME_ONLY_COMPARATOR;\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = NAME_COMPARATOR;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__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\nfunction NAME_ONLY_COMPARATOR(left, right) {\n return Object(__WEBPACK_IMPORTED_MODULE_0__util_util__[\"v\" /* nameCompare */])(left.name, right.name);\n}\nfunction NAME_COMPARATOR(left, right) {\n return Object(__WEBPACK_IMPORTED_MODULE_0__util_util__[\"v\" /* nameCompare */])(left, right);\n}\n\n/***/ }),\n/* 45 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return PathIndex; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Index__ = __webpack_require__(20);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__ChildrenNode__ = __webpack_require__(6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Node__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__nodeFromJSON__ = __webpack_require__(16);\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 __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 * @param {!Path} indexPath\r\n * @constructor\r\n * @extends {Index}\r\n */\nvar PathIndex = /** @class */function (_super) {\n __extends(PathIndex, _super);\n function PathIndex(indexPath_) {\n var _this = _super.call(this) || this;\n _this.indexPath_ = indexPath_;\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])(!indexPath_.isEmpty() && indexPath_.getFront() !== '.priority', \"Can't create PathIndex with empty path or .priority key\");\n return _this;\n }\n /**\r\n * @param {!Node} snap\r\n * @return {!Node}\r\n * @protected\r\n */\n PathIndex.prototype.extractChild = function (snap) {\n return snap.getChild(this.indexPath_);\n };\n /**\r\n * @inheritDoc\r\n */\n PathIndex.prototype.isDefinedOn = function (node) {\n return !node.getChild(this.indexPath_).isEmpty();\n };\n /**\r\n * @inheritDoc\r\n */\n PathIndex.prototype.compare = function (a, b) {\n var aChild = this.extractChild(a.node);\n var bChild = this.extractChild(b.node);\n var indexCmp = aChild.compareTo(bChild);\n if (indexCmp === 0) {\n return Object(__WEBPACK_IMPORTED_MODULE_1__util_util__[\"v\" /* nameCompare */])(a.name, b.name);\n } else {\n return indexCmp;\n }\n };\n /**\r\n * @inheritDoc\r\n */\n PathIndex.prototype.makePost = function (indexValue, name) {\n var valueNode = Object(__WEBPACK_IMPORTED_MODULE_5__nodeFromJSON__[\"a\" /* nodeFromJSON */])(indexValue);\n var node = __WEBPACK_IMPORTED_MODULE_3__ChildrenNode__[\"a\" /* ChildrenNode */].EMPTY_NODE.updateChild(this.indexPath_, valueNode);\n return new __WEBPACK_IMPORTED_MODULE_4__Node__[\"a\" /* NamedNode */](name, node);\n };\n /**\r\n * @inheritDoc\r\n */\n PathIndex.prototype.maxPost = function () {\n var node = __WEBPACK_IMPORTED_MODULE_3__ChildrenNode__[\"a\" /* ChildrenNode */].EMPTY_NODE.updateChild(this.indexPath_, __WEBPACK_IMPORTED_MODULE_3__ChildrenNode__[\"b\" /* MAX_NODE */]);\n return new __WEBPACK_IMPORTED_MODULE_4__Node__[\"a\" /* NamedNode */](__WEBPACK_IMPORTED_MODULE_1__util_util__[\"b\" /* MAX_NAME */], node);\n };\n /**\r\n * @inheritDoc\r\n */\n PathIndex.prototype.toString = function () {\n return this.indexPath_.slice().join('/');\n };\n return PathIndex;\n}(__WEBPACK_IMPORTED_MODULE_2__Index__[\"a\" /* Index */]);\n\n\n/***/ }),\n/* 46 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return DataSnapshot; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_validation__ = __webpack_require__(10);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_util_validation__ = __webpack_require__(11);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util_Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_snap_indexes_PriorityIndex__ = __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/**\r\n * Class representing a firebase data snapshot. It wraps a SnapshotNode and\r\n * surfaces the public methods (val, forEach, etc.) we want to expose.\r\n */\nvar DataSnapshot = /** @class */function () {\n /**\r\n * @param {!Node} node_ A SnapshotNode to wrap.\r\n * @param {!Reference} ref_ The ref of the location this snapshot came from.\r\n * @param {!Index} index_ The iteration order for this snapshot\r\n */\n function DataSnapshot(node_, ref_, index_) {\n this.node_ = node_;\n this.ref_ = ref_;\n this.index_ = index_;\n }\n /**\r\n * Retrieves the snapshot contents as JSON. Returns null if the snapshot is\r\n * empty.\r\n *\r\n * @return {*} JSON representation of the DataSnapshot contents, or null if empty.\r\n */\n DataSnapshot.prototype.val = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.val', 0, 0, arguments.length);\n return this.node_.val();\n };\n /**\r\n * Returns the snapshot contents as JSON, including priorities of node. Suitable for exporting\r\n * the entire node contents.\r\n * @return {*} JSON representation of the DataSnapshot contents, or null if empty.\r\n */\n DataSnapshot.prototype.exportVal = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.exportVal', 0, 0, arguments.length);\n return this.node_.val(true);\n };\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n // for end-users\n DataSnapshot.prototype.toJSON = function () {\n // Optional spacer argument is unnecessary because we're depending on recursion rather than stringifying the content\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.toJSON', 0, 1, arguments.length);\n return this.exportVal();\n };\n /**\r\n * Returns whether the snapshot contains a non-null value.\r\n *\r\n * @return {boolean} Whether the snapshot contains a non-null value, or is empty.\r\n */\n DataSnapshot.prototype.exists = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.exists', 0, 0, arguments.length);\n return !this.node_.isEmpty();\n };\n /**\r\n * Returns a DataSnapshot of the specified child node's contents.\r\n *\r\n * @param {!string} childPathString Path to a child.\r\n * @return {!DataSnapshot} DataSnapshot for child node.\r\n */\n DataSnapshot.prototype.child = function (childPathString) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.child', 0, 1, arguments.length);\n // Ensure the childPath is a string (can be a number)\n childPathString = String(childPathString);\n Object(__WEBPACK_IMPORTED_MODULE_1__core_util_validation__[\"h\" /* validatePathString */])('DataSnapshot.child', 1, childPathString, false);\n var childPath = new __WEBPACK_IMPORTED_MODULE_2__core_util_Path__[\"a\" /* Path */](childPathString);\n var childRef = this.ref_.child(childPath);\n return new DataSnapshot(this.node_.getChild(childPath), childRef, __WEBPACK_IMPORTED_MODULE_3__core_snap_indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */]);\n };\n /**\r\n * Returns whether the snapshot contains a child at the specified path.\r\n *\r\n * @param {!string} childPathString Path to a child.\r\n * @return {boolean} Whether the child exists.\r\n */\n DataSnapshot.prototype.hasChild = function (childPathString) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.hasChild', 1, 1, arguments.length);\n Object(__WEBPACK_IMPORTED_MODULE_1__core_util_validation__[\"h\" /* validatePathString */])('DataSnapshot.hasChild', 1, childPathString, false);\n var childPath = new __WEBPACK_IMPORTED_MODULE_2__core_util_Path__[\"a\" /* Path */](childPathString);\n return !this.node_.getChild(childPath).isEmpty();\n };\n /**\r\n * Returns the priority of the object, or null if no priority was set.\r\n *\r\n * @return {string|number|null} The priority.\r\n */\n DataSnapshot.prototype.getPriority = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.getPriority', 0, 0, arguments.length);\n // typecast here because we never return deferred values or internal priorities (MAX_PRIORITY)\n return this.node_.getPriority().val();\n };\n /**\r\n * Iterates through child nodes and calls the specified action for each one.\r\n *\r\n * @param {function(!DataSnapshot)} action Callback function to be called\r\n * for each child.\r\n * @return {boolean} True if forEach was canceled by action returning true for\r\n * one of the child nodes.\r\n */\n DataSnapshot.prototype.forEach = function (action) {\n var _this = this;\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.forEach', 1, 1, arguments.length);\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"c\" /* validateCallback */])('DataSnapshot.forEach', 1, action, false);\n if (this.node_.isLeafNode()) return false;\n var childrenNode = this.node_;\n // Sanitize the return value to a boolean. ChildrenNode.forEachChild has a weird return type...\n return !!childrenNode.forEachChild(this.index_, function (key, node) {\n return action(new DataSnapshot(node, _this.ref_.child(key), __WEBPACK_IMPORTED_MODULE_3__core_snap_indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */]));\n });\n };\n /**\r\n * Returns whether this DataSnapshot has children.\r\n * @return {boolean} True if the DataSnapshot contains 1 or more child nodes.\r\n */\n DataSnapshot.prototype.hasChildren = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.hasChildren', 0, 0, arguments.length);\n if (this.node_.isLeafNode()) return false;else return !this.node_.isEmpty();\n };\n Object.defineProperty(DataSnapshot.prototype, \"key\", {\n get: function get() {\n return this.ref_.getKey();\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * Returns the number of children for this DataSnapshot.\r\n * @return {number} The number of children that this DataSnapshot contains.\r\n */\n DataSnapshot.prototype.numChildren = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.numChildren', 0, 0, arguments.length);\n return this.node_.numChildren();\n };\n /**\r\n * @return {Reference} The Firebase reference for the location this snapshot's data came from.\r\n */\n DataSnapshot.prototype.getRef = function () {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_validation__[\"b\" /* validateArgCount */])('DataSnapshot.ref', 0, 0, arguments.length);\n return this.ref_;\n };\n Object.defineProperty(DataSnapshot.prototype, \"ref\", {\n get: function get() {\n return this.getRef();\n },\n enumerable: true,\n configurable: true\n });\n return DataSnapshot;\n}();\n\n\n/***/ }),\n/* 47 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return generateWithValues; });\n/* unused harmony export resolveDeferredValue */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return resolveDeferredValueTree; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return resolveDeferredValueSnapshot; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__SparseSnapshotTree__ = __webpack_require__(48);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__snap_LeafNode__ = __webpack_require__(21);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__snap_nodeFromJSON__ = __webpack_require__(16);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__snap_indexes_PriorityIndex__ = __webpack_require__(5);\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\n\n\n\n\n\n/**\r\n * Generate placeholders for deferred values.\r\n * @param {?Object} values\r\n * @return {!Object}\r\n */\nvar generateWithValues = function generateWithValues(values) {\n values = values || {};\n values['timestamp'] = values['timestamp'] || new Date().getTime();\n return values;\n};\n/**\r\n * Value to use when firing local events. When writing server values, fire\r\n * local events with an approximate value, otherwise return value as-is.\r\n * @param {(Object|string|number|boolean)} value\r\n * @param {!Object} serverValues\r\n * @return {!(string|number|boolean)}\r\n */\nvar resolveDeferredValue = function resolveDeferredValue(value, serverValues) {\n if (!value || (typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== 'object') {\n return value;\n } else {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_assert__[\"a\" /* assert */])('.sv' in value, 'Unexpected leaf node or priority contents');\n return serverValues[value['.sv']];\n }\n};\n/**\r\n * Recursively replace all deferred values and priorities in the tree with the\r\n * specified generated replacement values.\r\n * @param {!SparseSnapshotTree} tree\r\n * @param {!Object} serverValues\r\n * @return {!SparseSnapshotTree}\r\n */\nvar resolveDeferredValueTree = function resolveDeferredValueTree(tree, serverValues) {\n var resolvedTree = new __WEBPACK_IMPORTED_MODULE_2__SparseSnapshotTree__[\"a\" /* SparseSnapshotTree */]();\n tree.forEachTree(new __WEBPACK_IMPORTED_MODULE_1__Path__[\"a\" /* Path */](''), function (path, node) {\n resolvedTree.remember(path, resolveDeferredValueSnapshot(node, serverValues));\n });\n return resolvedTree;\n};\n/**\r\n * Recursively replace all deferred values and priorities in the node with the\r\n * specified generated replacement values. If there are no server values in the node,\r\n * it'll be returned as-is.\r\n * @param {!Node} node\r\n * @param {!Object} serverValues\r\n * @return {!Node}\r\n */\nvar resolveDeferredValueSnapshot = function resolveDeferredValueSnapshot(node, serverValues) {\n var rawPri = node.getPriority().val();\n var priority = resolveDeferredValue(rawPri, serverValues);\n var newNode;\n if (node.isLeafNode()) {\n var leafNode = node;\n var value = resolveDeferredValue(leafNode.getValue(), serverValues);\n if (value !== leafNode.getValue() || priority !== leafNode.getPriority().val()) {\n return new __WEBPACK_IMPORTED_MODULE_3__snap_LeafNode__[\"a\" /* LeafNode */](value, Object(__WEBPACK_IMPORTED_MODULE_4__snap_nodeFromJSON__[\"a\" /* nodeFromJSON */])(priority));\n } else {\n return node;\n }\n } else {\n var childrenNode = node;\n newNode = childrenNode;\n if (priority !== childrenNode.getPriority().val()) {\n newNode = newNode.updatePriority(new __WEBPACK_IMPORTED_MODULE_3__snap_LeafNode__[\"a\" /* LeafNode */](priority));\n }\n childrenNode.forEachChild(__WEBPACK_IMPORTED_MODULE_5__snap_indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], function (childName, childNode) {\n var newChildNode = resolveDeferredValueSnapshot(childNode, serverValues);\n if (newChildNode !== childNode) {\n newNode = newNode.updateImmediateChild(childName, newChildNode);\n }\n });\n return newNode;\n }\n};\n\n/***/ }),\n/* 48 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return SparseSnapshotTree; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_Path__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__snap_indexes_PriorityIndex__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_CountedSet__ = __webpack_require__(49);\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 * Helper class to store a sparse set of snapshots.\r\n *\r\n * @constructor\r\n */\nvar SparseSnapshotTree = /** @class */function () {\n function SparseSnapshotTree() {\n /**\r\n * @private\r\n * @type {Node}\r\n */\n this.value_ = null;\n /**\r\n * @private\r\n * @type {CountedSet}\r\n */\n this.children_ = null;\n }\n /**\r\n * Gets the node stored at the given path if one exists.\r\n *\r\n * @param {!Path} path Path to look up snapshot for.\r\n * @return {?Node} The retrieved node, or null.\r\n */\n SparseSnapshotTree.prototype.find = function (path) {\n if (this.value_ != null) {\n return this.value_.getChild(path);\n } else if (!path.isEmpty() && this.children_ != null) {\n var childKey = path.getFront();\n path = path.popFront();\n if (this.children_.contains(childKey)) {\n var childTree = this.children_.get(childKey);\n return childTree.find(path);\n } else {\n return null;\n }\n } else {\n return null;\n }\n };\n /**\r\n * Stores the given node at the specified path. If there is already a node\r\n * at a shallower path, it merges the new data into that snapshot node.\r\n *\r\n * @param {!Path} path Path to look up snapshot for.\r\n * @param {!Node} data The new data, or null.\r\n */\n SparseSnapshotTree.prototype.remember = function (path, data) {\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 __WEBPACK_IMPORTED_MODULE_2__util_CountedSet__[\"a\" /* CountedSet */]();\n }\n var childKey = path.getFront();\n if (!this.children_.contains(childKey)) {\n this.children_.add(childKey, new SparseSnapshotTree());\n }\n var child = this.children_.get(childKey);\n path = path.popFront();\n child.remember(path, data);\n }\n };\n /**\r\n * Purge the data at path from the cache.\r\n *\r\n * @param {!Path} path Path to look up snapshot for.\r\n * @return {boolean} True if this node should now be removed.\r\n */\n SparseSnapshotTree.prototype.forget = function (path) {\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 var value = this.value_;\n this.value_ = null;\n var self_1 = this;\n value.forEachChild(__WEBPACK_IMPORTED_MODULE_1__snap_indexes_PriorityIndex__[\"a\" /* PRIORITY_INDEX */], function (key, tree) {\n self_1.remember(new __WEBPACK_IMPORTED_MODULE_0__util_Path__[\"a\" /* Path */](key), tree);\n });\n return this.forget(path);\n }\n } else if (this.children_ !== null) {\n var childKey = path.getFront();\n path = path.popFront();\n if (this.children_.contains(childKey)) {\n var safeToRemove = this.children_.get(childKey).forget(path);\n if (safeToRemove) {\n this.children_.remove(childKey);\n }\n }\n if (this.children_.isEmpty()) {\n this.children_ = null;\n return true;\n } else {\n return false;\n }\n } else {\n return true;\n }\n }\n };\n /**\r\n * Recursively iterates through all of the stored tree and calls the\r\n * callback on each one.\r\n *\r\n * @param {!Path} prefixPath Path to look up node for.\r\n * @param {!Function} func The function to invoke for each tree.\r\n */\n SparseSnapshotTree.prototype.forEachTree = function (prefixPath, func) {\n if (this.value_ !== null) {\n func(prefixPath, this.value_);\n } else {\n this.forEachChild(function (key, tree) {\n var path = new __WEBPACK_IMPORTED_MODULE_0__util_Path__[\"a\" /* Path */](prefixPath.toString() + '/' + key);\n tree.forEachTree(path, func);\n });\n }\n };\n /**\r\n * Iterates through each immediate child and triggers the callback.\r\n *\r\n * @param {!Function} func The function to invoke for each child.\r\n */\n SparseSnapshotTree.prototype.forEachChild = function (func) {\n if (this.children_ !== null) {\n this.children_.each(function (key, tree) {\n func(key, tree);\n });\n }\n };\n return SparseSnapshotTree;\n}();\n\n\n/***/ }),\n/* 49 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return CountedSet; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__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/**\r\n * Implements a set with a count of elements.\r\n *\r\n * @template K, V\r\n */\nvar CountedSet = /** @class */function () {\n function CountedSet() {\n this.set = {};\n }\n /**\r\n * @param {!K} item\r\n * @param {V} val\r\n */\n CountedSet.prototype.add = function (item, val) {\n this.set[item] = val !== null ? val : true;\n };\n /**\r\n * @param {!K} key\r\n * @return {boolean}\r\n */\n CountedSet.prototype.contains = function (key) {\n return Object(__WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"b\" /* contains */])(this.set, key);\n };\n /**\r\n * @param {!K} item\r\n * @return {V}\r\n */\n CountedSet.prototype.get = function (item) {\n return this.contains(item) ? this.set[item] : undefined;\n };\n /**\r\n * @param {!K} item\r\n */\n CountedSet.prototype.remove = function (item) {\n delete this.set[item];\n };\n /**\r\n * Deletes everything in the set\r\n */\n CountedSet.prototype.clear = function () {\n this.set = {};\n };\n /**\r\n * True if there's nothing in the set\r\n * @return {boolean}\r\n */\n CountedSet.prototype.isEmpty = function () {\n return Object(__WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"j\" /* isEmpty */])(this.set);\n };\n /**\r\n * @return {number} The number of items in the set\r\n */\n CountedSet.prototype.count = function () {\n return Object(__WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"h\" /* getCount */])(this.set);\n };\n /**\r\n * Run a function on each k,v pair in the set\r\n * @param {function(K, V)} fn\r\n */\n CountedSet.prototype.each = function (fn) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"f\" /* forEach */])(this.set, function (k, v) {\n return fn(k, v);\n });\n };\n /**\r\n * Mostly for debugging\r\n * @return {Array.} The keys present in this CountedSet\r\n */\n CountedSet.prototype.keys = function () {\n var keys = [];\n Object(__WEBPACK_IMPORTED_MODULE_0__utils_obj__[\"f\" /* forEach */])(this.set, function (k) {\n keys.push(k);\n });\n return keys;\n };\n return CountedSet;\n}();\n\n\n/***/ }),\n/* 50 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// CONCATENATED MODULE: ./src/database/core/view/CacheNode.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 * A cache node only stores complete children. Additionally it holds a flag whether the node can be considered fully\r\n * initialized in the sense that we know at one point in time this represented a valid state of the world, e.g.\r\n * initialized with data from the server, or a complete overwrite by the client. The filtered flag also tracks\r\n * whether a node potentially had children removed due to a filter.\r\n */\nvar CacheNode = /** @class */function () {\n /**\r\n * @param {!Node} node_\r\n * @param {boolean} fullyInitialized_\r\n * @param {boolean} filtered_\r\n */\n function CacheNode(node_, fullyInitialized_, filtered_) {\n this.node_ = node_;\n this.fullyInitialized_ = fullyInitialized_;\n this.filtered_ = filtered_;\n }\n /**\r\n * Returns whether this node was fully initialized with either server data or a complete overwrite by the client\r\n * @return {boolean}\r\n */\n CacheNode.prototype.isFullyInitialized = function () {\n return this.fullyInitialized_;\n };\n /**\r\n * Returns whether this node is potentially missing children due to a filter applied to the node\r\n * @return {boolean}\r\n */\n CacheNode.prototype.isFiltered = function () {\n return this.filtered_;\n };\n /**\r\n * @param {!Path} path\r\n * @return {boolean}\r\n */\n CacheNode.prototype.isCompleteForPath = function (path) {\n if (path.isEmpty()) {\n return this.isFullyInitialized() && !this.filtered_;\n }\n var childKey = path.getFront();\n return this.isCompleteForChild(childKey);\n };\n /**\r\n * @param {!string} key\r\n * @return {boolean}\r\n */\n CacheNode.prototype.isCompleteForChild = function (key) {\n return this.isFullyInitialized() && !this.filtered_ || this.node_.hasChild(key);\n };\n /**\r\n * @return {!Node}\r\n */\n CacheNode.prototype.getNode = function () {\n return this.node_;\n };\n return CacheNode;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/snap/ChildrenNode.ts\nvar ChildrenNode = __webpack_require__(6);\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar obj = __webpack_require__(2);\n\n// CONCATENATED MODULE: ./src/database/core/view/ViewCache.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 * Stores the data we have cached for a view.\r\n *\r\n * serverSnap is the cached server data, eventSnap is the cached event data (server data plus any local writes).\r\n *\r\n * @constructor\r\n */\nvar ViewCache_ViewCache = /** @class */function () {\n /**\r\n *\r\n * @param {!CacheNode} eventCache_\r\n * @param {!CacheNode} serverCache_\r\n */\n function ViewCache(eventCache_, serverCache_) {\n this.eventCache_ = eventCache_;\n this.serverCache_ = serverCache_;\n }\n /**\r\n * @param {!Node} eventSnap\r\n * @param {boolean} complete\r\n * @param {boolean} filtered\r\n * @return {!ViewCache}\r\n */\n ViewCache.prototype.updateEventSnap = function (eventSnap, complete, filtered) {\n return new ViewCache(new CacheNode(eventSnap, complete, filtered), this.serverCache_);\n };\n /**\r\n * @param {!Node} serverSnap\r\n * @param {boolean} complete\r\n * @param {boolean} filtered\r\n * @return {!ViewCache}\r\n */\n ViewCache.prototype.updateServerSnap = function (serverSnap, complete, filtered) {\n return new ViewCache(this.eventCache_, new CacheNode(serverSnap, complete, filtered));\n };\n /**\r\n * @return {!CacheNode}\r\n */\n ViewCache.prototype.getEventCache = function () {\n return this.eventCache_;\n };\n /**\r\n * @return {?Node}\r\n */\n ViewCache.prototype.getCompleteEventSnap = function () {\n return this.eventCache_.isFullyInitialized() ? this.eventCache_.getNode() : null;\n };\n /**\r\n * @return {!CacheNode}\r\n */\n ViewCache.prototype.getServerCache = function () {\n return this.serverCache_;\n };\n /**\r\n * @return {?Node}\r\n */\n ViewCache.prototype.getCompleteServerSnap = function () {\n return this.serverCache_.isFullyInitialized() ? this.serverCache_.getNode() : null;\n };\n /**\r\n * @const\r\n * @type {ViewCache}\r\n */\n ViewCache.Empty = new ViewCache(new CacheNode(ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE,\n /*fullyInitialized=*/false,\n /*filtered=*/false), new CacheNode(ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE,\n /*fullyInitialized=*/false,\n /*filtered=*/false));\n return ViewCache;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/view/filter/IndexedFilter.ts\nvar IndexedFilter = __webpack_require__(28);\n\n// EXTERNAL MODULE: ./src/database/core/operation/Operation.ts\nvar Operation = __webpack_require__(12);\n\n// EXTERNAL MODULE: ./src/database/core/view/Change.ts\nvar Change = __webpack_require__(14);\n\n// CONCATENATED MODULE: ./src/database/core/view/ChildChangeAccumulator.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 * @constructor\r\n */\nvar ChildChangeAccumulator_ChildChangeAccumulator = /** @class */function () {\n function ChildChangeAccumulator() {\n this.changeMap_ = {};\n }\n /**\r\n * @param {!Change} change\r\n */\n ChildChangeAccumulator.prototype.trackChildChange = function (change) {\n var type = change.type;\n var childKey /** @type {!string} */ = change.childName;\n Object(assert[\"a\" /* assert */])(type == Change[\"a\" /* Change */].CHILD_ADDED || type == Change[\"a\" /* Change */].CHILD_CHANGED || type == Change[\"a\" /* Change */].CHILD_REMOVED, 'Only child changes supported for tracking');\n Object(assert[\"a\" /* assert */])(childKey !== '.priority', 'Only non-priority child changes can be tracked.');\n var oldChange = Object(obj[\"l\" /* safeGet */])(this.changeMap_, childKey);\n if (oldChange) {\n var oldType = oldChange.type;\n if (type == Change[\"a\" /* Change */].CHILD_ADDED && oldType == Change[\"a\" /* Change */].CHILD_REMOVED) {\n this.changeMap_[childKey] = Change[\"a\" /* Change */].childChangedChange(childKey, change.snapshotNode, oldChange.snapshotNode);\n } else if (type == Change[\"a\" /* Change */].CHILD_REMOVED && oldType == Change[\"a\" /* Change */].CHILD_ADDED) {\n delete this.changeMap_[childKey];\n } else if (type == Change[\"a\" /* Change */].CHILD_REMOVED && oldType == Change[\"a\" /* Change */].CHILD_CHANGED) {\n this.changeMap_[childKey] = Change[\"a\" /* Change */].childRemovedChange(childKey, oldChange.oldSnap);\n } else if (type == Change[\"a\" /* Change */].CHILD_CHANGED && oldType == Change[\"a\" /* Change */].CHILD_ADDED) {\n this.changeMap_[childKey] = Change[\"a\" /* Change */].childAddedChange(childKey, change.snapshotNode);\n } else if (type == Change[\"a\" /* Change */].CHILD_CHANGED && oldType == Change[\"a\" /* Change */].CHILD_CHANGED) {\n this.changeMap_[childKey] = Change[\"a\" /* Change */].childChangedChange(childKey, change.snapshotNode, oldChange.oldSnap);\n } else {\n throw Object(assert[\"b\" /* assertionError */])('Illegal combination of changes: ' + change + ' occurred after ' + oldChange);\n }\n } else {\n this.changeMap_[childKey] = change;\n }\n };\n /**\r\n * @return {!Array.}\r\n */\n ChildChangeAccumulator.prototype.getChanges = function () {\n return Object(obj[\"i\" /* getValues */])(this.changeMap_);\n };\n return ChildChangeAccumulator;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/KeyIndex.ts\nvar KeyIndex = __webpack_require__(15);\n\n// EXTERNAL MODULE: ./src/database/core/util/ImmutableTree.ts\nvar ImmutableTree = __webpack_require__(27);\n\n// EXTERNAL MODULE: ./src/database/core/util/Path.ts\nvar Path = __webpack_require__(4);\n\n// CONCATENATED MODULE: ./src/database/core/view/CompleteChildSource.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 * An implementation of CompleteChildSource that never returns any additional children\r\n *\r\n * @private\r\n * @constructor\r\n * @implements CompleteChildSource\r\n */\nvar NoCompleteChildSource_ = /** @class */function () {\n function NoCompleteChildSource_() {}\n /**\r\n * @inheritDoc\r\n */\n NoCompleteChildSource_.prototype.getCompleteChild = function (childKey) {\n return null;\n };\n /**\r\n * @inheritDoc\r\n */\n NoCompleteChildSource_.prototype.getChildAfterChild = function (index, child, reverse) {\n return null;\n };\n return NoCompleteChildSource_;\n}();\n\n/**\r\n * Singleton instance.\r\n * @const\r\n * @type {!CompleteChildSource}\r\n */\nvar NO_COMPLETE_CHILD_SOURCE = new NoCompleteChildSource_();\n/**\r\n * An implementation of CompleteChildSource that uses a WriteTree in addition to any other server data or\r\n * old event caches available to calculate complete children.\r\n *\r\n *\r\n * @implements CompleteChildSource\r\n */\nvar CompleteChildSource_WriteTreeCompleteChildSource = /** @class */function () {\n /**\r\n * @param {!WriteTreeRef} writes_\r\n * @param {!ViewCache} viewCache_\r\n * @param {?Node} optCompleteServerCache_\r\n */\n function WriteTreeCompleteChildSource(writes_, viewCache_, optCompleteServerCache_) {\n if (optCompleteServerCache_ === void 0) {\n optCompleteServerCache_ = null;\n }\n this.writes_ = writes_;\n this.viewCache_ = viewCache_;\n this.optCompleteServerCache_ = optCompleteServerCache_;\n }\n /**\r\n * @inheritDoc\r\n */\n WriteTreeCompleteChildSource.prototype.getCompleteChild = function (childKey) {\n var node = this.viewCache_.getEventCache();\n if (node.isCompleteForChild(childKey)) {\n return node.getNode().getImmediateChild(childKey);\n } else {\n var serverNode = this.optCompleteServerCache_ != null ? new CacheNode(this.optCompleteServerCache_, true, false) : this.viewCache_.getServerCache();\n return this.writes_.calcCompleteChild(childKey, serverNode);\n }\n };\n /**\r\n * @inheritDoc\r\n */\n WriteTreeCompleteChildSource.prototype.getChildAfterChild = function (index, child, reverse) {\n var completeServerData = this.optCompleteServerCache_ != null ? this.optCompleteServerCache_ : this.viewCache_.getCompleteServerSnap();\n var 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 return WriteTreeCompleteChildSource;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/view/ViewProcessor.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\n/**\r\n * @constructor\r\n * @struct\r\n */\nvar ProcessorResult = /** @class */function () {\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Array.} changes\r\n */\n function ProcessorResult(viewCache, changes) {\n this.viewCache = viewCache;\n this.changes = changes;\n }\n return ProcessorResult;\n}();\n\n/**\r\n * @constructor\r\n */\nvar ViewProcessor_ViewProcessor = /** @class */function () {\n /**\r\n * @param {!NodeFilter} filter_\r\n */\n function ViewProcessor(filter_) {\n this.filter_ = filter_;\n }\n /**\r\n * @param {!ViewCache} viewCache\r\n */\n ViewProcessor.prototype.assertIndexed = function (viewCache) {\n Object(assert[\"a\" /* assert */])(viewCache.getEventCache().getNode().isIndexed(this.filter_.getIndex()), 'Event snap not indexed');\n Object(assert[\"a\" /* assert */])(viewCache.getServerCache().getNode().isIndexed(this.filter_.getIndex()), 'Server snap not indexed');\n };\n /**\r\n * @param {!ViewCache} oldViewCache\r\n * @param {!Operation} operation\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} completeCache\r\n * @return {!ProcessorResult}\r\n */\n ViewProcessor.prototype.applyOperation = function (oldViewCache, operation, writesCache, completeCache) {\n var accumulator = new ChildChangeAccumulator_ChildChangeAccumulator();\n var newViewCache, filterServerNode;\n if (operation.type === Operation[\"b\" /* OperationType */].OVERWRITE) {\n var overwrite = operation;\n if (overwrite.source.fromUser) {\n newViewCache = this.applyUserOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, completeCache, accumulator);\n } else {\n Object(assert[\"a\" /* 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 || oldViewCache.getServerCache().isFiltered() && !overwrite.path.isEmpty();\n newViewCache = this.applyServerOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, completeCache, filterServerNode, accumulator);\n }\n } else if (operation.type === Operation[\"b\" /* OperationType */].MERGE) {\n var merge = operation;\n if (merge.source.fromUser) {\n newViewCache = this.applyUserMerge_(oldViewCache, merge.path, merge.children, writesCache, completeCache, accumulator);\n } else {\n Object(assert[\"a\" /* 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, filterServerNode, accumulator);\n }\n } else if (operation.type === Operation[\"b\" /* OperationType */].ACK_USER_WRITE) {\n var ackUserWrite = operation;\n if (!ackUserWrite.revert) {\n newViewCache = this.ackUserWrite_(oldViewCache, ackUserWrite.path, ackUserWrite.affectedTree, writesCache, completeCache, accumulator);\n } else {\n newViewCache = this.revertUserWrite_(oldViewCache, ackUserWrite.path, writesCache, completeCache, accumulator);\n }\n } else if (operation.type === Operation[\"b\" /* OperationType */].LISTEN_COMPLETE) {\n newViewCache = this.listenComplete_(oldViewCache, operation.path, writesCache, accumulator);\n } else {\n throw Object(assert[\"b\" /* assertionError */])('Unknown operation type: ' + operation.type);\n }\n var changes = accumulator.getChanges();\n ViewProcessor.maybeAddValueEvent_(oldViewCache, newViewCache, changes);\n return new ProcessorResult(newViewCache, changes);\n };\n /**\r\n * @param {!ViewCache} oldViewCache\r\n * @param {!ViewCache} newViewCache\r\n * @param {!Array.} accumulator\r\n * @private\r\n */\n ViewProcessor.maybeAddValueEvent_ = function (oldViewCache, newViewCache, accumulator) {\n var eventSnap = newViewCache.getEventCache();\n if (eventSnap.isFullyInitialized()) {\n var isLeafOrEmpty = eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty();\n var oldCompleteSnap = oldViewCache.getCompleteEventSnap();\n if (accumulator.length > 0 || !oldViewCache.getEventCache().isFullyInitialized() || isLeafOrEmpty && !eventSnap.getNode().equals /** @type {!Node} */(oldCompleteSnap) || !eventSnap.getNode().getPriority().equals(oldCompleteSnap.getPriority())) {\n accumulator.push(Change[\"a\" /* Change */].valueChange(\n /** @type {!Node} */newViewCache.getCompleteEventSnap()));\n }\n }\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Path} changePath\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {!CompleteChildSource} source\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.generateEventCacheAfterServerEvent_ = function (viewCache, changePath, writesCache, source, accumulator) {\n var oldEventSnap = viewCache.getEventCache();\n if (writesCache.shadowingWrite(changePath) != null) {\n // we have a shadowing write, ignore changes\n return viewCache;\n } else {\n var newEventCache = void 0,\n serverNode = void 0;\n if (changePath.isEmpty()) {\n // TODO: figure out how this plays with \"sliding ack windows\"\n Object(assert[\"a\" /* assert */])(viewCache.getServerCache().isFullyInitialized(), '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 var serverCache = viewCache.getCompleteServerSnap();\n var completeChildren = serverCache instanceof ChildrenNode[\"a\" /* ChildrenNode */] ? serverCache : ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n var completeEventChildren = writesCache.calcCompleteEventChildren(completeChildren);\n newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeEventChildren, accumulator);\n } else {\n var completeNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\n newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeNode, accumulator);\n }\n } else {\n var childKey = changePath.getFront();\n if (childKey == '.priority') {\n Object(assert[\"a\" /* assert */])(changePath.getLength() == 1, \"Can't have a priority with additional path components\");\n var oldEventNode = oldEventSnap.getNode();\n serverNode = viewCache.getServerCache().getNode();\n // we might have overwrites for this priority\n var 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 var childChangePath = changePath.popFront();\n // update child\n var newEventChild = void 0;\n if (oldEventSnap.isCompleteForChild(childKey)) {\n serverNode = viewCache.getServerCache().getNode();\n var eventChildUpdate = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventSnap.getNode(), serverNode);\n if (eventChildUpdate != null) {\n newEventChild = oldEventSnap.getNode().getImmediateChild(childKey).updateChild(childChangePath, 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, 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(), this.filter_.filtersNodes());\n }\n };\n /**\r\n * @param {!ViewCache} oldViewCache\r\n * @param {!Path} changePath\r\n * @param {!Node} changedSnap\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} completeCache\r\n * @param {boolean} filterServerNode\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.applyServerOverwrite_ = function (oldViewCache, changePath, changedSnap, writesCache, completeCache, filterServerNode, accumulator) {\n var oldServerSnap = oldViewCache.getServerCache();\n var newServerCache;\n var 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 var newServerNode = oldServerSnap.getNode().updateChild(changePath, changedSnap);\n newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), newServerNode, null);\n } else {\n var 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 var childChangePath = changePath.popFront();\n var childNode = oldServerSnap.getNode().getImmediateChild(childKey);\n var 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, NO_COMPLETE_CHILD_SOURCE, null);\n }\n }\n var newViewCache = oldViewCache.updateServerSnap(newServerCache, oldServerSnap.isFullyInitialized() || changePath.isEmpty(), serverFilter.filtersNodes());\n var source = new CompleteChildSource_WriteTreeCompleteChildSource(writesCache, newViewCache, completeCache);\n return this.generateEventCacheAfterServerEvent_(newViewCache, changePath, writesCache, source, accumulator);\n };\n /**\r\n * @param {!ViewCache} oldViewCache\r\n * @param {!Path} changePath\r\n * @param {!Node} changedSnap\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} completeCache\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.applyUserOverwrite_ = function (oldViewCache, changePath, changedSnap, writesCache, completeCache, accumulator) {\n var oldEventSnap = oldViewCache.getEventCache();\n var newViewCache, newEventCache;\n var source = new CompleteChildSource_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 var childKey = changePath.getFront();\n if (childKey === '.priority') {\n newEventCache = this.filter_.updatePriority(oldViewCache.getEventCache().getNode(), changedSnap);\n newViewCache = oldViewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized(), oldEventSnap.isFiltered());\n } else {\n var childChangePath = changePath.popFront();\n var oldChild = oldEventSnap.getNode().getImmediateChild(childKey);\n var newChild = void 0;\n if (childChangePath.isEmpty()) {\n // Child overwrite, we can replace the child\n newChild = changedSnap;\n } else {\n var childNode = source.getCompleteChild(childKey);\n if (childNode != null) {\n if (childChangePath.getBack() === '.priority' && 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[\"a\" /* ChildrenNode */].EMPTY_NODE;\n }\n }\n if (!oldChild.equals(newChild)) {\n var newEventSnap = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newChild, childChangePath, source, accumulator);\n newViewCache = oldViewCache.updateEventSnap(newEventSnap, oldEventSnap.isFullyInitialized(), this.filter_.filtersNodes());\n } else {\n newViewCache = oldViewCache;\n }\n }\n }\n return newViewCache;\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {string} childKey\r\n * @return {boolean}\r\n * @private\r\n */\n ViewProcessor.cacheHasChild_ = function (viewCache, childKey) {\n return viewCache.getEventCache().isCompleteForChild(childKey);\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Path} path\r\n * @param {ImmutableTree.} changedChildren\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} serverCache\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.applyUserMerge_ = function (viewCache, path, changedChildren, writesCache, serverCache, accumulator) {\n var _this = this;\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 var curViewCache = viewCache;\n changedChildren.foreach(function (relativePath, childNode) {\n var writePath = path.child(relativePath);\n if (ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\n curViewCache = _this.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache, serverCache, accumulator);\n }\n });\n changedChildren.foreach(function (relativePath, childNode) {\n var writePath = path.child(relativePath);\n if (!ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\n curViewCache = _this.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache, serverCache, accumulator);\n }\n });\n return curViewCache;\n };\n /**\r\n * @param {!Node} node\r\n * @param {ImmutableTree.} merge\r\n * @return {!Node}\r\n * @private\r\n */\n ViewProcessor.prototype.applyMerge_ = function (node, merge) {\n merge.foreach(function (relativePath, childNode) {\n node = node.updateChild(relativePath, childNode);\n });\n return node;\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Path} path\r\n * @param {!ImmutableTree.} changedChildren\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} serverCache\r\n * @param {boolean} filterServerNode\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.applyServerMerge_ = function (viewCache, path, changedChildren, writesCache, serverCache, filterServerNode, accumulator) {\n var _this = this;\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 // 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 var curViewCache = viewCache;\n var viewMergeTree;\n if (path.isEmpty()) {\n viewMergeTree = changedChildren;\n } else {\n viewMergeTree = ImmutableTree[\"a\" /* ImmutableTree */].Empty.setTree(path, changedChildren);\n }\n var serverNode = viewCache.getServerCache().getNode();\n viewMergeTree.children.inorderTraversal(function (childKey, childTree) {\n if (serverNode.hasChild(childKey)) {\n var serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);\n var newChild = _this.applyMerge_(serverChild, childTree);\n curViewCache = _this.applyServerOverwrite_(curViewCache, new Path[\"a\" /* Path */](childKey), newChild, writesCache, serverCache, filterServerNode, accumulator);\n }\n });\n viewMergeTree.children.inorderTraversal(function (childKey, childMergeTree) {\n var isUnknownDeepMerge = !viewCache.getServerCache().isCompleteForChild(childKey) && childMergeTree.value == null;\n if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {\n var serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);\n var newChild = _this.applyMerge_(serverChild, childMergeTree);\n curViewCache = _this.applyServerOverwrite_(curViewCache, new Path[\"a\" /* Path */](childKey), newChild, writesCache, serverCache, filterServerNode, accumulator);\n }\n });\n return curViewCache;\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Path} ackPath\r\n * @param {!ImmutableTree} affectedTree\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} completeCache\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.ackUserWrite_ = function (viewCache, ackPath, affectedTree, writesCache, completeCache, accumulator) {\n if (writesCache.shadowingWrite(ackPath) != null) {\n return viewCache;\n }\n // Only filter server node if it is currently filtered\n var filterServerNode = viewCache.getServerCache().isFiltered();\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 var 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), 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 var changedChildren_1 = ImmutableTree[\"a\" /* ImmutableTree */].Empty;\n serverCache.getNode().forEachChild(KeyIndex[\"a\" /* KEY_INDEX */], function (name, node) {\n changedChildren_1 = changedChildren_1.set(new Path[\"a\" /* Path */](name), node);\n });\n return this.applyServerMerge_(viewCache, ackPath, changedChildren_1, writesCache, completeCache, filterServerNode, accumulator);\n } else {\n return viewCache;\n }\n } else {\n // This is a merge.\n var changedChildren_2 = ImmutableTree[\"a\" /* ImmutableTree */].Empty;\n affectedTree.foreach(function (mergePath, value) {\n var serverCachePath = ackPath.child(mergePath);\n if (serverCache.isCompleteForPath(serverCachePath)) {\n changedChildren_2 = changedChildren_2.set(mergePath, serverCache.getNode().getChild(serverCachePath));\n }\n });\n return this.applyServerMerge_(viewCache, ackPath, changedChildren_2, writesCache, completeCache, filterServerNode, accumulator);\n }\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Path} path\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.listenComplete_ = function (viewCache, path, writesCache, accumulator) {\n var oldServerNode = viewCache.getServerCache();\n var newViewCache = viewCache.updateServerSnap(oldServerNode.getNode(), oldServerNode.isFullyInitialized() || path.isEmpty(), oldServerNode.isFiltered());\n return this.generateEventCacheAfterServerEvent_(newViewCache, path, writesCache, NO_COMPLETE_CHILD_SOURCE, accumulator);\n };\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Path} path\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} completeServerCache\r\n * @param {!ChildChangeAccumulator} accumulator\r\n * @return {!ViewCache}\r\n * @private\r\n */\n ViewProcessor.prototype.revertUserWrite_ = function (viewCache, path, writesCache, completeServerCache, accumulator) {\n var complete;\n if (writesCache.shadowingWrite(path) != null) {\n return viewCache;\n } else {\n var source = new CompleteChildSource_WriteTreeCompleteChildSource(writesCache, viewCache, completeServerCache);\n var oldEventCache = viewCache.getEventCache().getNode();\n var newEventCache = void 0;\n if (path.isEmpty() || path.getFront() === '.priority') {\n var newNode = void 0;\n if (viewCache.getServerCache().isFullyInitialized()) {\n newNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\n } else {\n var serverChildren = viewCache.getServerCache().getNode();\n Object(assert[\"a\" /* assert */])(serverChildren instanceof ChildrenNode[\"a\" /* ChildrenNode */], 'serverChildren would be complete if leaf node');\n newNode = writesCache.calcCompleteEventChildren(serverChildren);\n }\n newNode = newNode;\n newEventCache = this.filter_.updateFullNode(oldEventCache, newNode, accumulator);\n } else {\n var childKey = path.getFront();\n var 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, 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[\"a\" /* ChildrenNode */].EMPTY_NODE, path.popFront(), 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() || writesCache.shadowingWrite(Path[\"a\" /* Path */].Empty) != null;\n return viewCache.updateEventSnap(newEventCache, complete, this.filter_.filtersNodes());\n }\n };\n return ViewProcessor;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/snap/Node.ts\nvar Node = __webpack_require__(7);\n\n// CONCATENATED MODULE: ./src/database/core/view/EventGenerator.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 * An EventGenerator is used to convert \"raw\" changes (Change) as computed by the\r\n * CacheDiffer into actual events (Event) that can be raised. See generateEventsForChanges()\r\n * for details.\r\n *\r\n * @constructor\r\n */\nvar EventGenerator_EventGenerator = /** @class */function () {\n /**\r\n *\r\n * @param {!Query} query_\r\n */\n function EventGenerator(query_) {\n this.query_ = query_;\n /**\r\n * @private\r\n * @type {!Index}\r\n */\n this.index_ = this.query_.getQueryParams().getIndex();\n }\n /**\r\n * Given a set of raw changes (no moved events and prevName not specified yet), and a set of\r\n * EventRegistrations that should be notified of these changes, generate the actual events to be raised.\r\n *\r\n * Notes:\r\n * - child_moved events will be synthesized at this time for any child_changed events that affect\r\n * our index.\r\n * - prevName will be calculated based on the index ordering.\r\n *\r\n * @param {!Array.} changes\r\n * @param {!Node} eventCache\r\n * @param {!Array.} eventRegistrations\r\n * @return {!Array.}\r\n */\n EventGenerator.prototype.generateEventsForChanges = function (changes, eventCache, eventRegistrations) {\n var _this = this;\n var events = [];\n var moves = [];\n changes.forEach(function (change) {\n if (change.type === Change[\"a\" /* Change */].CHILD_CHANGED && _this.index_.indexedValueChanged(change.oldSnap, change.snapshotNode)) {\n moves.push(Change[\"a\" /* Change */].childMovedChange(change.childName, change.snapshotNode));\n }\n });\n this.generateEventsForType_(events, Change[\"a\" /* Change */].CHILD_REMOVED, changes, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change[\"a\" /* Change */].CHILD_ADDED, changes, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change[\"a\" /* Change */].CHILD_MOVED, moves, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change[\"a\" /* Change */].CHILD_CHANGED, changes, eventRegistrations, eventCache);\n this.generateEventsForType_(events, Change[\"a\" /* Change */].VALUE, changes, eventRegistrations, eventCache);\n return events;\n };\n /**\r\n * Given changes of a single change type, generate the corresponding events.\r\n *\r\n * @param {!Array.} events\r\n * @param {!string} eventType\r\n * @param {!Array.} changes\r\n * @param {!Array.} registrations\r\n * @param {!Node} eventCache\r\n * @private\r\n */\n EventGenerator.prototype.generateEventsForType_ = function (events, eventType, changes, registrations, eventCache) {\n var _this = this;\n var filteredChanges = changes.filter(function (change) {\n return change.type === eventType;\n });\n filteredChanges.sort(this.compareChanges_.bind(this));\n filteredChanges.forEach(function (change) {\n var materializedChange = _this.materializeSingleChange_(change, eventCache);\n registrations.forEach(function (registration) {\n if (registration.respondsTo(change.type)) {\n events.push(registration.createEvent(materializedChange, _this.query_));\n }\n });\n });\n };\n /**\r\n * @param {!Change} change\r\n * @param {!Node} eventCache\r\n * @return {!Change}\r\n * @private\r\n */\n EventGenerator.prototype.materializeSingleChange_ = function (change, eventCache) {\n if (change.type === 'value' || change.type === 'child_removed') {\n return change;\n } else {\n change.prevName = eventCache.getPredecessorChildName(\n /** @type {!string} */\n change.childName, change.snapshotNode, this.index_);\n return change;\n }\n };\n /**\r\n * @param {!Change} a\r\n * @param {!Change} b\r\n * @return {number}\r\n * @private\r\n */\n EventGenerator.prototype.compareChanges_ = function (a, b) {\n if (a.childName == null || b.childName == null) {\n throw Object(assert[\"b\" /* assertionError */])('Should only compare child_ events.');\n }\n var aWrapped = new Node[\"a\" /* NamedNode */](a.childName, a.snapshotNode);\n var bWrapped = new Node[\"a\" /* NamedNode */](b.childName, b.snapshotNode);\n return this.index_.compare(aWrapped, bWrapped);\n };\n return EventGenerator;\n}();\n\n// EXTERNAL MODULE: ./src/database/core/snap/indexes/PriorityIndex.ts\nvar PriorityIndex = __webpack_require__(5);\n\n// CONCATENATED MODULE: ./src/database/core/view/View.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\n\n/**\r\n * A view represents a specific location and query that has 1 or more event registrations.\r\n *\r\n * It does several things:\r\n * - Maintains the list of event registrations for this location/query.\r\n * - Maintains a cache of the data visible for this location/query.\r\n * - Applies new operations (via applyOperation), updates the cache, and based on the event\r\n * registrations returns the set of events to be raised.\r\n * @constructor\r\n */\nvar View_View = /** @class */function () {\n /**\r\n *\r\n * @param {!Query} query_\r\n * @param {!ViewCache} initialViewCache\r\n */\n function View(query_, initialViewCache) {\n this.query_ = query_;\n this.eventRegistrations_ = [];\n var params = this.query_.getQueryParams();\n var indexFilter = new IndexedFilter[\"a\" /* IndexedFilter */](params.getIndex());\n var filter = params.getNodeFilter();\n /**\r\n * @type {ViewProcessor}\r\n * @private\r\n */\n this.processor_ = new ViewProcessor_ViewProcessor(filter);\n var initialServerCache = initialViewCache.getServerCache();\n var initialEventCache = initialViewCache.getEventCache();\n // Don't filter server node with other filter than index, wait for tagged listen\n var serverSnap = indexFilter.updateFullNode(ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE, initialServerCache.getNode(), null);\n var eventSnap = filter.updateFullNode(ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE, initialEventCache.getNode(), null);\n var newServerCache = new CacheNode(serverSnap, initialServerCache.isFullyInitialized(), indexFilter.filtersNodes());\n var newEventCache = new CacheNode(eventSnap, initialEventCache.isFullyInitialized(), filter.filtersNodes());\n /**\r\n * @type {!ViewCache}\r\n * @private\r\n */\n this.viewCache_ = new ViewCache_ViewCache(newEventCache, newServerCache);\n /**\r\n * @type {!EventGenerator}\r\n * @private\r\n */\n this.eventGenerator_ = new EventGenerator_EventGenerator(this.query_);\n }\n /**\r\n * @return {!Query}\r\n */\n View.prototype.getQuery = function () {\n return this.query_;\n };\n /**\r\n * @return {?Node}\r\n */\n View.prototype.getServerCache = function () {\n return this.viewCache_.getServerCache().getNode();\n };\n /**\r\n * @param {!Path} path\r\n * @return {?Node}\r\n */\n View.prototype.getCompleteServerCache = function (path) {\n var 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() || !path.isEmpty() && !cache.getImmediateChild(path.getFront()).isEmpty()) {\n return cache.getChild(path);\n }\n }\n return null;\n };\n /**\r\n * @return {boolean}\r\n */\n View.prototype.isEmpty = function () {\n return this.eventRegistrations_.length === 0;\n };\n /**\r\n * @param {!EventRegistration} eventRegistration\r\n */\n View.prototype.addEventRegistration = function (eventRegistration) {\n this.eventRegistrations_.push(eventRegistration);\n };\n /**\r\n * @param {?EventRegistration} eventRegistration If null, remove all callbacks.\r\n * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\r\n * @return {!Array.} Cancel events, if cancelError was provided.\r\n */\n View.prototype.removeEventRegistration = function (eventRegistration, cancelError) {\n var cancelEvents = [];\n if (cancelError) {\n Object(assert[\"a\" /* assert */])(eventRegistration == null, 'A cancel should cancel all event registrations.');\n var path_1 = this.query_.path;\n this.eventRegistrations_.forEach(function (registration) {\n cancelError /** @type {!Error} */ = cancelError;\n var maybeEvent = registration.createCancelEvent(cancelError, path_1);\n if (maybeEvent) {\n cancelEvents.push(maybeEvent);\n }\n });\n }\n if (eventRegistration) {\n var remaining = [];\n for (var i = 0; i < this.eventRegistrations_.length; ++i) {\n var 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 /**\r\n * Applies the given Operation, updates our cache, and returns the appropriate events.\r\n *\r\n * @param {!Operation} operation\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} completeServerCache\r\n * @return {!Array.}\r\n */\n View.prototype.applyOperation = function (operation, writesCache, completeServerCache) {\n if (operation.type === Operation[\"b\" /* OperationType */].MERGE && operation.source.queryId !== null) {\n Object(assert[\"a\" /* assert */])(this.viewCache_.getCompleteServerSnap(), 'We should always have a full cache before handling merges');\n Object(assert[\"a\" /* assert */])(this.viewCache_.getCompleteEventSnap(), 'Missing event cache, even though we have a server cache');\n }\n var oldViewCache = this.viewCache_;\n var result = this.processor_.applyOperation(oldViewCache, operation, writesCache, completeServerCache);\n this.processor_.assertIndexed(result.viewCache);\n Object(assert[\"a\" /* assert */])(result.viewCache.getServerCache().isFullyInitialized() || !oldViewCache.getServerCache().isFullyInitialized(), 'Once a server snap is complete, it should never go back');\n this.viewCache_ = result.viewCache;\n return this.generateEventsForChanges_(result.changes, result.viewCache.getEventCache().getNode(), null);\n };\n /**\r\n * @param {!EventRegistration} registration\r\n * @return {!Array.}\r\n */\n View.prototype.getInitialEvents = function (registration) {\n var eventSnap = this.viewCache_.getEventCache();\n var initialChanges = [];\n if (!eventSnap.getNode().isLeafNode()) {\n var eventNode = eventSnap.getNode();\n eventNode.forEachChild(PriorityIndex[\"a\" /* PRIORITY_INDEX */], function (key, childNode) {\n initialChanges.push(Change[\"a\" /* Change */].childAddedChange(key, childNode));\n });\n }\n if (eventSnap.isFullyInitialized()) {\n initialChanges.push(Change[\"a\" /* Change */].valueChange(eventSnap.getNode()));\n }\n return this.generateEventsForChanges_(initialChanges, eventSnap.getNode(), registration);\n };\n /**\r\n * @private\r\n * @param {!Array.} changes\r\n * @param {!Node} eventCache\r\n * @param {EventRegistration=} eventRegistration\r\n * @return {!Array.}\r\n */\n View.prototype.generateEventsForChanges_ = function (changes, eventCache, eventRegistration) {\n var registrations = eventRegistration ? [eventRegistration] : this.eventRegistrations_;\n return this.eventGenerator_.generateEventsForChanges(changes, eventCache, registrations);\n };\n return View;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/SyncPoint.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return SyncPoint_SyncPoint; });\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 __referenceConstructor;\n/**\r\n * SyncPoint represents a single location in a SyncTree with 1 or more event registrations, meaning we need to\r\n * maintain 1 or more Views at this location to cache server data and raise appropriate events for server changes\r\n * and user writes (set, transaction, update).\r\n *\r\n * It's responsible for:\r\n * - Maintaining the set of 1 or more views necessary at this location (a SyncPoint with 0 views should be removed).\r\n * - Proxying user / server operations to the views as appropriate (i.e. applyServerOverwrite,\r\n * applyUserOverwrite, etc.)\r\n */\nvar SyncPoint_SyncPoint = /** @class */function () {\n function SyncPoint() {\n /**\r\n * The Views being tracked at this location in the tree, stored as a map where the key is a\r\n * queryId and the value is the View for that query.\r\n *\r\n * NOTE: This list will be quite small (usually 1, but perhaps 2 or 3; any more is an odd use case).\r\n *\r\n * @type {!Object.}\r\n * @private\r\n */\n this.views_ = {};\n }\n Object.defineProperty(SyncPoint, \"__referenceConstructor\", {\n get: function get() {\n Object(assert[\"a\" /* assert */])(__referenceConstructor, 'Reference.ts has not been loaded');\n return __referenceConstructor;\n },\n set: function set(val) {\n Object(assert[\"a\" /* assert */])(!__referenceConstructor, '__referenceConstructor has already been defined');\n __referenceConstructor = val;\n },\n enumerable: true,\n configurable: true\n });\n /**\r\n * @return {boolean}\r\n */\n SyncPoint.prototype.isEmpty = function () {\n return Object(obj[\"j\" /* isEmpty */])(this.views_);\n };\n /**\r\n *\r\n * @param {!Operation} operation\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} optCompleteServerCache\r\n * @return {!Array.}\r\n */\n SyncPoint.prototype.applyOperation = function (operation, writesCache, optCompleteServerCache) {\n var queryId = operation.source.queryId;\n if (queryId !== null) {\n var view = Object(obj[\"l\" /* safeGet */])(this.views_, queryId);\n Object(assert[\"a\" /* assert */])(view != null, 'SyncTree gave us an op for an invalid query.');\n return view.applyOperation(operation, writesCache, optCompleteServerCache);\n } else {\n var events_1 = [];\n Object(obj[\"f\" /* forEach */])(this.views_, function (key, view) {\n events_1 = events_1.concat(view.applyOperation(operation, writesCache, optCompleteServerCache));\n });\n return events_1;\n }\n };\n /**\r\n * Add an event callback for the specified query.\r\n *\r\n * @param {!Query} query\r\n * @param {!EventRegistration} eventRegistration\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} serverCache Complete server cache, if we have it.\r\n * @param {boolean} serverCacheComplete\r\n * @return {!Array.} Events to raise.\r\n */\n SyncPoint.prototype.addEventRegistration = function (query, eventRegistration, writesCache, serverCache, serverCacheComplete) {\n var queryId = query.queryIdentifier();\n var view = Object(obj[\"l\" /* safeGet */])(this.views_, queryId);\n if (!view) {\n // TODO: make writesCache take flag for complete server node\n var eventCache = writesCache.calcCompleteEventCache(serverCacheComplete ? serverCache : null);\n var eventCacheComplete = false;\n if (eventCache) {\n eventCacheComplete = true;\n } else if (serverCache instanceof ChildrenNode[\"a\" /* ChildrenNode */]) {\n eventCache = writesCache.calcCompleteEventChildren(serverCache);\n eventCacheComplete = false;\n } else {\n eventCache = ChildrenNode[\"a\" /* ChildrenNode */].EMPTY_NODE;\n eventCacheComplete = false;\n }\n var viewCache = new ViewCache_ViewCache(new CacheNode /** @type {!Node} */(eventCache, eventCacheComplete, false), new CacheNode /** @type {!Node} */(serverCache, serverCacheComplete, false));\n view = new View_View(query, viewCache);\n this.views_[queryId] = view;\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 /**\r\n * Remove event callback(s). Return cancelEvents if a cancelError is specified.\r\n *\r\n * If query is the default query, we'll check all views for the specified eventRegistration.\r\n * If eventRegistration is null, we'll remove all callbacks for the specified view(s).\r\n *\r\n * @param {!Query} query\r\n * @param {?EventRegistration} eventRegistration If null, remove all callbacks.\r\n * @param {Error=} cancelError If a cancelError is provided, appropriate cancel events will be returned.\r\n * @return {{removed:!Array., events:!Array.}} removed queries and any cancel events\r\n */\n SyncPoint.prototype.removeEventRegistration = function (query, eventRegistration, cancelError) {\n var queryId = query.queryIdentifier();\n var removed = [];\n var cancelEvents = [];\n var hadCompleteView = this.hasCompleteView();\n if (queryId === 'default') {\n // When you do ref.off(...), we search all views for the registration to remove.\n var self_1 = this;\n Object(obj[\"f\" /* forEach */])(this.views_, function (viewQueryId, view) {\n cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));\n if (view.isEmpty()) {\n delete self_1.views_[viewQueryId];\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 var view = Object(obj[\"l\" /* 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 // We'll deal with complete views later.\n if (!view.getQuery().getQueryParams().loadsAllData()) {\n removed.push(view.getQuery());\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 return { removed: removed, events: cancelEvents };\n };\n /**\r\n * @return {!Array.}\r\n */\n SyncPoint.prototype.getQueryViews = function () {\n var _this = this;\n var values = Object.keys(this.views_).map(function (key) {\n return _this.views_[key];\n });\n return values.filter(function (view) {\n return !view.getQuery().getQueryParams().loadsAllData();\n });\n };\n /**\r\n *\r\n * @param {!Path} path The path to the desired complete snapshot\r\n * @return {?Node} A complete cache, if it exists\r\n */\n SyncPoint.prototype.getCompleteServerCache = function (path) {\n var serverCache = null;\n Object(obj[\"f\" /* forEach */])(this.views_, function (key, view) {\n serverCache = serverCache || view.getCompleteServerCache(path);\n });\n return serverCache;\n };\n /**\r\n * @param {!Query} query\r\n * @return {?View}\r\n */\n SyncPoint.prototype.viewForQuery = function (query) {\n var params = query.getQueryParams();\n if (params.loadsAllData()) {\n return this.getCompleteView();\n } else {\n var queryId = query.queryIdentifier();\n return Object(obj[\"l\" /* safeGet */])(this.views_, queryId);\n }\n };\n /**\r\n * @param {!Query} query\r\n * @return {boolean}\r\n */\n SyncPoint.prototype.viewExistsForQuery = function (query) {\n return this.viewForQuery(query) != null;\n };\n /**\r\n * @return {boolean}\r\n */\n SyncPoint.prototype.hasCompleteView = function () {\n return this.getCompleteView() != null;\n };\n /**\r\n * @return {?View}\r\n */\n SyncPoint.prototype.getCompleteView = function () {\n var completeView = Object(obj[\"e\" /* findValue */])(this.views_, function (view) {\n return view.getQuery().getQueryParams().loadsAllData();\n });\n return completeView || null;\n };\n return SyncPoint;\n}();\n\n\n/***/ }),\n/* 51 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/app.ts + 1 modules\nvar app = __webpack_require__(9);\n\n// EXTERNAL MODULE: ./src/utils/obj.ts\nvar obj = __webpack_require__(2);\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// EXTERNAL MODULE: ./src/utils/assert.ts\nvar assert = __webpack_require__(0);\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/database/core/util/Path.ts\nvar Path = __webpack_require__(4);\n\n// CONCATENATED MODULE: ./src/database/core/util/EventEmitter.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 * Base class to be used if you want to emit events. Call the constructor with\r\n * the set of allowed event names.\r\n */\nvar EventEmitter_EventEmitter = /** @class */function () {\n /**\r\n * @param {!Array.} allowedEvents_\r\n */\n function EventEmitter(allowedEvents_) {\n this.allowedEvents_ = allowedEvents_;\n this.listeners_ = {};\n Object(assert[\"a\" /* assert */])(Array.isArray(allowedEvents_) && allowedEvents_.length > 0, 'Requires a non-empty array');\n }\n /**\r\n * To be called by derived classes to trigger events.\r\n * @param {!string} eventType\r\n * @param {...*} var_args\r\n */\n EventEmitter.prototype.trigger = function (eventType) {\n var var_args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n var_args[_i - 1] = arguments[_i];\n }\n if (Array.isArray(this.listeners_[eventType])) {\n // Clone the list, since callbacks could add/remove listeners.\n var listeners = this.listeners_[eventType].slice();\n for (var i = 0; i < listeners.length; i++) {\n listeners[i].callback.apply(listeners[i].context, var_args);\n }\n }\n };\n EventEmitter.prototype.on = function (eventType, callback, context) {\n this.validateEventType_(eventType);\n this.listeners_[eventType] = this.listeners_[eventType] || [];\n this.listeners_[eventType].push({ callback: callback, context: context });\n var eventData = this.getInitialEvent(eventType);\n if (eventData) {\n callback.apply(context, eventData);\n }\n };\n EventEmitter.prototype.off = function (eventType, callback, context) {\n this.validateEventType_(eventType);\n var listeners = this.listeners_[eventType] || [];\n for (var 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 EventEmitter.prototype.validateEventType_ = function (eventType) {\n Object(assert[\"a\" /* assert */])(this.allowedEvents_.find(function (et) {\n return et === eventType;\n }), 'Unknown event: ' + eventType);\n };\n return EventEmitter;\n}();\n\n// CONCATENATED MODULE: ./src/database/core/util/VisibilityMonitor.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 __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/**\r\n * @extends {EventEmitter}\r\n */\nvar VisibilityMonitor_VisibilityMonitor = /** @class */function (_super) {\n __extends(VisibilityMonitor, _super);\n function VisibilityMonitor() {\n var _this = _super.call(this, ['visible']) || this;\n var hidden;\n var visibilityChange;\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 // 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 if (visibilityChange) {\n document.addEventListener(visibilityChange, function () {\n var visible = !document[hidden];\n if (visible !== _this.visible_) {\n _this.visible_ = visible;\n _this.trigger('visible', visible);\n }\n }, false);\n }\n return _this;\n }\n VisibilityMonitor.getInstance = function () {\n return new VisibilityMonitor();\n };\n /**\r\n * @param {!string} eventType\r\n * @return {Array.}\r\n */\n VisibilityMonitor.prototype.getInitialEvent = function (eventType) {\n Object(assert[\"a\" /* assert */])(eventType === 'visible', 'Unknown event type: ' + eventType);\n return [this.visible_];\n };\n return VisibilityMonitor;\n}(EventEmitter_EventEmitter);\n\n// EXTERNAL MODULE: ./src/utils/environment.ts\nvar environment = __webpack_require__(13);\n\n// CONCATENATED MODULE: ./src/database/core/util/OnlineMonitor.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 OnlineMonitor___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/**\r\n * Monitors online state (as reported by window.online/offline events).\r\n *\r\n * The expectation is that this could have many false positives (thinks we are online\r\n * when we're not), but no false negatives. So we can safely use it to determine when\r\n * we definitely cannot reach the internet.\r\n *\r\n * @extends {EventEmitter}\r\n */\nvar OnlineMonitor_OnlineMonitor = /** @class */function (_super) {\n OnlineMonitor___extends(OnlineMonitor, _super);\n function OnlineMonitor() {\n var _this = _super.call(this, ['online']) || this;\n _this.online_ = true;\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' && typeof window.addEventListener !== 'undefined' && !Object(environment[\"a\" /* isMobileCordova */])()) {\n window.addEventListener('online', function () {\n if (!_this.online_) {\n _this.online_ = true;\n _this.trigger('online', true);\n }\n }, false);\n window.addEventListener('offline', function () {\n if (_this.online_) {\n _this.online_ = false;\n _this.trigger('online', false);\n }\n }, false);\n }\n return _this;\n }\n OnlineMonitor.getInstance = function () {\n return new OnlineMonitor();\n };\n /**\r\n * @param {!string} eventType\r\n * @return {Array.}\r\n */\n OnlineMonitor.prototype.getInitialEvent = function (eventType) {\n Object(assert[\"a\" /* assert */])(eventType === 'online', 'Unknown event type: ' + eventType);\n return [this.online_];\n };\n /**\r\n * @return {boolean}\r\n */\n OnlineMonitor.prototype.currentlyOnline = function () {\n return this.online_;\n };\n return OnlineMonitor;\n}(EventEmitter_EventEmitter);\n\n// CONCATENATED MODULE: ./src/utils/jwt.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\n\n/**\r\n * Decodes a Firebase auth. token into constituent parts.\r\n *\r\n * Notes:\r\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n *\r\n * @param {?string} token\r\n * @return {{header: *, claims: *, data: *, signature: string}}\r\n */\nvar jwt_decode = function decode(token) {\n var header = {},\n claims = {},\n data = {},\n signature = '';\n try {\n var parts = token.split('.');\n header = Object(json[\"a\" /* jsonEval */])(Object(util[\"e\" /* base64Decode */])(parts[0]) || '');\n claims = Object(json[\"a\" /* jsonEval */])(Object(util[\"e\" /* base64Decode */])(parts[1]) || '');\n signature = parts[2];\n data = claims['d'] || {};\n delete claims['d'];\n } catch (e) {}\n return {\n header: header,\n claims: claims,\n data: data,\n signature: signature\n };\n};\n/**\r\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\r\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\r\n *\r\n * Notes:\r\n * - May return a false negative if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n *\r\n * @param {?string} token\r\n * @return {boolean}\r\n */\nvar isValidTimestamp = function isValidTimestamp(token) {\n var claims = jwt_decode(token).claims,\n now = Math.floor(new Date().getTime() / 1000),\n validSince,\n validUntil;\n if ((typeof claims === 'undefined' ? 'undefined' : _typeof(claims)) === 'object') {\n if (claims.hasOwnProperty('nbf')) {\n validSince = claims['nbf'];\n } else if (claims.hasOwnProperty('iat')) {\n validSince = claims['iat'];\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 return now && validSince && validUntil && now >= validSince && now <= validUntil;\n};\n/**\r\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\r\n *\r\n * Notes:\r\n * - May return null if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n *\r\n * @param {?string} token\r\n * @return {?number}\r\n */\nvar issuedAtTime = function issuedAtTime(token) {\n var claims = jwt_decode(token).claims;\n if ((typeof claims === 'undefined' ? 'undefined' : _typeof(claims)) === 'object' && claims.hasOwnProperty('iat')) {\n return claims['iat'];\n }\n return null;\n};\n/**\r\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time and non-empty\r\n * signature.\r\n *\r\n * Notes:\r\n * - May return a false negative if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n *\r\n * @param {?string} token\r\n * @return {boolean}\r\n */\nvar isValidFormat = function isValidFormat(token) {\n var decoded = jwt_decode(token),\n claims = decoded.claims;\n return !!decoded.signature && !!claims && (typeof claims === 'undefined' ? 'undefined' : _typeof(claims)) === 'object' && claims.hasOwnProperty('iat');\n};\n/**\r\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\r\n *\r\n * Notes:\r\n * - May return a false negative if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n *\r\n * @param {?string} token\r\n * @return {boolean}\r\n */\nvar isAdmin = function isAdmin(token) {\n var claims = jwt_decode(token).claims;\n return (typeof claims === 'undefined' ? 'undefined' : _typeof(claims)) === 'object' && claims['admin'] === true;\n};\n// EXTERNAL MODULE: ./src/database/realtime/Connection.ts + 1 modules\nvar Connection = __webpack_require__(52);\n\n// EXTERNAL MODULE: ./src/utils/constants.ts\nvar constants = __webpack_require__(17);\n\n// EXTERNAL MODULE: ./src/database/core/ServerActions.ts\nvar ServerActions = __webpack_require__(55);\n\n// CONCATENATED MODULE: ./src/database/core/PersistentConnection.ts\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return PersistentConnection_PersistentConnection; });\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 = /** @class */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_ = Object(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_ && !Object(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_VisibilityMonitor.getInstance().on('visible', _this.onVisible_, _this);\n if (repoInfo_.host.indexOf('fblocal') === -1) {\n OnlineMonitor_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_(Object(json[\"b\" /* stringify */])(msg));\n Object(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 Object(assert[\"a\" /* assert */])(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), 'listen() called for non-default but complete query');\n Object(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' && Object(obj[\"b\" /* contains */])(payload, 'w')) {\n var warnings = Object(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 Object(util[\"B\" /* warn */])(\"Using an unspecified index. Your data will be downloaded and \" + (\"filtered on the client. 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 Object(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 = {\n /*path*/p: pathString,\n /*data*/d: data\n };\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: ' + Object(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'],\n /*isMerge*/false, body['t']);else if (action === 'm') this.onDataUpdate_(body['p'], body['d'],\n /*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 Object(util[\"k\" /* error */])('Unrecognized action received from server: ' + Object(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 Object(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 Object(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 Object(util[\"s\" /* log */])('getToken() completed. Creating connection.');\n self_1.authToken_ = result && result.accessToken;\n connection_1 = new Connection[\"a\" /* Connection */](connId_1, self_1.repoInfo_, onDataMessage_1, onReady_1, onDisconnect_1,\n /* onKill= */function (reason) {\n Object(util[\"B\" /* warn */])(reason + ' (' + self_1.repoInfo_.toString() + ')');\n self_1.interrupt(SERVER_KILL_INTERRUPT_REASON);\n }, lastSessionId_1);\n } else {\n Object(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 (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 Object(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 Object(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 Object(util[\"s\" /* log */])('Resuming connection for reason: ' + reason);\n delete this.interruptReasons_[reason];\n if (Object(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 && /*hash*/'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 Object(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[\"a\" /* 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 (Object(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 Object(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 Object(obj[\"f\" /* forEach */])(this.listens_, function (pathString, queries) {\n Object(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 (constants[\"a\" /* CONSTANTS */].NODE_ADMIN) {\n clientName = 'admin_node';\n } else if (constants[\"a\" /* CONSTANTS */].NODE_CLIENT) {\n clientName = 'node';\n }\n stats['sdk.' + clientName + '.' + app[\"default\"].SDK_VERSION.replace(/\\./g, '-')] = 1;\n if (Object(environment[\"a\" /* isMobileCordova */])()) {\n stats['framework.cordova'] = 1;\n } else if (Object(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_OnlineMonitor.getInstance().currentlyOnline();\n return Object(obj[\"j\" /* isEmpty */])(this.interruptReasons_) && online;\n };\n /**\r\n * @private\r\n */\n 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 */\n PersistentConnection.nextConnectionId_ = 0;\n return PersistentConnection;\n}(ServerActions[\"a\" /* ServerActions */]);\n\n\n/***/ }),\n/* 52 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/database/core/storage/storage.ts + 2 modules\nvar storage = __webpack_require__(18);\n\n// EXTERNAL MODULE: ./src/database/realtime/Constants.ts\nvar Constants = __webpack_require__(19);\n\n// EXTERNAL MODULE: ./src/database/realtime/BrowserPollConnection.ts + 1 modules\nvar BrowserPollConnection = __webpack_require__(53);\n\n// EXTERNAL MODULE: ./src/database/realtime/WebSocketConnection.ts\nvar WebSocketConnection = __webpack_require__(54);\n\n// CONCATENATED MODULE: ./src/database/realtime/TransportManager.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 * 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 = /** @class */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[\"a\" /* BrowserPollConnection */], 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 = WebSocketConnection[\"a\" /* WebSocketConnection */] && WebSocketConnection[\"a\" /* WebSocketConnection */]['isAvailable']();\n var isSkipPollConnection = isWebSocketsAvailable && !WebSocketConnection[\"a\" /* WebSocketConnection */].previouslyFailed();\n if (repoInfo.webSocketOnly) {\n if (!isWebSocketsAvailable) Object(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_ = [WebSocketConnection[\"a\" /* WebSocketConnection */]];\n } else {\n var transports_1 = this.transports_ = [];\n Object(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 export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Connection_Connection; });\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 = /** @class */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_ = Object(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_ = Object(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 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 = Object(util[\"w\" /* requireKey */])('t', parsedData);\n var data = Object(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 = Object(util[\"w\" /* requireKey */])('t', parsedData);\n var data = Object(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 Connection.prototype.onControl_ = function (controlData) {\n var cmd = Object(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 Object(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 Object(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 (Constants[\"e\" /* PROTOCOL_VERSION */] !== version) {\n Object(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 Object(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 Object(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 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\n/***/ }),\n/* 53 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXTERNAL MODULE: ./src/database/core/util/util.ts + 3 modules\nvar util = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./src/database/core/util/CountedSet.ts\nvar CountedSet = __webpack_require__(49);\n\n// EXTERNAL MODULE: ./src/database/core/stats/StatsManager.ts + 1 modules\nvar StatsManager = __webpack_require__(29);\n\n// CONCATENATED MODULE: ./src/database/realtime/polling/PacketReceiver.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 * This class ensures the packets from the server arrive in order\r\n * This class takes data from the server and ensures it gets passed into the callbacks in order.\r\n * @constructor\r\n */\nvar PacketReceiver_PacketReceiver = /** @class */function () {\n /**\r\n * @param onMessage_\r\n */\n function PacketReceiver(onMessage_) {\n this.onMessage_ = onMessage_;\n this.pendingResponses = [];\n this.currentResponseNum = 0;\n this.closeAfterResponse = -1;\n this.onClose = null;\n }\n PacketReceiver.prototype.closeAfter = function (responseNum, callback) {\n this.closeAfterResponse = responseNum;\n this.onClose = callback;\n if (this.closeAfterResponse < this.currentResponseNum) {\n this.onClose();\n this.onClose = null;\n }\n };\n /**\r\n * Each message from the server comes with a response number, and an array of data. The responseNumber\r\n * allows us to ensure that we process them in the right order, since we can't be guaranteed that all\r\n * browsers will respond in the same order as the requests we sent\r\n * @param {number} requestNum\r\n * @param {Array} data\r\n */\n PacketReceiver.prototype.handleResponse = function (requestNum, data) {\n var _this = this;\n this.pendingResponses[requestNum] = data;\n var _loop_1 = function _loop_1() {\n var toProcess = this_1.pendingResponses[this_1.currentResponseNum];\n delete this_1.pendingResponses[this_1.currentResponseNum];\n var _loop_2 = function _loop_2(i) {\n if (toProcess[i]) {\n Object(util[\"m\" /* exceptionGuard */])(function () {\n _this.onMessage_(toProcess[i]);\n });\n }\n };\n for (var i = 0; i < toProcess.length; ++i) {\n _loop_2(i);\n }\n if (this_1.currentResponseNum === this_1.closeAfterResponse) {\n if (this_1.onClose) {\n this_1.onClose();\n this_1.onClose = null;\n }\n return \"break\";\n }\n this_1.currentResponseNum++;\n };\n var this_1 = this;\n while (this.pendingResponses[this.currentResponseNum]) {\n var state_1 = _loop_1();\n if (state_1 === \"break\") break;\n }\n };\n return PacketReceiver;\n}();\n\n// EXTERNAL MODULE: ./src/database/realtime/Constants.ts\nvar Constants = __webpack_require__(19);\n\n// EXTERNAL MODULE: ./src/utils/json.ts\nvar json = __webpack_require__(8);\n\n// EXTERNAL MODULE: ./src/utils/environment.ts\nvar environment = __webpack_require__(13);\n\n// CONCATENATED MODULE: ./src/database/realtime/BrowserPollConnection.ts\n/* unused harmony export FIREBASE_LONGPOLL_START_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_CLOSE_COMMAND */\n/* unused harmony export FIREBASE_LONGPOLL_COMMAND_CB_NAME */\n/* unused harmony export FIREBASE_LONGPOLL_DATA_CB_NAME */\n/* unused harmony export FIREBASE_LONGPOLL_ID_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_PW_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_SERIAL_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_CALLBACK_ID_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET */\n/* unused harmony export FIREBASE_LONGPOLL_DATA_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM */\n/* unused harmony export FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return BrowserPollConnection_BrowserPollConnection; });\n/* unused harmony export FirebaseIFrameScriptHolder */\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// URL query parameters associated with longpolling\nvar FIREBASE_LONGPOLL_START_PARAM = 'start';\nvar FIREBASE_LONGPOLL_CLOSE_COMMAND = 'close';\nvar FIREBASE_LONGPOLL_COMMAND_CB_NAME = 'pLPCommand';\nvar FIREBASE_LONGPOLL_DATA_CB_NAME = 'pRTLPCB';\nvar FIREBASE_LONGPOLL_ID_PARAM = 'id';\nvar FIREBASE_LONGPOLL_PW_PARAM = 'pw';\nvar FIREBASE_LONGPOLL_SERIAL_PARAM = 'ser';\nvar FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = 'cb';\nvar FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = 'seg';\nvar FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = 'ts';\nvar FIREBASE_LONGPOLL_DATA_PARAM = 'd';\nvar FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = 'disconn';\nvar FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = 'dframe';\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.\nvar MAX_URL_DATA_SIZE = 1870;\nvar SEG_HEADER_SIZE = 30; //ie: &seg=8299234&ts=982389123&d=\nvar MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE;\n/**\r\n * Keepalive period\r\n * send a fresh request at minimum every 25 seconds. Opera has a maximum request\r\n * length of 30 seconds that we can't exceed.\r\n * @const\r\n * @type {number}\r\n */\nvar KEEPALIVE_REQUEST_INTERVAL = 25000;\n/**\r\n * How long to wait before aborting a long-polling connection attempt.\r\n * @const\r\n * @type {number}\r\n */\nvar LP_CONNECT_TIMEOUT = 30000;\n/**\r\n * This class manages a single long-polling connection.\r\n *\r\n * @constructor\r\n * @implements {Transport}\r\n */\nvar BrowserPollConnection_BrowserPollConnection = /** @class */function () {\n /**\r\n * @param {string} connId An identifier for this connection, used for logging\r\n * @param {RepoInfo} repoInfo The info for the endpoint to send data to.\r\n * @param {string=} transportSessionId Optional transportSessionid if we are reconnecting for an existing\r\n * transport session\r\n * @param {string=} lastSessionId Optional lastSessionId if the PersistentConnection has already created a\r\n * connection previously\r\n */\n function BrowserPollConnection(connId, repoInfo, transportSessionId, lastSessionId) {\n this.connId = connId;\n this.repoInfo = repoInfo;\n this.transportSessionId = transportSessionId;\n this.lastSessionId = lastSessionId;\n this.bytesSent = 0;\n this.bytesReceived = 0;\n this.everConnected_ = false;\n this.log_ = Object(util[\"t\" /* logWrapper */])(connId);\n this.stats_ = StatsManager[\"a\" /* StatsManager */].getCollection(repoInfo);\n this.urlFn = function (params) {\n return repoInfo.connectionURL(Constants[\"d\" /* LONG_POLLING */], params);\n };\n }\n /**\r\n *\r\n * @param {function(Object)} onMessage Callback when messages arrive\r\n * @param {function()} onDisconnect Callback with connection lost.\r\n */\n BrowserPollConnection.prototype.open = function (onMessage, onDisconnect) {\n var _this = this;\n this.curSegmentNum = 0;\n this.onDisconnect_ = onDisconnect;\n this.myPacketOrderer = new PacketReceiver_PacketReceiver(onMessage);\n this.isClosed_ = false;\n this.connectTimeoutTimer_ = setTimeout(function () {\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));\n // Ensure we delay the creation of the iframe until the DOM is loaded.\n Object(util[\"n\" /* executeWhenDOMReady */])(function () {\n if (_this.isClosed_) return;\n //Set up a callback that gets triggered once a connection is set up.\n _this.scriptTagHolder = new BrowserPollConnection_FirebaseIFrameScriptHolder(function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var command = args[0],\n arg1 = args[1],\n arg2 = args[2],\n arg3 = args[3],\n arg4 = args[4];\n _this.incrementIncomingBytes_(args);\n if (!_this.scriptTagHolder) return; // we closed the connection.\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 // 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, function () {\n _this.onClosed_();\n });\n } else {\n _this.onClosed_();\n }\n } else {\n throw new Error('Unrecognized command received: ' + command);\n }\n }, function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var pN = args[0],\n data = args[1];\n _this.incrementIncomingBytes_(args);\n _this.myPacketOrderer.handleResponse(pN, data);\n }, function () {\n _this.onClosed_();\n }, _this.urlFn);\n //Send the initial request to connect. The serial number is simply to keep the browser from pulling previous results\n //from cache.\n var urlParams = {};\n urlParams[FIREBASE_LONGPOLL_START_PARAM] = 't';\n urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(Math.random() * 100000000);\n if (_this.scriptTagHolder.uniqueCallbackIdentifier) urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = _this.scriptTagHolder.uniqueCallbackIdentifier;\n urlParams[Constants[\"h\" /* VERSION_PARAM */]] = Constants[\"e\" /* PROTOCOL_VERSION */];\n if (_this.transportSessionId) {\n urlParams[Constants[\"g\" /* TRANSPORT_SESSION_PARAM */]] = _this.transportSessionId;\n }\n if (_this.lastSessionId) {\n urlParams[Constants[\"c\" /* LAST_SESSION_PARAM */]] = _this.lastSessionId;\n }\n if (!Object(environment[\"b\" /* isNodeSdk */])() && typeof location !== 'undefined' && location.href && location.href.indexOf(Constants[\"a\" /* FORGE_DOMAIN */]) !== -1) {\n urlParams[Constants[\"f\" /* REFERER_PARAM */]] = Constants[\"b\" /* FORGE_REF */];\n }\n var connectURL = _this.urlFn(urlParams);\n _this.log_('Connecting via long-poll to ' + connectURL);\n _this.scriptTagHolder.addTag(connectURL, function () {\n /* do nothing */\n });\n });\n };\n /**\r\n * Call this when a handshake has completed successfully and we want to consider the connection established\r\n */\n BrowserPollConnection.prototype.start = function () {\n this.scriptTagHolder.startLongPoll(this.id, this.password);\n this.addDisconnectPingFrame(this.id, this.password);\n };\n /**\r\n * Forces long polling to be considered as a potential transport\r\n */\n BrowserPollConnection.forceAllow = function () {\n BrowserPollConnection.forceAllow_ = true;\n };\n /**\r\n * Forces longpolling to not be considered as a potential transport\r\n */\n BrowserPollConnection.forceDisallow = function () {\n BrowserPollConnection.forceDisallow_ = true;\n };\n // Static method, use string literal so it can be accessed in a generic way\n BrowserPollConnection.isAvailable = function () {\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_ || !BrowserPollConnection.forceDisallow_ && typeof document !== 'undefined' && document.createElement != null && !Object(util[\"p\" /* isChromeExtensionContentScript */])() && !Object(util[\"r\" /* isWindowsStoreApp */])() && !Object(environment[\"b\" /* isNodeSdk */])();\n };\n /**\r\n * No-op for polling\r\n */\n BrowserPollConnection.prototype.markConnectionHealthy = function () {};\n /**\r\n * Stops polling and cleans up the iframe\r\n * @private\r\n */\n BrowserPollConnection.prototype.shutdown_ = function () {\n this.isClosed_ = true;\n if (this.scriptTagHolder) {\n this.scriptTagHolder.close();\n this.scriptTagHolder = null;\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 if (this.connectTimeoutTimer_) {\n clearTimeout(this.connectTimeoutTimer_);\n this.connectTimeoutTimer_ = null;\n }\n };\n /**\r\n * Triggered when this transport is closed\r\n * @private\r\n */\n BrowserPollConnection.prototype.onClosed_ = function () {\n if (!this.isClosed_) {\n this.log_('Longpoll is closing itself');\n this.shutdown_();\n if (this.onDisconnect_) {\n this.onDisconnect_(this.everConnected_);\n this.onDisconnect_ = null;\n }\n }\n };\n /**\r\n * External-facing close handler. RealTime has requested we shut down. Kill our connection and tell the server\r\n * that we've left.\r\n */\n BrowserPollConnection.prototype.close = function () {\n if (!this.isClosed_) {\n this.log_('Longpoll is being closed.');\n this.shutdown_();\n }\n };\n /**\r\n * Send the JSON object down to the server. It will need to be stringified, base64 encoded, and then\r\n * broken into chunks (since URLs have a small maximum length).\r\n * @param {!Object} data The JSON data to transmit.\r\n */\n BrowserPollConnection.prototype.send = function (data) {\n var dataStr = Object(json[\"b\" /* stringify */])(data);\n this.bytesSent += dataStr.length;\n this.stats_.incrementCounter('bytes_sent', dataStr.length);\n //first, lets get the base64-encoded data\n var base64data = Object(util[\"f\" /* base64Encode */])(dataStr);\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 var dataSegs = Object(util[\"z\" /* splitStringBySize */])(base64data, MAX_PAYLOAD_SIZE);\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 (var i = 0; i < dataSegs.length; i++) {\n this.scriptTagHolder.enqueueSegment(this.curSegmentNum, dataSegs.length, dataSegs[i]);\n this.curSegmentNum++;\n }\n };\n /**\r\n * This is how we notify the server that we're leaving.\r\n * We aren't able to send requests with DHTML on a window close event, but we can\r\n * trigger XHR requests in some browsers (everything but Opera basically).\r\n * @param {!string} id\r\n * @param {!string} pw\r\n */\n BrowserPollConnection.prototype.addDisconnectPingFrame = function (id, pw) {\n if (Object(environment[\"b\" /* isNodeSdk */])()) return;\n this.myDisconnFrame = document.createElement('iframe');\n var urlParams = {};\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 document.body.appendChild(this.myDisconnFrame);\n };\n /**\r\n * Used to track the bytes received by this client\r\n * @param {*} args\r\n * @private\r\n */\n BrowserPollConnection.prototype.incrementIncomingBytes_ = function (args) {\n // TODO: This is an annoying perf hit just to track the number of incoming bytes. Maybe it should be opt-in.\n var bytesReceived = Object(json[\"b\" /* stringify */])(args).length;\n this.bytesReceived += bytesReceived;\n this.stats_.incrementCounter('bytes_received', bytesReceived);\n };\n return BrowserPollConnection;\n}();\n\n/*********************************************************************************************\r\n * A wrapper around an iframe that is used as a long-polling script holder.\r\n * @constructor\r\n *********************************************************************************************/\nvar BrowserPollConnection_FirebaseIFrameScriptHolder = /** @class */function () {\n /**\r\n * @param commandCB - The callback to be called when control commands are recevied from the server.\r\n * @param onMessageCB - The callback to be triggered when responses arrive from the server.\r\n * @param onDisconnect - The callback to be triggered when this tag holder is closed\r\n * @param urlFn - A function that provides the URL of the endpoint to send data to.\r\n */\n function FirebaseIFrameScriptHolder(commandCB, onMessageCB, onDisconnect, urlFn) {\n this.onDisconnect = onDisconnect;\n this.urlFn = urlFn;\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 /**\r\n * @type {CountedSet.}\r\n */\n this.outstandingRequests = new CountedSet[\"a\" /* CountedSet */]();\n //A queue of the pending segments waiting for transmission to the server.\n this.pendingSegs = [];\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 this.currentSerial = Math.floor(Math.random() * 100000000);\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 this.sendNewPolls = true;\n if (!Object(environment[\"b\" /* 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 = Object(util[\"a\" /* LUIDGenerator */])();\n window[FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier] = commandCB;\n window[FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier] = onMessageCB;\n //Create an iframe for us to add script tags to.\n this.myIFrame = FirebaseIFrameScriptHolder.createIFrame_();\n // Set the iframe's contents.\n var 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 var currentDomain = document.domain;\n script = '';\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 Object(util[\"s\" /* log */])('frame writing exception');\n if (e.stack) {\n Object(util[\"s\" /* log */])(e.stack);\n }\n Object(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 Object(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 (Object(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 /**\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 /**\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 /**\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 /**\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 (Object(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 Object(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\n/***/ }),\n/* 54 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(process) {/* unused harmony export setWebSocketImpl */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return WebSocketConnection; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__app__ = __webpack_require__(9);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_assert__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_stats_StatsManager__ = __webpack_require__(29);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Constants__ = __webpack_require__(19);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_constants__ = __webpack_require__(17);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_storage_storage__ = __webpack_require__(18);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__utils_json__ = __webpack_require__(8);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_environment__ = __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\n\n\n\n\n\n\n\nvar WEBSOCKET_MAX_FRAME_SIZE = 16384;\nvar WEBSOCKET_KEEPALIVE_INTERVAL = 45000;\nvar WebSocketImpl = null;\nif (typeof MozWebSocket !== 'undefined') {\n WebSocketImpl = MozWebSocket;\n} else if (typeof WebSocket !== 'undefined') {\n WebSocketImpl = WebSocket;\n}\nfunction setWebSocketImpl(impl) {\n WebSocketImpl = impl;\n}\n/**\r\n * Create a new websocket connection with the given callbacks.\r\n * @constructor\r\n * @implements {Transport}\r\n */\nvar WebSocketConnection = /** @class */function () {\n /**\r\n * @param {string} connId identifier for this transport\r\n * @param {RepoInfo} repoInfo The info for the websocket endpoint.\r\n * @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport\r\n * session\r\n * @param {string=} lastSessionId Optional lastSessionId if there was a previous connection\r\n */\n function WebSocketConnection(connId, repoInfo, transportSessionId, lastSessionId) {\n this.connId = connId;\n this.keepaliveTimer = null;\n this.frames = null;\n this.totalFrames = 0;\n this.bytesSent = 0;\n this.bytesReceived = 0;\n this.log_ = Object(__WEBPACK_IMPORTED_MODULE_2__core_util_util__[\"t\" /* logWrapper */])(this.connId);\n this.stats_ = __WEBPACK_IMPORTED_MODULE_3__core_stats_StatsManager__[\"a\" /* StatsManager */].getCollection(repoInfo);\n this.connURL = WebSocketConnection.connectionURL_(repoInfo, transportSessionId, lastSessionId);\n }\n /**\r\n * @param {RepoInfo} repoInfo The info for the websocket endpoint.\r\n * @param {string=} transportSessionId Optional transportSessionId if this is connecting to an existing transport\r\n * session\r\n * @param {string=} lastSessionId Optional lastSessionId if there was a previous connection\r\n * @return {string} connection url\r\n * @private\r\n */\n WebSocketConnection.connectionURL_ = function (repoInfo, transportSessionId, lastSessionId) {\n var urlParams = {};\n urlParams[__WEBPACK_IMPORTED_MODULE_4__Constants__[\"h\" /* VERSION_PARAM */]] = __WEBPACK_IMPORTED_MODULE_4__Constants__[\"e\" /* PROTOCOL_VERSION */];\n if (!Object(__WEBPACK_IMPORTED_MODULE_8__utils_environment__[\"b\" /* isNodeSdk */])() && typeof location !== 'undefined' && location.href && location.href.indexOf(__WEBPACK_IMPORTED_MODULE_4__Constants__[\"a\" /* FORGE_DOMAIN */]) !== -1) {\n urlParams[__WEBPACK_IMPORTED_MODULE_4__Constants__[\"f\" /* REFERER_PARAM */]] = __WEBPACK_IMPORTED_MODULE_4__Constants__[\"b\" /* FORGE_REF */];\n }\n if (transportSessionId) {\n urlParams[__WEBPACK_IMPORTED_MODULE_4__Constants__[\"g\" /* TRANSPORT_SESSION_PARAM */]] = transportSessionId;\n }\n if (lastSessionId) {\n urlParams[__WEBPACK_IMPORTED_MODULE_4__Constants__[\"c\" /* LAST_SESSION_PARAM */]] = lastSessionId;\n }\n return repoInfo.connectionURL(__WEBPACK_IMPORTED_MODULE_4__Constants__[\"i\" /* WEBSOCKET */], urlParams);\n };\n /**\r\n *\r\n * @param onMessage Callback when messages arrive\r\n * @param onDisconnect Callback with connection lost.\r\n */\n WebSocketConnection.prototype.open = function (onMessage, onDisconnect) {\n var _this = this;\n this.onDisconnect = onDisconnect;\n this.onMessage = onMessage;\n this.log_('Websocket connecting to ' + this.connURL);\n this.everConnected_ = false;\n // Assume failure until proven otherwise.\n __WEBPACK_IMPORTED_MODULE_6__core_storage_storage__[\"a\" /* PersistentStorage */].set('previous_websocket_failure', true);\n try {\n if (Object(__WEBPACK_IMPORTED_MODULE_8__utils_environment__[\"b\" /* isNodeSdk */])()) {\n var device = __WEBPACK_IMPORTED_MODULE_5__utils_constants__[\"a\" /* CONSTANTS */].NODE_ADMIN ? 'AdminNode' : 'Node';\n // UA Format: Firebase////\n var options = {\n headers: {\n 'User-Agent': \"Firebase/\" + __WEBPACK_IMPORTED_MODULE_4__Constants__[\"e\" /* PROTOCOL_VERSION */] + \"/\" + __WEBPACK_IMPORTED_MODULE_0__app__[\"default\"].SDK_VERSION + \"/\" + process.platform + \"/\" + device\n }\n };\n // Plumb appropriate http_proxy environment variable into faye-websocket if it exists.\n var env = process['env'];\n var proxy = this.connURL.indexOf('wss://') == 0 ? env['HTTPS_PROXY'] || env['https_proxy'] : env['HTTP_PROXY'] || env['http_proxy'];\n if (proxy) {\n options['proxy'] = { origin: proxy };\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 var error = e.message || e.data;\n if (error) {\n this.log_(error);\n }\n this.onClosed_();\n return;\n }\n this.mySock.onopen = function () {\n _this.log_('Websocket connected.');\n _this.everConnected_ = true;\n };\n this.mySock.onclose = function () {\n _this.log_('Websocket connection was disconnected.');\n _this.mySock = null;\n _this.onClosed_();\n };\n this.mySock.onmessage = function (m) {\n _this.handleIncomingFrame(m);\n };\n this.mySock.onerror = function (e) {\n _this.log_('WebSocket error. Closing connection.');\n var error = e.message || e.data;\n if (error) {\n _this.log_(error);\n }\n _this.onClosed_();\n };\n };\n /**\r\n * No-op for websockets, we don't need to do anything once the connection is confirmed as open\r\n */\n WebSocketConnection.prototype.start = function () {};\n WebSocketConnection.forceDisallow = function () {\n WebSocketConnection.forceDisallow_ = true;\n };\n WebSocketConnection.isAvailable = function () {\n var isOldAndroid = false;\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n var oldAndroidRegex = /Android ([0-9]{0,}\\.[0-9]{0,})/;\n var 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 return !isOldAndroid && WebSocketImpl !== null && !WebSocketConnection.forceDisallow_;\n };\n /**\r\n * Returns true if we previously failed to connect with this transport.\r\n * @return {boolean}\r\n */\n WebSocketConnection.previouslyFailed = function () {\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 __WEBPACK_IMPORTED_MODULE_6__core_storage_storage__[\"a\" /* PersistentStorage */].isInMemoryStorage || __WEBPACK_IMPORTED_MODULE_6__core_storage_storage__[\"a\" /* PersistentStorage */].get('previous_websocket_failure') === true;\n };\n WebSocketConnection.prototype.markConnectionHealthy = function () {\n __WEBPACK_IMPORTED_MODULE_6__core_storage_storage__[\"a\" /* PersistentStorage */].remove('previous_websocket_failure');\n };\n WebSocketConnection.prototype.appendFrame_ = function (data) {\n this.frames.push(data);\n if (this.frames.length == this.totalFrames) {\n var fullMess = this.frames.join('');\n this.frames = null;\n var jsonMess = Object(__WEBPACK_IMPORTED_MODULE_7__utils_json__[\"a\" /* jsonEval */])(fullMess);\n //handle the message\n this.onMessage(jsonMess);\n }\n };\n /**\r\n * @param {number} frameCount The number of frames we are expecting from the server\r\n * @private\r\n */\n WebSocketConnection.prototype.handleNewFrameCount_ = function (frameCount) {\n this.totalFrames = frameCount;\n this.frames = [];\n };\n /**\r\n * Attempts to parse a frame count out of some text. If it can't, assumes a value of 1\r\n * @param {!String} data\r\n * @return {?String} Any remaining data to be process, or null if there is none\r\n * @private\r\n */\n WebSocketConnection.prototype.extractFrameCount_ = function (data) {\n Object(__WEBPACK_IMPORTED_MODULE_1__utils_assert__[\"a\" /* 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 var 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 /**\r\n * Process a websocket frame that has arrived from the server.\r\n * @param mess The frame data\r\n */\n WebSocketConnection.prototype.handleIncomingFrame = function (mess) {\n if (this.mySock === null) return; // Chrome apparently delivers incoming packets even after we .close() the connection sometimes.\n var data = mess['data'];\n this.bytesReceived += data.length;\n this.stats_.incrementCounter('bytes_received', data.length);\n this.resetKeepAlive();\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 var remainingData = this.extractFrameCount_(data);\n if (remainingData !== null) {\n this.appendFrame_(remainingData);\n }\n }\n };\n /**\r\n * Send a message to the server\r\n * @param {Object} data The JSON object to transmit\r\n */\n WebSocketConnection.prototype.send = function (data) {\n this.resetKeepAlive();\n var dataStr = Object(__WEBPACK_IMPORTED_MODULE_7__utils_json__[\"b\" /* stringify */])(data);\n this.bytesSent += dataStr.length;\n this.stats_.incrementCounter('bytes_sent', dataStr.length);\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 var dataSegs = Object(__WEBPACK_IMPORTED_MODULE_2__core_util_util__[\"z\" /* splitStringBySize */])(dataStr, WEBSOCKET_MAX_FRAME_SIZE);\n //Send the length header\n if (dataSegs.length > 1) {\n this.sendString_(String(dataSegs.length));\n }\n //Send the actual data in segments.\n for (var i = 0; i < dataSegs.length; i++) {\n this.sendString_(dataSegs[i]);\n }\n };\n WebSocketConnection.prototype.shutdown_ = function () {\n this.isClosed_ = true;\n if (this.keepaliveTimer) {\n clearInterval(this.keepaliveTimer);\n this.keepaliveTimer = null;\n }\n if (this.mySock) {\n this.mySock.close();\n this.mySock = null;\n }\n };\n WebSocketConnection.prototype.onClosed_ = function () {\n if (!this.isClosed_) {\n this.log_('WebSocket is closing itself');\n this.shutdown_();\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 /**\r\n * External-facing close handler.\r\n * Close the websocket and kill the connection.\r\n */\n WebSocketConnection.prototype.close = function () {\n if (!this.isClosed_) {\n this.log_('WebSocket is being closed');\n this.shutdown_();\n }\n };\n /**\r\n * Kill the current keepalive timer and start a new one, to ensure that it always fires N seconds after\r\n * the last activity.\r\n */\n WebSocketConnection.prototype.resetKeepAlive = function () {\n var _this = this;\n clearInterval(this.keepaliveTimer);\n this.keepaliveTimer = setInterval(function () {\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));\n };\n /**\r\n * Send a string over the websocket.\r\n *\r\n * @param {string} str String to send.\r\n * @private\r\n */\n WebSocketConnection.prototype.sendString_ = function (str) {\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 /**\r\n * Number of response before we consider the connection \"healthy.\"\r\n * @type {number}\r\n */\n WebSocketConnection.responsesRequiredToBeHealthy = 2;\n /**\r\n * Time to wait for the connection te become healthy before giving up.\r\n * @type {number}\r\n */\n WebSocketConnection.healthyTimeout = 30000;\n return WebSocketConnection;\n}();\n\n/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(34)))\n\n/***/ }),\n/* 55 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return ServerActions; });\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 = /** @class */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\n/***/ }),\n/* 56 */,\n/* 57 */,\n/* 58 */,\n/* 59 */,\n/* 60 */,\n/* 61 */,\n/* 62 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* WEBPACK VAR INJECTION */(function(module) {/* harmony export (immutable) */ __webpack_exports__[\"registerDatabase\"] = registerDatabase;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__app__ = __webpack_require__(9);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__database_api_Database__ = __webpack_require__(36);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__database_api_Query__ = __webpack_require__(39);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__database_api_Reference__ = __webpack_require__(26);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__database_core_util_util__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__database_core_RepoManager__ = __webpack_require__(30);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__database_api_internal__ = __webpack_require__(64);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__database_api_test_access__ = __webpack_require__(65);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_environment__ = __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\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, unused, url) {\n return __WEBPACK_IMPORTED_MODULE_5__database_core_RepoManager__[\"a\" /* RepoManager */].getInstance().databaseFromApp(app, url);\n },\n // firebase.database namespace properties\n {\n Reference: __WEBPACK_IMPORTED_MODULE_3__database_api_Reference__[\"a\" /* Reference */],\n Query: __WEBPACK_IMPORTED_MODULE_2__database_api_Query__[\"a\" /* Query */],\n Database: __WEBPACK_IMPORTED_MODULE_1__database_api_Database__[\"a\" /* Database */],\n enableLogging: __WEBPACK_IMPORTED_MODULE_4__database_core_util_util__[\"j\" /* enableLogging */],\n INTERNAL: __WEBPACK_IMPORTED_MODULE_6__database_api_internal__,\n ServerValue: __WEBPACK_IMPORTED_MODULE_1__database_api_Database__[\"a\" /* Database */].ServerValue,\n TEST_ACCESS: __WEBPACK_IMPORTED_MODULE_7__database_api_test_access__\n }, null, true);\n if (Object(__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__(63)(module)))\n\n/***/ }),\n/* 63 */\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/* 64 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"forceLongPolling\", function() { return forceLongPolling; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"forceWebSockets\", function() { return forceWebSockets; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"isWebSocketsAvailable\", function() { return isWebSocketsAvailable; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"setSecurityDebugCallback\", function() { return setSecurityDebugCallback; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"stats\", function() { return stats; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"statsIncrementCounter\", function() { return statsIncrementCounter; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"dataUpdateCount\", function() { return dataUpdateCount; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"interceptServerData\", function() { return interceptServerData; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__ = __webpack_require__(54);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__realtime_BrowserPollConnection__ = __webpack_require__(53);\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 forceLongPolling = function forceLongPolling() {\n __WEBPACK_IMPORTED_MODULE_0__realtime_WebSocketConnection__[\"a\" /* WebSocketConnection */].forceDisallow();\n __WEBPACK_IMPORTED_MODULE_1__realtime_BrowserPollConnection__[\"a\" /* BrowserPollConnection */].forceAllow();\n};\nvar forceWebSockets = function forceWebSockets() {\n __WEBPACK_IMPORTED_MODULE_1__realtime_BrowserPollConnection__[\"a\" /* 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 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\n/***/ }),\n/* 65 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"DataConnection\", function() { return DataConnection; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"RealTimeConnection\", function() { return RealTimeConnection; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"hijackHash\", function() { return hijackHash; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ConnectionTarget\", function() { return ConnectionTarget; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"queryIdentifier\", function() { return queryIdentifier; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"listens\", function() { return listens; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"forceRestClient\", function() { return forceRestClient; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_RepoInfo__ = __webpack_require__(38);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__ = __webpack_require__(51);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_RepoManager__ = __webpack_require__(30);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__realtime_Connection__ = __webpack_require__(52);\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 = __WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__[\"a\" /* PersistentConnection */];\n/**\r\n * @param {!string} pathString\r\n * @param {function(*)} onComplete\r\n */\n__WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__[\"a\" /* 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 */\n__WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__[\"a\" /* PersistentConnection */].prototype.echo = function (data, onEcho) {\n this.sendRequest('echo', { d: data }, onEcho);\n};\n// RealTimeConnection properties that we use in tests.\nvar RealTimeConnection = __WEBPACK_IMPORTED_MODULE_3__realtime_Connection__[\"a\" /* Connection */];\n/**\r\n * @param {function(): string} newHash\r\n * @return {function()}\r\n */\nvar hijackHash = function hijackHash(newHash) {\n var oldPut = __WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__[\"a\" /* PersistentConnection */].prototype.put;\n __WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__[\"a\" /* 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 __WEBPACK_IMPORTED_MODULE_1__core_PersistentConnection__[\"a\" /* PersistentConnection */].prototype.put = oldPut;\n };\n};\n/**\r\n * @type {function(new:RepoInfo, !string, boolean, !string, boolean): undefined}\r\n */\nvar ConnectionTarget = __WEBPACK_IMPORTED_MODULE_0__core_RepoInfo__[\"a\" /* 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 forceRestClient = function forceRestClient(_forceRestClient) {\n __WEBPACK_IMPORTED_MODULE_2__core_RepoManager__[\"a\" /* RepoManager */].getInstance().forceRestClient(_forceRestClient);\n};\n\n/***/ })\n],[62]);\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(\n 'Firebase Database (' +\n CONSTANTS.SDK_VERSION +\n ') INTERNAL ASSERT FAILED: ' +\n message\n );\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 = [],\n 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 * Maps websafe characters to bytes.\n * @type {Object}\n * @private\n */\n charToByteMapWebSafe_: null,\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' + 'abcdefghijklmnopqrstuvwxyz' + '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(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\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(stringToByteArray(input), opt_webSafe);\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 * 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 || 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 * 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] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[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_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\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\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 * 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] =\n (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] =\n (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 /** @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\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 * 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\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 * 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 * @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 (\n Array.isArray(var_args[i]) ||\n (var_args[i] &&\n typeof var_args[i] === 'object' &&\n typeof var_args[i].length === 'number')\n ) {\n message += buildLogMessage_.apply(null, var_args[i]);\n } else if (typeof var_args[i] === 'object') {\n message += stringify(var_args[i]);\n } else {\n message += var_args[i];\n }\n message += ' ';\n }\n\n return message;\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 * Flag to check for log availability on first log message\n * @type {boolean}\n * @private\n */\nlet firstLog_ = true;\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(\n logger_?: boolean | ((a: string) => void) | null,\n persistent?: boolean\n) {\n assert(\n !persistent || (logger_ === true || logger_ === false),\n \"Can't turn on custom loggers persistently.\"\n );\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) {\n console.log(message);\n };\n }\n }\n if (persistent) SessionStorage.set('logging_enabled', true);\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 * @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 * @param {!string} prefix\n * @return {function(...[*])}\n */\nexport const logWrapper = function(\n prefix: string\n): (...var_args: any[]) => void {\n return function(...var_args: any[]) {\n log(prefix, ...var_args);\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: ' + 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 * @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 * @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 * 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 (\n typeof window !== 'undefined' &&\n window.location &&\n window.location.protocol &&\n window.location.protocol.indexOf('https:') !== -1\n ) {\n warn(\n '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(\n 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 (\n 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', function() {\n if (document.readyState === 'complete') wrappedFn();\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 * 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 * 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 * 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 * @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 * @param {string} key\n * @param {Object} obj\n * @return {*}\n */\nexport const requireKey = function(\n key: string,\n obj: { [k: string]: any }\n): any {\n if (obj && key in obj) {\n return obj[key];\n } else {\n throw new Error(\n '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) 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) 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 * 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(\n str: string,\n segsize: number\n): 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 } else {\n dataSegs.push(str.substring(c, c + segsize));\n }\n }\n return dataSegs;\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(\n obj: Object | Array,\n fn: (v?: any, k?: any) => void\n) {\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 * 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(\n callback: (a: any) => void,\n context?: object | null\n): Function {\n return context ? callback.bind(context) : callback;\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,\n fbits = 52;\n let bias = (1 << (ebits - 1)) - 1,\n s,\n e,\n f,\n ln,\n i,\n bits,\n 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 } 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 } 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) hexByte = '0' + hexByte;\n hexByteString = hexByteString + hexByte;\n }\n return hexByteString.toLowerCase();\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 !!(\n typeof window === 'object' &&\n window['chrome'] &&\n window['chrome']['extension'] &&\n !/^chrome/.test(window.location.href)\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 * 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 =\n '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(\n code + ' at ' + query.path.toString() + ': ' + reason\n );\n (error as any).code = code.toUpperCase();\n return error;\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 * 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 * 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 * 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(\n callback?: Function | null,\n ...var_args: any[]\n) {\n if (typeof callback === 'function') {\n exceptionGuard(function() {\n callback(...var_args);\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 =\n (typeof window === 'object' &&\n window['navigator'] &&\n window['navigator']['userAgent']) ||\n '';\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 (\n userAgent.search(\n /googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i\n ) >= 0\n );\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(\n object: Object,\n name: string,\n fnGet: () => any\n) {\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(\n fn: Function,\n time: number\n): 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)) 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 * 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 * 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(\n obj: Object,\n fn: (k: string, v?: V) => boolean\n): 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\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) 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] !== '') 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) 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 (\n let i = childPathObj.pieceNum_;\n i < childPathObj.pieces_.length;\n i++\n ) {\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) 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(),\n inner = innerPath.getFront();\n if (outer === null) {\n return innerPath;\n } else if (outer === inner) {\n return Path.relativePath(outerPath.popFront(), innerPath.popFront());\n } else {\n throw new Error(\n 'INTERNAL ERROR: innerPath (' +\n innerPath +\n ') is not within ' +\n 'outerPath (' +\n outerPath +\n ')'\n );\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 (\n let i = this.pieceNum_, j = other.pieceNum_;\n i <= this.pieces_.length;\n i++, j++\n ) {\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(\n this.errorPrefix_ +\n 'has a key path longer than ' +\n ValidationPath.MAX_PATH_LENGTH_BYTES +\n ' bytes (' +\n this.byteLength_ +\n ').'\n );\n }\n if (this.parts_.length > ValidationPath.MAX_PATH_DEPTH) {\n throw new Error(\n this.errorPrefix_ +\n 'path specified exceeds the maximum depth that can be written (' +\n ValidationPath.MAX_PATH_DEPTH +\n ') or object contains a cycle ' +\n this.toErrorString()\n );\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// 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 { 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 * @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 * @inheritDoc\n */\n isDefinedOn(node: Node): boolean {\n return !node.getPriority().isEmpty();\n }\n\n /**\n * @inheritDoc\n */\n indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n return !oldNode.getPriority().equals(newNode.getPriority());\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 new NamedNode(MAX_NAME, new LeafNode('[PRIORITY-POST]', MAX_NODE));\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 * @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\nimport { assert } from '../../../utils/assert';\nimport { sha1, MAX_NAME, MIN_NAME } from '../util/util';\nimport { SortedMap, SortedMapIterator } from '../util/SortedMap';\nimport { Node, NamedNode } from './Node';\nimport { validatePriorityNode, priorityHashText, setMaxNode } from './snap';\nimport {\n PRIORITY_INDEX,\n setMaxNode as setPriorityMaxNode\n} 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 (\n children_: SortedMap,\n priorityNode_: Node | null,\n indexMap_: IndexMap\n ): 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 (\n EMPTY_NODE ||\n (EMPTY_NODE = new ChildrenNode(\n new SortedMap(NAME_COMPARATOR),\n null,\n IndexMap.Default\n ))\n );\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(\n 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(\n !this.priorityNode_ || this.priorityNode_.isEmpty(),\n 'An empty node cannot have a priority'\n );\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) 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(\n namedNode,\n 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(\n path.getFront() !== '.priority' || path.getLength() === 1,\n '.priority must be the last token in a path'\n );\n const newImmediateChild = this.getImmediateChild(front).updateChild(\n path.popFront(),\n newChildNode\n );\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()) return null;\n\n const obj: { [k: string]: Object } = {};\n let numKeys = 0,\n maxKey = 0,\n 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) 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 /** @inheritDoc */\n hash(): string {\n if (this.lazyHash_ === null) {\n let toHash = '';\n if (!this.getPriority().isEmpty())\n toHash +=\n 'priority:' +\n priorityHashText(this.getPriority().val() as string | number) +\n ':';\n\n this.forEachChild(PRIORITY_INDEX, function(key, childNode) {\n const childHash = childNode.hash();\n if (childHash !== '') toHash += ':' + key + ':' + childHash;\n });\n\n this.lazyHash_ = toHash === '' ? '' : sha1(toHash);\n }\n return this.lazyHash_;\n }\n\n /** @inheritDoc */\n getPredecessorChildName(\n childName: string,\n childNode: Node,\n index: Index\n ): string {\n const idx = this.resolveIndex_(index);\n if (idx) {\n const predecessor = idx.getPredecessorKey(\n new NamedNode(childName, childNode)\n );\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 * @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(\n indexDefinition: Index\n ): 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(\n startPost: NamedNode,\n indexDefinition: Index\n ): 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(\n startPost.name,\n NamedNode.Wrap\n );\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(\n indexDefinition: Index\n ): SortedMapIterator {\n return this.getReverseIteratorFrom(\n indexDefinition.maxPost(),\n indexDefinition\n );\n }\n\n /**\n * @param {!NamedNode} endPost\n * @param {!Index} indexDefinition\n * @return {!SortedMapIterator}\n */\n getReverseIteratorFrom(\n endPost: NamedNode,\n indexDefinition: Index\n ): SortedMapIterator {\n const idx = this.resolveIndex_(indexDefinition);\n if (idx) {\n return idx.getReverseIteratorFrom(endPost, function(key) {\n return key;\n });\n } else {\n const iterator = this.children_.getReverseIteratorFrom(\n endPost.name,\n NamedNode.Wrap\n );\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 (\n indexDefinition === KEY_INDEX ||\n this.indexMap_.hasIndex(indexDefinition)\n ) {\n return this;\n } else {\n const newIndexMap = this.indexMap_.addIndex(\n indexDefinition,\n this.children_\n );\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 } 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 (\n this.children_.count() === otherChildrenNode.children_.count()\n ) {\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 (\n thisCurrent.name !== otherCurrent.name ||\n !thisCurrent.node.equals(otherCurrent.node)\n ) {\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 * 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_(\n indexDefinition: Index\n ): 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 * @constructor\n * @extends {ChildrenNode}\n * @private\n */\nexport class MaxNode extends ChildrenNode {\n constructor() {\n super(\n new SortedMap(NAME_COMPARATOR),\n ChildrenNode.EMPTY_NODE,\n IndexMap.Default\n );\n }\n\n compareTo(other: Node): number {\n if (other === this) {\n return 0;\n } else {\n return 1;\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 getPriority(): MaxNode {\n return this;\n }\n\n getImmediateChild(childName: string): ChildrenNode {\n return ChildrenNode.EMPTY_NODE;\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\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 { 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 * Gets the priority of the node.\n * @return {!Node} The priority of the node.\n */\n getPriority(): Node;\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 * 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 * 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 * 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(\n childName: String,\n childNode: Node,\n index: Index\n ): 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 * 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 * @return {number} The number of children of this node.\n */\n numChildren(): number;\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// 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\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 * 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\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 =\n fnName +\n ' failed: Was called with ' +\n argCount +\n (argCount === 1 ? ' argument.' : ' arguments.') +\n ' Expects ' +\n argError +\n '.';\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(\n 'errorPrefix called with argumentNumber > 4. Need to update it?'\n );\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(\n fnName,\n argumentNumber,\n namespace,\n optional\n) {\n if (optional && !namespace) 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(\n errorPrefix(fnName, argumentNumber, optional) +\n 'must be a valid firebase namespace.'\n );\n }\n};\n\nexport const validateCallback = function(\n fnName,\n argumentNumber,\n callback,\n optional\n) {\n if (optional && !callback) return;\n if (typeof callback !== 'function')\n throw new Error(\n errorPrefix(fnName, argumentNumber, optional) +\n 'must be a valid function.'\n );\n};\n\nexport const validateContextObject = function(\n fnName,\n argumentNumber,\n context,\n optional\n) {\n if (optional && !context) return;\n if (typeof context !== 'object' || context === null)\n throw new Error(\n errorPrefix(fnName, argumentNumber, optional) +\n 'must be a valid context object.'\n );\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 { 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 * @param {*} key\n * @return {boolean}\n */\nexport const isValidKey = function(key: any): boolean {\n return (\n typeof key === 'string' && key.length !== 0 && !INVALID_KEY_REGEX_.test(key)\n );\n};\n\n/**\n * @param {string} pathString\n * @return {boolean}\n */\nexport const isValidPathString = function(pathString: string): boolean {\n return (\n typeof pathString === 'string' &&\n pathString.length !== 0 &&\n !INVALID_PATH_REGEX_.test(pathString)\n );\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 (\n priority === null ||\n typeof priority === 'string' ||\n (typeof priority === 'number' && !isInvalidJSONNumber(priority)) ||\n (priority && typeof priority === 'object' && contains(priority, '.sv'))\n );\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(\n fnName: string,\n argumentNumber: number,\n data: any,\n path: Path,\n optional: boolean\n) {\n if (optional && data === undefined) return;\n\n validateFirebaseData(\n errorPrefixFxn(fnName, argumentNumber, optional),\n data,\n 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(\n errorPrefix: string,\n data: any,\n path_: Path | ValidationPath\n) {\n const path =\n path_ instanceof Path ? new ValidationPath(path_, errorPrefix) : 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(\n errorPrefix +\n 'contains a function ' +\n path.toErrorString() +\n ' with contents = ' +\n data.toString()\n );\n }\n if (isInvalidJSONNumber(data)) {\n throw new Error(\n errorPrefix + 'contains ' + data.toString() + ' ' + path.toErrorString()\n );\n }\n\n // Check max leaf size, but try to avoid the utf8 conversion if we can.\n if (\n typeof data === 'string' &&\n data.length > MAX_LEAF_SIZE_ / 3 &&\n stringLength(data) > MAX_LEAF_SIZE_\n ) {\n throw new Error(\n errorPrefix +\n 'contains a string greater than ' +\n MAX_LEAF_SIZE_ +\n ' utf8 bytes ' +\n path.toErrorString() +\n \" ('\" +\n data.substring(0, 50) +\n \"...')\"\n );\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,\n hasActualChild = false;\n forEach(data, function(key: string, value: any) {\n if (key === '.value') {\n hasDotValue = true;\n } else if (key !== '.priority' && key !== '.sv') {\n hasActualChild = true;\n if (!isValidKey(key)) {\n throw new Error(\n errorPrefix +\n ' contains an invalid key (' +\n key +\n ') ' +\n path.toErrorString() +\n '. Keys must be non-empty strings ' +\n 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"'\n );\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(\n errorPrefix +\n ' contains \".value\" child ' +\n path.toErrorString() +\n ' in addition to actual children.'\n );\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(\n errorPrefix: string,\n mergePaths: Path[]\n) {\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(\n errorPrefix +\n 'contains an invalid key (' +\n keys[j] +\n ') in path ' +\n curPath.toString() +\n '. Keys must be non-empty strings ' +\n 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"'\n );\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(\n errorPrefix +\n 'contains a path ' +\n prevPath.toString() +\n ' that is ancestor of another path ' +\n curPath.toString()\n );\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(\n fnName: string,\n argumentNumber: number,\n data: any,\n path: Path,\n optional: boolean\n) {\n if (optional && data === undefined) return;\n\n const errorPrefix = errorPrefixFxn(fnName, argumentNumber, optional);\n\n if (!(data && typeof data === 'object') || Array.isArray(data)) {\n throw new Error(\n errorPrefix + ' must be an object containing the children to replace.'\n );\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 +\n \"contains an invalid value for '\" +\n curPath.toString() +\n \"', which must be a valid \" +\n 'Firebase priority (a string, finite number, server value, or null).'\n );\n }\n }\n mergePaths.push(curPath);\n });\n validateFirebaseMergePaths(errorPrefix, mergePaths);\n};\n\nexport const validatePriority = function(\n fnName: string,\n argumentNumber: number,\n priority: any,\n optional: boolean\n) {\n if (optional && priority === undefined) return;\n if (isInvalidJSONNumber(priority))\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'is ' +\n priority.toString() +\n ', but must be a valid Firebase priority (a string, finite number, ' +\n 'server value, or null).'\n );\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};\n\nexport const validateEventType = function(\n fnName: string,\n argumentNumber: number,\n eventType: string,\n optional: boolean\n) {\n if (optional && eventType === undefined) 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};\n\nexport const validateKey = function(\n fnName: string,\n argumentNumber: number,\n key: string,\n optional: boolean\n) {\n if (optional && key === undefined) return;\n if (!isValidKey(key))\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'was an invalid key = \"' +\n key +\n '\". Firebase keys must be non-empty strings and ' +\n 'can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\").'\n );\n};\n\nexport const validatePathString = function(\n fnName: string,\n argumentNumber: number,\n pathString: string,\n optional: boolean\n) {\n if (optional && pathString === undefined) return;\n\n if (!isValidPathString(pathString))\n throw new Error(\n 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};\n\nexport const validateRootPathString = function(\n fnName: string,\n argumentNumber: number,\n pathString: string,\n optional: boolean\n) {\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(\n fnName: string,\n argumentNumber: number,\n parsedUrl: { repoInfo: RepoInfo; path: Path }\n) {\n // TODO = Validate server better.\n const pathString = parsedUrl.path.toString();\n if (\n !(typeof parsedUrl.repoInfo.host === 'string') ||\n parsedUrl.repoInfo.host.length === 0 ||\n !isValidKey(parsedUrl.repoInfo.namespace) ||\n (pathString.length !== 0 && !isValidRootPathString(pathString))\n ) {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, false) +\n 'must be a valid firebase URL and ' +\n 'the path can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\".'\n );\n }\n};\n\nexport const validateCredential = function(\n fnName: string,\n argumentNumber: number,\n cred: any,\n optional: boolean\n) {\n if (optional && cred === undefined) 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};\n\nexport const validateBoolean = function(\n fnName: string,\n argumentNumber: number,\n bool: any,\n optional: boolean\n) {\n if (optional && bool === undefined) return;\n if (typeof bool !== 'boolean')\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) + 'must be a boolean.'\n );\n};\n\nexport const validateString = function(\n fnName: string,\n argumentNumber: number,\n string: any,\n optional: boolean\n) {\n if (optional && string === undefined) return;\n if (!(typeof string === 'string')) {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must be a valid string.'\n );\n }\n};\n\nexport const validateObject = function(\n fnName: string,\n argumentNumber: number,\n obj: any,\n optional: boolean\n) {\n if (optional && obj === undefined) 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};\n\nexport const validateObjectContainsKey = function(\n fnName: string,\n argumentNumber: number,\n obj: any,\n key: string,\n optional: boolean,\n opt_type?: string\n) {\n const objectContainsKey =\n 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 \"' +\n key +\n '\"'\n );\n }\n }\n\n if (opt_type) {\n const val = safeGet(obj, key);\n if (\n (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 ) {\n if (optional) {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'contains invalid value for key \"' +\n key +\n '\" (must be of type \"' +\n opt_type +\n '\")'\n );\n } else {\n throw new Error(\n errorPrefixFxn(fnName, argumentNumber, optional) +\n 'must contain the key \"' +\n key +\n '\" with type \"' +\n opt_type +\n '\"'\n );\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 { 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(\n public fromUser: boolean,\n public fromServer: boolean,\n public queryId: string | null,\n public tagged: boolean\n ) {\n assert(!tagged || fromServer, 'Tagged queries must be from server.');\n }\n /**\n * @const\n * @type {!OperationSource}\n */\n static User = new OperationSource(\n /*fromUser=*/ true,\n false,\n null,\n /*tagged=*/ false\n );\n\n /**\n * @const\n * @type {!OperationSource}\n */\n static Server = new OperationSource(\n false,\n /*fromServer=*/ true,\n null,\n /*tagged=*/ false\n );\n\n /**\n * @param {string} queryId\n * @return {!OperationSource}\n */\n static forServerTaggedQuery = function(queryId: string): OperationSource {\n return new OperationSource(\n false,\n /*fromServer=*/ true,\n queryId,\n /*tagged=*/ true\n );\n };\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 { 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 (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\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 (\n 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 (\n 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\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(\n 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(\n childKey: string,\n newSnapshot: Node,\n oldSnapshot: Node\n ): 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// 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 { 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 * @inheritDoc\n */\n indexedValueChanged(oldNode: Node, newNode: Node): boolean {\n return false; // The key for a node never changes.\n }\n\n /**\n * @inheritDoc\n */\n minPost() {\n return (NamedNode as any).MIN;\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 * @param {*} indexValue\n * @param {string} name\n * @return {!NamedNode}\n */\n makePost(indexValue: string, name: string): NamedNode {\n assert(\n typeof indexValue === 'string',\n 'KeyIndex indexValue must always be a string.'\n );\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 * @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\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 { 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(\n json: any | null,\n priority: string | number | null = null\n): 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) !== '.') {\n // Ignore metadata nodes\n const childNode = nodeFromJSON(hinzeJsonObj[key]);\n if (!childNode.isEmpty()) {\n childrenHavePriority =\n 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(\n children,\n NAME_ONLY_COMPARATOR,\n namedNode => namedNode.name,\n NAME_COMPARATOR\n ) as SortedMap;\n if (childrenHavePriority) {\n const sortedChildSet = buildChildSet(\n children,\n PRIORITY_INDEX.getCompare()\n );\n return new ChildrenNode(\n childSet,\n nodeFromJSON(priority),\n new IndexMap(\n { '.priority': sortedChildSet },\n { '.priority': PRIORITY_INDEX }\n )\n );\n } else {\n return new ChildrenNode(\n childSet,\n nodeFromJSON(priority),\n IndexMap.Default\n );\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) !== '.') {\n // 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\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\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.5.0'\n};\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 * @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(\n domStorageName: string\n): 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 (\n typeof window !== 'undefined' &&\n typeof window[domStorageName] !== 'undefined'\n ) {\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 // Failed to create wrapper. Just return in-memory storage.\n // TODO: log?\n return new MemoryStorage();\n};\n\n/** A storage object that lasts across sessions */\nexport const PersistentStorage = createStoragefor('localStorage');\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 { 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 * @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 * 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 * @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 * @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 * @param {*} indexValue\n * @param {string} name\n * @return {!NamedNode}\n */\n abstract makePost(indexValue: any, name: string): NamedNode;\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 { assert } from '../../../utils/assert';\nimport { doubleToIEEE754String, sha1 } from '../util/util';\nimport { priorityHashText, validatePriorityNode } 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(\n private readonly value_: string | number | boolean | object,\n private priorityNode_: Node = LeafNode.__childrenNodeConstructor.EMPTY_NODE\n ) {\n assert(\n this.value_ !== undefined && this.value_ !== null,\n \"LeafNode shouldn't be created with null/undefined value.\"\n );\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(\n front !== '.priority' || path.getLength() === 1,\n '.priority must be the last token in a path'\n );\n\n return this.updateImmediateChild(\n front,\n LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(\n path.popFront(),\n newChildNode\n )\n );\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 {\n '.value': this.getValue(),\n '.priority': this.getPriority().val()\n };\n else 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 +=\n 'priority:' +\n priorityHashText(this.priorityNode_.val() as number | string) +\n ':';\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 } else if (other.isLeafNode()) {\n const otherLeaf = other as LeafNode;\n return (\n this.value_ === otherLeaf.value_ &&\n this.priorityNode_.equals(otherLeaf.priorityNode_)\n );\n } else {\n return false;\n }\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\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// 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(\n 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) 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 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) 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 * 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(\n public key: K,\n public value: V,\n color: boolean | null,\n left?: LLRBNode | LLRBEmptyNode | null,\n right?: LLRBNode | LLRBEmptyNode | null\n ) {\n this.color = color != null ? color : LLRBNode.RED;\n this.left =\n left != null ? left : SortedMap.EMPTY_NODE as LLRBEmptyNode;\n this.right =\n 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(\n key: K | null,\n value: V | null,\n color: boolean | null,\n left: LLRBNode | LLRBEmptyNode | null,\n right: LLRBNode | LLRBEmptyNode | null\n ): 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 /**\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 (\n this.left.inorderTraversal(action) ||\n action(this.key, this.value) ||\n this.right.inorderTraversal(action)\n );\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 (\n this.right.reverseTraversal(action) ||\n action(this.key, this.value) ||\n this.left.reverseTraversal(action)\n );\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(\n null,\n null,\n null,\n null,\n n.right.insert(key, value, comparator)\n );\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.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(\n key: K,\n comparator: Comparator\n ): 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(\n smallest.key,\n smallest.value,\n null,\n null,\n (n.right as LLRBNode).removeMin_()\n );\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(\n null,\n null,\n null,\n null,\n (n.right as LLRBNode).rotateRight_()\n );\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(\n 'Red node has red child(' + this.key + ',' + this.value + ')'\n );\n }\n if (this.right.isRed_()) {\n throw new Error(\n 'Right child of (' + this.key + ',' + this.value + ') is red'\n );\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 * 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(\n key: K | null,\n value: V | null,\n color: boolean | null,\n left: LLRBNode | LLRBEmptyNode | null,\n right: LLRBNode | LLRBEmptyNode | null\n ): 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(\n private comparator_: Comparator,\n private root_:\n | LLRBNode\n | 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_\n .insert(key, value, this.comparator_)\n .copy(null, null, LLRBNode.BLACK, null, null)\n );\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_\n .remove(key, this.comparator_)\n .copy(null, null, LLRBNode.BLACK, null, null)\n );\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,\n node = this.root_,\n 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()) 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(\n 'Attempted to find predecessor key for a nonexistent key. What gives?'\n );\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(\n resultGenerator?: (k: K, v: V) => T\n ): SortedMapIterator {\n return new SortedMapIterator(\n this.root_,\n null,\n this.comparator_,\n false,\n resultGenerator\n );\n }\n\n getIteratorFrom(\n key: K,\n resultGenerator?: (k: K, v: V) => T\n ): SortedMapIterator {\n return new SortedMapIterator(\n this.root_,\n key,\n this.comparator_,\n false,\n resultGenerator\n );\n }\n\n getReverseIteratorFrom(\n key: K,\n resultGenerator?: (k: K, v: V) => T\n ): SortedMapIterator {\n return new SortedMapIterator(\n this.root_,\n key,\n this.comparator_,\n true,\n resultGenerator\n );\n }\n\n getReverseIterator(\n resultGenerator?: (k: K, v: V) => T\n ): SortedMapIterator {\n return new SortedMapIterator(\n this.root_,\n null,\n this.comparator_,\n true,\n resultGenerator\n );\n }\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 { 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(\n /**@inheritDoc */ public path: Path,\n /**@inheritDoc */ public affectedTree: ImmutableTree,\n /**@inheritDoc */ public revert: boolean\n ) {}\n\n /**\n * @inheritDoc\n */\n operationForChild(childName: string): AckUserWrite {\n if (!this.path.isEmpty()) {\n assert(\n this.path.getFront() === childName,\n 'operationForChild called for unrelated child.'\n );\n return new AckUserWrite(\n this.path.popFront(),\n this.affectedTree,\n this.revert\n );\n } else if (this.affectedTree.value != null) {\n assert(\n this.affectedTree.children.isEmpty(),\n 'affectedTree should not have overlapping affected paths.'\n );\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\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 { 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 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(\n 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(\n this.source,\n Path.Empty,\n this.snap.getImmediateChild(childName)\n );\n } else {\n return new Overwrite(this.source, this.path.popFront(), this.snap);\n }\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(\n /**@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(\n this.path.getFront() === childName,\n \"Can't get a merge for a child not on the path of the operation\"\n );\n return new Merge(this.source, this.path.popFront(), this.children);\n }\n }\n\n /**\n * @inheritDoc\n */\n toString(): string {\n return (\n 'Operation(' +\n this.path +\n ': ' +\n this.source.toString() +\n ' merge: ' +\n this.children.toString() +\n ')'\n );\n }\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 { 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_\n .get(rootmost.path)\n .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(\n childName,\n childNode\n ) {\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(\n relativePath: Path,\n writeTree: ImmutableTree,\n node: Node\n ): 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(\n childTree.value !== null,\n 'Priority writes must always be leaf nodes'\n );\n priorityWrite = childTree.value;\n } else {\n node = CompoundWrite.applySubtreeWrite_(\n relativePath.child(childKey),\n childTree,\n node\n );\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// 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(\n writeId > this.lastWriteId_,\n 'Stacking an older write on top of newer ones'\n );\n if (visible === undefined) {\n visible = true;\n }\n this.allWrites_.push({\n path: path,\n snap: snap,\n writeId: writeId,\n visible: visible\n });\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(\n path: Path,\n changedChildren: { [k: string]: Node },\n writeId: number\n ) {\n assert(\n writeId > this.lastWriteId_,\n 'Stacking an older merge on top of newer ones'\n );\n this.allWrites_.push({\n path: path,\n children: changedChildren,\n writeId: writeId,\n visible: true\n });\n\n this.visibleWrites_ = this.visibleWrites_.addWrites(path, changedChildren);\n this.lastWriteId_ = writeId;\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 * 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) {\n return s.writeId === writeId;\n });\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 (\n i >= idx &&\n this.recordContainsPath_(currentWrite, writeToRemove.path)\n ) {\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(\n writeToRemove.path\n );\n } else {\n const children = writeToRemove.children;\n forEach(children, (childName: string) => {\n this.visibleWrites_ = this.visibleWrites_.removeWrite(\n writeToRemove.path.child(childName)\n );\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(\n treePath: Path,\n completeServerCache: Node | null,\n writeIdsToExclude?: number[],\n includeHiddenWrites?: boolean\n ): 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 (\n completeServerCache == null &&\n !subMerge.hasCompleteWrite(Path.Empty)\n ) {\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 (\n !includeHiddenWrites &&\n completeServerCache == null &&\n !merge.hasCompleteWrite(Path.Empty)\n ) {\n return null;\n } else {\n const filter = function(write: WriteRecord) {\n return (\n (write.visible || includeHiddenWrites) &&\n (!writeIdsToExclude ||\n !~writeIdsToExclude.indexOf(write.writeId)) &&\n (write.path.contains(treePath) || treePath.contains(write.path))\n );\n };\n const mergeAtPath = WriteTree.layerTree_(\n this.allWrites_,\n filter,\n treePath\n );\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(\n treePath: Path,\n completeServerChildren: ChildrenNode | null\n ) {\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(\n childName,\n childSnap\n ) {\n completeChildren = completeChildren.updateImmediateChild(\n childName,\n childSnap\n );\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(\n childName,\n childNode\n ) {\n const node = merge\n .childCompoundWrite(new Path(childName))\n .apply(childNode);\n completeChildren = completeChildren.updateImmediateChild(\n childName,\n node\n );\n });\n // Add any complete children we have from the set\n merge.getCompleteChildren().forEach(function(namedNode) {\n completeChildren = completeChildren.updateImmediateChild(\n namedNode.name,\n namedNode.node\n );\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(\n namedNode.name,\n namedNode.node\n );\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(\n treePath: Path,\n childPath: Path,\n existingEventSnap: Node | null,\n existingServerSnap: Node | null\n ): Node | null {\n assert(\n existingEventSnap || existingServerSnap,\n 'Either existingEventSnap or existingServerSnap must exist'\n );\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(\n treePath: Path,\n childKey: string,\n existingServerSnap: CacheNode\n ): 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(\n existingServerSnap.getNode().getImmediateChild(childKey)\n );\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(\n treePath: Path,\n completeServerData: Node | null,\n startPost: NamedNode,\n count: number,\n reverse: boolean,\n index: Index\n ): 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\n ? (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(\n childSnap: Node,\n childName: string\n ) {\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_(\n this.allWrites_,\n WriteTree.DefaultFilter_,\n Path.Empty\n );\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_(\n writes: WriteRecord[],\n filter: (w: WriteRecord) => boolean,\n treeRoot: Path\n ): 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(\n Path.Empty,\n write.snap.getChild(relativePath)\n );\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(\n relativePath,\n write.children\n );\n } else if (writePath.contains(treeRoot)) {\n relativePath = Path.relativePath(writePath, treeRoot);\n if (relativePath.isEmpty()) {\n compoundWrite = compoundWrite.addWrites(\n Path.Empty,\n write.children\n );\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(\n completeServerCache: Node | null,\n writeIdsToExclude?: number[],\n includeHiddenWrites?: boolean\n ): Node | null {\n return this.writeTree_.calcCompleteEventCache(\n this.treePath_,\n completeServerCache,\n writeIdsToExclude,\n includeHiddenWrites\n );\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(\n this.treePath_,\n completeServerChildren\n ) 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(\n path: Path,\n existingEventSnap: Node | null,\n existingServerSnap: Node | null\n ): Node | null {\n return this.writeTree_.calcEventCacheAfterServerOverwrite(\n this.treePath_,\n path,\n existingEventSnap,\n existingServerSnap\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.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(\n completeServerData: Node | null,\n startPost: NamedNode,\n count: number,\n reverse: boolean,\n index: Index\n ): NamedNode[] {\n return this.writeTree_.calcIndexedSlice(\n this.treePath_,\n completeServerData,\n startPost,\n count,\n reverse,\n index\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 {!string} childKey\n * @param {!CacheNode} existingServerCache\n * @return {?Node}\n */\n calcCompleteChild(\n childKey: string,\n existingServerCache: CacheNode\n ): Node | null {\n return this.writeTree_.calcCompleteChild(\n this.treePath_,\n childKey,\n existingServerCache\n );\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(\n query: Query,\n tag: number | null,\n hashFn: () => string,\n onComplete: (a: string, b?: any) => Event[]\n ): 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 * 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(\n path: Path,\n newData: Node,\n writeId: number,\n visible?: boolean\n ): 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 /**\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(\n path: Path,\n changedChildren: { [k: string]: Node },\n writeId: number\n ): 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 /**\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) {\n // 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_(\n new AckUserWrite(write.path, affectedTree, revert)\n );\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 /**\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(\n path: Path,\n changedChildren: { [k: string]: Node }\n ): Event[] {\n const changeTree = ImmutableTree.fromObject(changedChildren);\n\n return this.applyOperationToSyncPoints_(\n new Merge(OperationSource.Server, path, changeTree)\n );\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 /**\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,\n queryId = r.queryId;\n const relativePath = Path.relativePath(queryPath, path);\n const op = new Overwrite(\n OperationSource.forServerTaggedQuery(queryId),\n relativePath,\n snap\n );\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(\n path: Path,\n changedChildren: { [k: string]: Node },\n tag: number\n ): Event[] {\n const queryKey = this.queryKeyForTag_(tag);\n if (queryKey) {\n const r = SyncTree.parseQueryKey_(queryKey);\n const queryPath = r.path,\n queryId = r.queryId;\n const relativePath = Path.relativePath(queryPath, path);\n const changeTree = ImmutableTree.fromObject(changedChildren);\n const op = new Merge(\n OperationSource.forServerTaggedQuery(queryId),\n relativePath,\n changeTree\n );\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,\n queryId = r.queryId;\n const relativePath = Path.relativePath(queryPath, path);\n const op = new ListenComplete(\n OperationSource.forServerTaggedQuery(queryId),\n relativePath\n );\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(\n query: Query,\n eventRegistration: EventRegistration\n ): 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 =\n 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 =\n 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(\n childName,\n completeCache\n );\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(\n !(queryKey in this.queryToTagMap_),\n 'View does not exist, but we have a tag'\n );\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(\n query,\n eventRegistration,\n writesCache,\n serverCache,\n serverCacheComplete\n );\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(\n query: Query,\n eventRegistration: EventRegistration | null,\n cancelError?: Error\n ): 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 (\n maybeSyncPoint &&\n (query.queryIdentifier() === 'default' ||\n maybeSyncPoint.viewExistsForQuery(query))\n ) {\n /**\n * @type {{removed: !Array., events: !Array.}}\n */\n const removedAndEvents = maybeSyncPoint.removeEventRegistration(\n query,\n eventRegistration,\n cancelError\n );\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 =\n -1 !==\n removed.findIndex(function(query) {\n return query.getQueryParams().loadsAllData();\n });\n const covered = this.syncPointTree_.findOnPath(path, function(\n relativePath,\n parentSyncPoint\n ) {\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],\n newQuery = view.getQuery();\n const listener = this.createListenerForView_(view);\n this.listenProvider_.startListening(\n SyncTree.queryForListening_(newQuery),\n this.tagForQuery_(newQuery),\n listener.hashFn,\n listener.onComplete\n );\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(\n SyncTree.queryForListening_(query),\n defaultTag\n );\n } else {\n removed.forEach((queryToRemove: Query) => {\n const tagToRemove = this.queryToTagMap_[\n SyncTree.makeQueryKey_(queryToRemove)\n ];\n this.listenProvider_.stopListening(\n SyncTree.queryForListening_(queryToRemove),\n tagToRemove\n );\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(\n path: Path,\n writeIdsToExclude?: number[]\n ): Node | null {\n const includeHiddenSets = true;\n const writeTree = this.pendingWriteTree_;\n const serverCache = this.syncPointTree_.findOnPath(path, function(\n pathSoFar,\n syncPoint\n ) {\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(\n path,\n serverCache,\n writeIdsToExclude,\n includeHiddenSets\n );\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_(\n subtree: ImmutableTree\n ): View[] {\n return subtree.fold<\n View[]\n >((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 * 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 (\n query.getQueryParams().loadsAllData() &&\n !query.getQueryParams().isDefault()\n ) {\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 * 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(\n SyncTree.queryForListening_(query),\n tag,\n listener.hashFn,\n listener.onComplete\n );\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(\n !subtree.value.hasCompleteView(),\n \"If we're adding a query, it shouldn't be shadowed\"\n );\n } else {\n // Shadow everything at or below this location, this is a default listener.\n const queriesToStop = subtree.fold(function(\n relativePath,\n maybeChildSyncPoint,\n childMap\n ) {\n if (\n !relativePath.isEmpty() &&\n maybeChildSyncPoint &&\n maybeChildSyncPoint.hasCompleteView()\n ) {\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(\n SyncTree.queryForListening_(queryToStop),\n this.tagForQuery_(queryToStop)\n );\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_(\n view: View\n ): { 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(\n query,\n /*eventRegistration*/ null,\n error\n );\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_(\n queryKey: string\n ): { queryId: string; path: Path } {\n const splitIndex = queryKey.indexOf('$');\n assert(\n splitIndex !== -1 && splitIndex < queryKey.length - 1,\n 'Bad queryKey.'\n );\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_(\n queryPath: Path,\n operation: Operation\n ): 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(\n operation,\n writesCache,\n /*serverCache=*/ null\n );\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_(\n operation,\n this.syncPointTree_,\n /*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_(\n operation: Operation,\n syncPointTree: ImmutableTree,\n serverCache: Node | null,\n writesCache: WriteTreeRef\n ): Event[] {\n if (operation.path.isEmpty()) {\n return this.applyOperationDescendantsHelper_(\n operation,\n syncPointTree,\n serverCache,\n writesCache\n );\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\n ? serverCache.getImmediateChild(childName)\n : null;\n const childWritesCache = writesCache.child(childName);\n events = events.concat(\n this.applyOperationHelper_(\n childOperation,\n childTree,\n childServerCache,\n childWritesCache\n )\n );\n }\n\n if (syncPoint) {\n events = events.concat(\n syncPoint.applyOperation(operation, writesCache, serverCache)\n );\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_(\n operation: Operation,\n syncPointTree: ImmutableTree,\n serverCache: Node | null,\n writesCache: WriteTreeRef\n ): 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\n ? serverCache.getImmediateChild(childName)\n : null;\n const childWritesCache = writesCache.child(childName);\n const childOperation = operation.operationForChild(childName);\n if (childOperation) {\n events = events.concat(\n this.applyOperationDescendantsHelper_(\n childOperation,\n childTree,\n childServerCache,\n childWritesCache\n )\n );\n }\n });\n\n if (syncPoint) {\n events = events.concat(\n syncPoint.applyOperation(operation, writesCache, serverCache)\n );\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 * @param {boolean} forceRefresh\n * @return {!Promise}\n */\n getToken(forceRefresh: boolean): Promise {\n return this.app_['INTERNAL']['getToken'](forceRefresh).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\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 =\n 'Provided authentication credentials for the app named \"' +\n this.app_.name +\n '\" are invalid. This usually indicates your app was not ' +\n 'initialized correctly. ';\n if ('credential' in this.app_.options) {\n errorMessage +=\n '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 +=\n '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 +=\n '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 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// 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 =\n FIRST_STATS_MIN_TIME +\n (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(\n this.reportStats_.bind(this),\n Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL)\n );\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 * @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) =>\n eventPath.equals(path)\n );\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_(\n predicate: (path: Path) => boolean\n ) {\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 * @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 * @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// 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 { 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(\n encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)\n );\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return params.length ? '&' + params.join('&') : '';\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\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: { [k: string]: any }): 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(\n query.getQueryParams().isDefault(),\n \"should have a tag if it's not a default query.\"\n );\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(\n private repoInfo_: RepoInfo,\n private onDataUpdate_: (\n a: string,\n b: any,\n c: boolean,\n d: number | null\n ) => void,\n private authTokenProvider_: AuthTokenProvider\n ) {\n super();\n }\n\n /** @inheritDoc */\n listen(\n query: Query,\n currentHashFn: () => string,\n tag: number | null,\n onComplete: (a: string, b: any) => void\n ) {\n const pathString = query.path.toString();\n this.log_(\n 'Listen called for ' + pathString + ' ' + query.queryIdentifier()\n );\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\n .getQueryParams()\n .toRestQueryStringParameters();\n\n this.restRequest_(\n pathString + '.json',\n queryStringParamaters,\n (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\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_(\n pathString: string,\n queryStringParameters: { [k: string]: any } = {},\n callback: ((a: number | null, b?: any) => void) | null\n ) {\n queryStringParameters['format'] = 'export';\n\n this.authTokenProvider_\n .getToken(/*forceRefresh=*/ false)\n .then(authTokenData => {\n const authToken = authTokenData && authTokenData.accessToken;\n if (authToken) {\n queryStringParameters['auth'] = authToken;\n }\n\n const url =\n (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_(\n 'REST Response for ' + url + ' received. status:',\n xhr.status,\n 'response:',\n xhr.responseText\n );\n let res = null;\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n res = jsonEval(xhr.responseText);\n } catch (e) {\n warn(\n 'Failed to parse JSON response for ' +\n url +\n ': ' +\n xhr.responseText\n );\n }\n callback(null, res);\n } else {\n // 401 and 404 are expected.\n if (xhr.status !== 401 && xhr.status !== 404) {\n warn(\n 'Got unsuccessful REST response for ' +\n url +\n ' Status: ' +\n xhr.status\n );\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_:\n | ((a: string, b: any) => void)\n | 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(\n public repoInfo_: RepoInfo,\n forceRestClient: boolean,\n public app: FirebaseApp\n ) {\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(\n this.repoInfo_,\n this.onDataUpdate_.bind(this),\n authTokenProvider\n );\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(\n 'Only objects are supported for option databaseAuthVariableOverride'\n );\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(\n this.repoInfo_,\n this.onDataUpdate_.bind(this),\n this.onConnectStatus_.bind(this),\n this.onServerInfoUpdate_.bind(this),\n authTokenProvider,\n authOverride\n );\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(\n repoInfo_,\n () => new StatsReporter(this.stats_, this.server_)\n );\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(\n query.path,\n node\n );\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 (\n (this.repoInfo_.secure ? 'https://' : 'http://') + this.repoInfo_.host\n );\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(\n new Path('.info/serverTimeOffset')\n );\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_(\n pathString: string,\n data: any,\n isMerge: boolean,\n tag: number | null\n ) {\n // For testing.\n this.dataUpdateCount++;\n const path = new Path(pathString);\n data = this.interceptServerDataCallback_\n ? this.interceptServerDataCallback_(pathString, data)\n : data;\n let events = [];\n if (tag) {\n if (isMerge) {\n const taggedChildren = map(data as { [k: string]: any }, (raw: any) =>\n nodeFromJSON(raw)\n );\n events = this.serverSyncTree_.applyTaggedQueryMerge(\n path,\n taggedChildren,\n tag\n );\n } else {\n const taggedSnap = nodeFromJSON(data);\n events = this.serverSyncTree_.applyTaggedQueryOverwrite(\n path,\n taggedSnap,\n tag\n );\n }\n } else if (isMerge) {\n const changedChildren = map(data as { [k: string]: any }, (raw: any) =>\n nodeFromJSON(raw)\n );\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(\n path: Path,\n newVal: any,\n newPriority: number | string | null,\n onComplete: ((status: Error | null, errorReason?: string) => void) | null\n ) {\n this.log_('set', {\n path: path.toString(),\n value: newVal,\n priority: newPriority\n });\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(\n newNodeUnresolved,\n serverValues\n );\n\n const writeId = this.getNextWriteId_();\n const events = this.serverSyncTree_.applyUserOverwrite(\n path,\n newNode,\n writeId,\n true\n );\n this.eventQueue_.queueEvents(events);\n this.server_.put(\n path.toString(),\n newNodeUnresolved.val(/*export=*/ true),\n (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(\n writeId,\n !success\n );\n this.eventQueue_.raiseEventsForChangedPath(path, clearEvents);\n this.callOnCompleteCallback(onComplete, status, errorReason);\n }\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(\n path: Path,\n childrenToMerge: { [k: string]: any },\n onComplete: ((status: Error | null, errorReason?: string) => void) | null\n ) {\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(\n newNodeUnresolved,\n serverValues\n );\n });\n\n if (!empty) {\n const writeId = this.getNextWriteId_();\n const events = this.serverSyncTree_.applyUserMerge(\n path,\n changedChildren,\n writeId\n );\n this.eventQueue_.queueEvents(events);\n this.server_.merge(\n path.toString(),\n childrenToMerge,\n (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(\n writeId,\n !success\n );\n const affectedPath =\n clearEvents.length > 0 ? this.rerunTransactions_(path) : path;\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, clearEvents);\n this.callOnCompleteCallback(onComplete, status, errorReason);\n }\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(\n this.onDisconnect_,\n serverValues\n );\n let events: Event[] = [];\n\n resolvedOnDisconnectTree.forEachTree(Path.Empty, (path, snap) => {\n events = events.concat(\n this.serverSyncTree_.applyServerOverwrite(path, snap)\n );\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(\n path: Path,\n onComplete: ((status: Error | null, errorReason?: string) => void) | null\n ) {\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(\n path: Path,\n value: any,\n onComplete: ((status: Error | null, errorReason?: string) => void) | null\n ) {\n const newNode = nodeFromJSON(value);\n this.server_.onDisconnectPut(\n path.toString(),\n newNode.val(/*export=*/ true),\n (status, errorReason) => {\n if (status === 'ok') {\n this.onDisconnect_.remember(path, newNode);\n }\n this.callOnCompleteCallback(onComplete, status, errorReason);\n }\n );\n }\n\n /**\n * @param {!Path} path\n * @param {*} value\n * @param {*} priority\n * @param {?function(?Error, *=)} onComplete\n */\n onDisconnectSetWithPriority(\n path: Path,\n value: any,\n priority: any,\n onComplete: ((status: Error | null, errorReason?: string) => void) | null\n ) {\n const newNode = nodeFromJSON(value, priority);\n this.server_.onDisconnectPut(\n path.toString(),\n newNode.val(/*export=*/ true),\n (status, errorReason) => {\n if (status === 'ok') {\n this.onDisconnect_.remember(path, newNode);\n }\n this.callOnCompleteCallback(onComplete, status, errorReason);\n }\n );\n }\n\n /**\n * @param {!Path} path\n * @param {*} childrenToMerge\n * @param {?function(?Error, *=)} onComplete\n */\n onDisconnectUpdate(\n path: Path,\n childrenToMerge: { [k: string]: any },\n onComplete: ((status: Error | null, errorReason?: string) => void) | null\n ) {\n if (isEmpty(childrenToMerge)) {\n log(\n \"onDisconnect().update() called with empty data. Don't do anything.\"\n );\n this.callOnCompleteCallback(onComplete, 'ok');\n return;\n }\n\n this.server_.onDisconnectMerge(\n path.toString(),\n childrenToMerge,\n (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 /**\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(\n query,\n eventRegistration\n );\n } else {\n events = this.serverSyncTree_.addEventRegistration(\n query,\n eventRegistration\n );\n }\n this.eventQueue_.raiseEventsAtPath(query.path, events);\n }\n\n /**\n * @param {!Query} query\n * @param {?EventRegistration} eventRegistration\n */\n removeEventCallbackForQuery(\n query: Query,\n eventRegistration: EventRegistration\n ) {\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(\n query,\n eventRegistration\n );\n } else {\n events = this.serverSyncTree_.removeEventRegistration(\n query,\n eventRegistration\n );\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') 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) =>\n Math.max(currentValue.length, previousValue),\n 0\n );\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++) 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(\n callback: ((status: Error | null, errorReason?: string) => void) | null,\n status: string,\n errorReason?: string | null\n ) {\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) 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// 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 { 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 * @param {string} str\n * @return {Array}\n */\nexport const stringToByteArray = function(str) {\n var out = [],\n 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 * 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 { validateArgCount, validateCallback } 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, private path_: Path) {}\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(\n this.path_,\n deferred.wrapCallback(onComplete)\n );\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(\n this.path_,\n null,\n deferred.wrapCallback(onComplete)\n );\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(\n this.path_,\n value,\n deferred.wrapCallback(onComplete)\n );\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(\n value: any,\n priority: number | string | null,\n onComplete?: (a: Error | null) => void\n ): Promise {\n validateArgCount('OnDisconnect.setWithPriority', 2, 3, arguments.length);\n validateWritablePath('OnDisconnect.setWithPriority', this.path_);\n validateFirebaseDataArg(\n 'OnDisconnect.setWithPriority',\n 1,\n value,\n this.path_,\n false\n );\n validatePriority('OnDisconnect.setWithPriority', 2, priority, false);\n validateCallback('OnDisconnect.setWithPriority', 3, onComplete, true);\n\n const deferred = new Deferred();\n this.repo_.onDisconnectSetWithPriority(\n this.path_,\n value,\n priority,\n deferred.wrapCallback(onComplete)\n );\n return deferred.promise;\n }\n\n /**\n * @param {!Object} objectToMerge\n * @param {function(?Error)=} onComplete\n * @return {!firebase.Promise}\n */\n update(\n objectToMerge: object,\n onComplete?: (a: Error | null) => void\n ): 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(\n 'OnDisconnect.update',\n 1,\n objectToMerge,\n this.path_,\n false\n );\n validateCallback('OnDisconnect.update', 2, onComplete, true);\n const deferred = new Deferred();\n this.repo_.onDisconnectUpdate(\n this.path_,\n objectToMerge,\n deferred.wrapCallback(onComplete)\n );\n return deferred.promise;\n }\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';\nimport { validateArgCount } from '../../utils/validation';\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 // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\n // for end-users\n toJSON(): object {\n validateArgCount('TransactionResult.toJSON', 0, 1, arguments.length);\n return { committed: this.committed, snapshot: this.snapshot.toJSON() };\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 =\n '-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 { 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 (\n this.index_.compare(this.getStartPost(), node) <= 0 &&\n this.index_.compare(node, this.getEndPost()) <= 0\n );\n }\n\n /**\n * @inheritDoc\n */\n updateChild(\n snap: Node,\n key: string,\n newChild: Node,\n affectedPath: Path,\n source: CompleteChildSource,\n optChangeAccumulator: ChildChangeAccumulator | null\n ): Node {\n if (!this.matches(new NamedNode(key, newChild))) {\n newChild = ChildrenNode.EMPTY_NODE;\n }\n return this.indexedFilter_.updateChild(\n snap,\n key,\n newChild,\n affectedPath,\n source,\n optChangeAccumulator\n );\n }\n\n /**\n * @inheritDoc\n */\n updateFullNode(\n oldSnap: Node,\n newSnap: Node,\n optChangeAccumulator: ChildChangeAccumulator | null\n ): 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(\n oldSnap,\n filtered,\n optChangeAccumulator\n );\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(\n snap: Node,\n key: string,\n newChild: Node,\n affectedPath: Path,\n source: CompleteChildSource,\n optChangeAccumulator: ChildChangeAccumulator | null\n ): 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_\n .getIndexedFilter()\n .updateChild(\n snap,\n key,\n newChild,\n affectedPath,\n source,\n optChangeAccumulator\n );\n } else {\n return this.fullLimitUpdateChild_(\n snap,\n key,\n newChild,\n source,\n optChangeAccumulator\n );\n }\n }\n\n /**\n * @inheritDoc\n */\n updateFullNode(\n oldSnap: Node,\n newSnap: Node,\n optChangeAccumulator: ChildChangeAccumulator | null\n ): 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 (\n this.limit_ * 2 < newSnap.numChildren() &&\n newSnap.isIndexed(this.index_)\n ) {\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(\n this.rangedFilter_.getEndPost(),\n this.index_\n );\n } else {\n iterator = (newSnap as ChildrenNode).getIteratorFrom(\n this.rangedFilter_.getStartPost(),\n this.index_\n );\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 =\n this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;\n } else {\n inRange =\n 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(\n ChildrenNode.EMPTY_NODE\n ) 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 =\n foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;\n if (inRange) {\n count++;\n } else {\n filtered = filtered.updateImmediateChild(\n next.name,\n ChildrenNode.EMPTY_NODE\n );\n }\n }\n }\n }\n return this.rangedFilter_\n .getIndexedFilter()\n .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_(\n snap: Node,\n childKey: string,\n childSnap: Node,\n source: CompleteChildSource,\n changeAccumulator: ChildChangeAccumulator | null\n ): 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_\n ? oldEventCache.getFirstChild(this.index_)\n : 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(\n this.index_,\n windowBoundary,\n this.reverse_\n );\n while (\n nextChild != null &&\n (nextChild.name == childKey || oldEventCache.hasChild(nextChild.name))\n ) {\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(\n this.index_,\n nextChild,\n this.reverse_\n );\n }\n const compareNext =\n nextChild == null ? 1 : cmp(nextChild, newChildNamedNode);\n const remainsInWindow =\n inRange && !childSnap.isEmpty() && compareNext >= 0;\n if (remainsInWindow) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(\n Change.childChangedChange(childKey, childSnap, oldChildSnap)\n );\n }\n return oldEventCache.updateImmediateChild(childKey, childSnap);\n } else {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(\n Change.childRemovedChange(childKey, oldChildSnap)\n );\n }\n const newEventCache = oldEventCache.updateImmediateChild(\n childKey,\n ChildrenNode.EMPTY_NODE\n );\n const nextChildInRange =\n nextChild != null && this.rangedFilter_.matches(nextChild);\n if (nextChildInRange) {\n if (changeAccumulator != null) {\n changeAccumulator.trackChildChange(\n Change.childAddedChange(nextChild.name, nextChild.node)\n );\n }\n return newEventCache.updateImmediateChild(\n nextChild.name,\n nextChild.node\n );\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(\n Change.childRemovedChange(windowBoundary.name, windowBoundary.node)\n );\n changeAccumulator.trackChildChange(\n Change.childAddedChange(childKey, childSnap)\n );\n }\n return oldEventCache\n .updateImmediateChild(childKey, childSnap)\n .updateImmediateChild(windowBoundary.name, 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 { MIN_NAME, MAX_NAME } 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 (\n this.viewFrom_ === QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT\n );\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 * 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 { validateArgCount, validateCallback } from '../../utils/validation';\nimport {\n Deferred,\n attachDummyErrorHandler,\n PromiseImpl\n} 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(\n 'new Reference() no longer supported - use app.database().'\n );\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()) return null;\n else 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 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(\n this.path,\n newVal,\n /*priority=*/ null,\n deferred.wrapCallback(onComplete)\n );\n return deferred.promise;\n }\n\n /**\n * @param {!Object} objectToMerge\n * @param {function(?Error)=} onComplete\n * @return {!Promise}\n */\n update(\n objectToMerge: Object,\n onComplete?: (a: Error | null) => void\n ): 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(\n '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(\n 'Reference.update',\n 1,\n objectToMerge,\n this.path,\n false\n );\n validateCallback('Reference.update', 2, onComplete, true);\n const deferred = new Deferred();\n this.repo.update(\n this.path,\n objectToMerge,\n deferred.wrapCallback(onComplete)\n );\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(\n newVal: any,\n newPriority: string | number | null,\n onComplete?: (a: Error | null) => void\n ): Promise {\n validateArgCount('Reference.setWithPriority', 2, 3, arguments.length);\n validateWritablePath('Reference.setWithPriority', this.path);\n validateFirebaseDataArg(\n 'Reference.setWithPriority',\n 1,\n newVal,\n this.path,\n false\n );\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: ' +\n this.getKey() +\n ' is a read-only object.';\n\n const deferred = new Deferred();\n this.repo.setWithPriority(\n this.path,\n newVal,\n newPriority,\n deferred.wrapCallback(onComplete)\n );\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(\n transactionUpdate: (a: any) => any,\n onComplete?: (a: Error | null, b: boolean, c: DataSnapshot | null) => void,\n applyLocally?: boolean\n ): 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: ' +\n this.getKey() +\n ' is a read-only object.';\n\n if (applyLocally === undefined) applyLocally = true;\n\n const deferred = new Deferred();\n if (typeof onComplete === 'function') {\n attachDummyErrorHandler(deferred.promise);\n }\n\n const promiseComplete = function(\n error: Error,\n committed: boolean,\n snapshot: DataSnapshot\n ) {\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(\n this.path,\n transactionUpdate,\n promiseComplete,\n applyLocally\n );\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(\n priority: string | number | null,\n onComplete?: (a: Error | null) => void\n ): 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(\n this.path.child('.priority'),\n priority,\n null,\n deferred.wrapCallback(onComplete)\n );\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\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 { 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>(\n stringCompare\n );\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(\n public readonly value: T | null,\n public readonly children: SortedMap<\n string,\n ImmutableTree\n > = 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(\n relativePath: Path,\n predicate: (a: T) => boolean\n ): { 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 = child.findRootMostMatchingPathAndValue(\n relativePath.popFront(),\n predicate\n );\n if (childExistingPathAndValue != null) {\n const fullPath = new Path(front).child(\n childExistingPathAndValue.path\n );\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(\n relativePath: Path\n ): { 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_(\n pathSoFar: Path,\n fn: (path: Path, value: T | null, children: { [k: string]: V }) => V\n ): V {\n const accum: { [k: string]: V } = {};\n this.children.inorderTraversal(function(\n childKey: string,\n childTree: ImmutableTree\n ) {\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_(\n pathToFollow: Path,\n pathSoFar: Path,\n f: (path: Path, value: T) => V | null\n ): 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_(\n pathToFollow.popFront(),\n pathSoFar.child(front),\n f\n );\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(\n path: Path,\n f: (path: Path, value: T) => void\n ): ImmutableTree {\n return this.foreachOnPath_(path, Path.Empty, f);\n }\n\n private foreachOnPath_(\n pathToFollow: Path,\n currentRelativePath: Path,\n f: (path: Path, value: T) => void\n ): 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_(\n pathToFollow.popFront(),\n currentRelativePath.child(front),\n f\n );\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_(\n currentRelativePath: Path,\n f: (path: Path, value: T) => void\n ) {\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(\n (childName: string, childTree: ImmutableTree) => {\n if (childTree.value) {\n f(childName, childTree.value);\n }\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 { 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 updateChild(\n snap: Node,\n key: string,\n newChild: Node,\n affectedPath: Path,\n source: CompleteChildSource,\n optChangeAccumulator: ChildChangeAccumulator | null\n ): Node {\n assert(\n snap.isIndexed(this.index_),\n 'A node must be indexed if only a child is updated'\n );\n const oldChild = snap.getImmediateChild(key);\n // Check if anything actually changed.\n if (\n oldChild.getChild(affectedPath).equals(newChild.getChild(affectedPath))\n ) {\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(\n Change.childRemovedChange(key, oldChild)\n );\n } else {\n assert(\n snap.isLeafNode(),\n 'A child remove without an old child only makes sense on a leaf node'\n );\n }\n } else if (oldChild.isEmpty()) {\n optChangeAccumulator.trackChildChange(\n Change.childAddedChange(key, newChild)\n );\n } else {\n optChangeAccumulator.trackChildChange(\n Change.childChangedChange(key, newChild, oldChild)\n );\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(\n oldSnap: Node,\n newSnap: Node,\n optChangeAccumulator: ChildChangeAccumulator | null\n ): 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(\n Change.childRemovedChange(key, childNode)\n );\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(\n Change.childChangedChange(key, childNode, oldChild)\n );\n }\n } else {\n optChangeAccumulator.trackChildChange(\n Change.childAddedChange(key, childNode)\n );\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 { 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)) 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// 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(\n repoInfo: RepoInfo,\n creatorFunction: () => T\n ): 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 { 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 { LUIDGenerator, warn, exceptionGuard } 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(\n path: Path,\n transactionUpdate: (a: any) => void,\n onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null,\n applyLocally: boolean\n ): 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(\n path: Path,\n transactionUpdate: (a: any) => any,\n onComplete: ((a: Error, b: boolean, c: DataSnapshot) => void) | null,\n applyLocally: boolean\n) {\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() {\n watchRef.off('value', valueCallback);\n };\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 // 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(\n transaction.currentInputSnapshot,\n new Reference(this, transaction.path),\n PRIORITY_INDEX\n );\n transaction.onComplete(null, false, snapshot);\n }\n } else {\n validateFirebaseData(\n 'transaction failed: Data returned ',\n newVal,\n transaction.path\n );\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 (\n typeof newVal === 'object' &&\n newVal !== null &&\n contains(newVal, '.priority')\n ) {\n priorityForNode = safeGet(newVal, '.priority');\n assert(\n isValidPriority(priorityForNode),\n 'Invalid priority returned by transaction. ' +\n 'Priority must be a valid string, finite number, server value, or null.'\n );\n } else {\n const currentNode =\n this.serverSyncTree_.calcCompleteEventCache(path) ||\n 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(\n newNodeUnresolved,\n serverValues\n );\n transaction.currentOutputSnapshotRaw = newNodeUnresolved;\n transaction.currentOutputSnapshotResolved = newNode;\n transaction.currentWriteId = this.getNextWriteId_();\n\n const events = this.serverSyncTree_.applyUserOverwrite(\n path,\n newNode,\n transaction.currentWriteId,\n transaction.applyLocally\n );\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(\n path: Path,\n excludeSets?: number[]\n): Node {\n return (\n this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) ||\n 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(\n node: Tree = this.transactionQueueTree_\n) {\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(\n (transaction: Transaction) => transaction.status === TransactionStatus.RUN\n );\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 * 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(\n path: Path,\n queue: Array\n) {\n // Mark transactions as sent and increment retry count!\n const setsToIgnore = queue.map(function(txn) {\n return txn.currentWriteId;\n });\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(\n txn.status === TransactionStatus.RUN,\n 'tryToSendTransactionQueue_: items in queue should all be run.'\n );\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(\n relativePath /**@type {!Node} */,\n txn.currentOutputSnapshotRaw\n );\n }\n\n const dataToSend = snapToSend.val(true);\n const pathToSend = path;\n\n // Send the put.\n this.server_.put(\n pathToSend.toString(),\n dataToSend,\n (status: string) => {\n this.log_('transaction put response', {\n path: pathToSend.toString(),\n status\n });\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(\n this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId)\n );\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(\n queue[i].onComplete.bind(null, null, true, snapshot)\n );\n }\n queue[i].unwatcher();\n }\n\n // Now remove the completed transactions.\n this.pruneCompletedTransactionsBelowNode_(\n this.transactionQueueTree_.subTree(path)\n );\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 queue[i].status = TransactionStatus.RUN;\n }\n } else {\n warn(\n 'transaction at ' + pathToSend.toString() + ' failed: ' + status\n );\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 },\n latestHash\n );\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 * 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(\n queue: Array,\n path: Path\n) {\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) {\n return q.status === TransactionStatus.RUN;\n });\n const setsToIgnore = txnsToRerun.map(function(q) {\n return q.currentWriteId;\n });\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,\n abortReason;\n assert(\n relativePath !== null,\n 'rerunTransactionsUnderNode_: relativePath should not be null.'\n );\n\n if (transaction.status === TransactionStatus.NEEDS_ABORT) {\n abortTransaction = true;\n abortReason = transaction.abortReason;\n events = events.concat(\n this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true)\n );\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(\n this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true)\n );\n } else {\n // This code reruns a transaction\n const currentNode = this.getLatestState_(\n transaction.path,\n setsToIgnore\n );\n transaction.currentInputSnapshot = currentNode;\n const newData = queue[i].update(currentNode.val());\n if (newData !== undefined) {\n validateFirebaseData(\n 'transaction failed: Data returned ',\n newData,\n transaction.path\n );\n let newDataNode = nodeFromJSON(newData);\n const hasExplicitPriority =\n typeof newData === 'object' &&\n 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(\n newDataNode,\n serverValues\n );\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(\n transaction.path,\n newNodeResolved,\n transaction.currentWriteId,\n transaction.applyLocally\n )\n );\n events = events.concat(\n this.serverSyncTree_.ackUserWrite(oldWriteId, true)\n );\n } else {\n abortTransaction = true;\n abortReason = 'nodata';\n events = events.concat(\n this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true)\n );\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(\n queue[i].onComplete.bind(null, new Error(abortReason), false, null)\n );\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 * 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(\n path: Path\n): 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 (\n (front = path.getFront()) !== null &&\n transactionNode.getValue() === null\n ) {\n transactionNode = transactionNode.subTree(front);\n path = path.popFront();\n }\n\n return transactionNode;\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(\n transactionNode: Tree\n): 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) {\n return a.order - b.order;\n });\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(\n node: Tree,\n queue: Array\n) {\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 * 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(\n node: Tree\n) {\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 * 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 * 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(\n node: Tree\n) {\n const 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 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(\n lastSent === i - 1,\n 'All SENT items should be at beginning of queue.'\n );\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(\n queue[i].status === TransactionStatus.RUN,\n 'Unexpected transaction status in abort'\n );\n // We can abort it immediately.\n queue[i].unwatcher();\n events = events.concat(\n this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId, true)\n );\n if (queue[i].onComplete) {\n const snapshot: DataSnapshot | null = null;\n callbacks.push(\n queue[i].onComplete.bind(null, new Error('set'), false, snapshot)\n );\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 * 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(\n 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 ? pathObj : new Path(pathObj);\n let child = this as any,\n 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(\n action: (tree: Tree) => void,\n includeSelf?: boolean,\n childrenFirst?: boolean\n ) {\n if (includeSelf && !childrenFirst) action(this);\n\n this.forEachChild(function(child) {\n child.forEachDescendant(action, /*includeSelf=*/ true, childrenFirst);\n });\n\n if (includeSelf && childrenFirst) 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(\n action: (tree: Tree) => void,\n includeSelf?: boolean\n ): 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) action(child);\n else 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(\n this.parent_ === null\n ? this.name_\n : this.parent_.path() + '/' + this.name_\n );\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) 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 } 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 [appName: string]: {\n [dbUrl: string]: Repo;\n };\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 appName in this.repos_) {\n for (const dbUrl in this.repos_[appName]) {\n this.repos_[appName][dbUrl].interrupt();\n }\n }\n }\n\n resume() {\n for (const appName in this.repos_) {\n for (const dbUrl in this.repos_[appName]) {\n this.repos_[appName][dbUrl].resume();\n }\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, url?: string): Database {\n const dbUrl: string = url || app.options[DATABASE_URL_OPTION];\n if (dbUrl === undefined) {\n fatal(\n \"Can't determine Firebase Database URL. Be sure to include \" +\n DATABASE_URL_OPTION +\n ' option when calling firebase.intializeApp().'\n );\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(\n 'Database URL must point to the root of a Firebase Database ' +\n '(not including a child path).'\n );\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 const appRepos = safeGet(this.repos_, repo.app.name);\n // This should never happen...\n if (!appRepos || safeGet(appRepos, repo.repoInfo_.toURLString()) !== repo) {\n fatal(\n `Database ${repo.app.name}(${repo.repoInfo_}) has already been deleted.`\n );\n }\n repo.interrupt();\n delete appRepos[repo.repoInfo_.toURLString()];\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 appRepos = safeGet(this.repos_, app.name);\n\n if (!appRepos) {\n appRepos = {};\n this.repos_[app.name] = appRepos;\n }\n\n let repo = safeGet(appRepos, repoInfo.toURLString());\n if (repo) {\n fatal(\n 'Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.'\n );\n }\n repo = new Repo(repoInfo, this.useRestClient_, app);\n appRepos[repoInfo.toURLString()] = 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\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(\n \"Don't call new Database() directly - please use firebase.database().\"\n );\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(\n apiName +\n ': Host name does not match the current database: ' +\n '(found ' +\n repoInfo.host +\n ' but expected ' +\n ((this.repo_ as any).repoInfo_ as RepoInfo).host +\n ')'\n );\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 /** @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// 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 { 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(\n dataURL: string\n): { repoInfo: RepoInfo; path: Path } {\n const parsedUrl = parseURL(dataURL),\n namespace = parsedUrl.subdomain;\n\n if (parsedUrl.domain === 'firebase') {\n fatal(\n parsedUrl.host +\n ' is no longer supported. ' +\n 'Please use .firebaseio.com instead'\n );\n }\n\n // Catch common error of uninitialized namespace value.\n if (!namespace || namespace == 'undefined') {\n fatal(\n 'Cannot parse Firebase url. Please use https://.firebaseio.com'\n );\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(\n parsedUrl.host,\n parsedUrl.secure,\n namespace,\n webSocketOnly\n ),\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(\n dataURL: string\n): {\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 = '',\n domain = '',\n subdomain = '',\n pathString = '';\n\n // Always default to SSL, unless otherwise specified.\n let secure = true,\n scheme = 'https',\n 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\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\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 * 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(\n host: string,\n public secure: boolean,\n public namespace: string,\n public webSocketOnly: boolean,\n public persistenceKey: string = ''\n ) {\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 (\n this.domain !== 'firebaseio.com' && this.domain !== 'firebaseio-demo.com'\n );\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 =\n (this.secure ? 'wss://' : 'ws://') + this.internalHost + '/.ws?';\n } else if (type === LONG_POLLING) {\n connURL =\n (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 { 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 * 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(\n public eventType:\n | 'value'\n | ' child_added'\n | ' child_changed'\n | ' child_moved'\n | ' 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 (\n this.getPath().toString() +\n ':' +\n this.eventType +\n ':' +\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(\n 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 * 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(\n 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(\n 'value',\n this,\n new DataSnapshot(change.snapshotNode, query.getRef(), index)\n );\n }\n\n /**\n * @inheritDoc\n */\n getEventRunner(eventData: CancelEvent | DataEvent): () => void {\n const ctx = this.context_;\n if (eventData.getEventType() === 'cancel') {\n assert(\n this.cancelCallback_,\n 'Raising a cancel event on a listener with no cancel callback'\n );\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 (\n other.callback_ === this.callback_ && other.context_ === this.context_\n );\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(\n private callbacks_:\n | ({ [k: string]: (d: DataSnapshot, s?: string | null) => void })\n | 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 =\n eventType === 'children_added' ? 'child_added' : eventType;\n eventToCheck =\n 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(\n change.type as any,\n this,\n new DataSnapshot(change.snapshotNode, ref, index as any),\n change.prevName\n );\n }\n\n /**\n * @inheritDoc\n */\n getEventRunner(eventData: CancelEvent | DataEvent): () => void {\n const ctx = this.context_;\n if (eventData.getEventType() === 'cancel') {\n assert(\n this.cancelCallback_,\n 'Raising a cancel event on a listener with no cancel callback'\n );\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(\n ctx,\n (eventData as DataEvent).snapshot,\n (eventData as DataEvent).prevName\n );\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 (\n thisKey === otherKey &&\n (!other.callbacks_[otherKey] ||\n !this.callbacks_[thisKey] ||\n other.callbacks_[otherKey] === this.callbacks_[thisKey])\n );\n } else {\n // Exact match on each key.\n return every(\n this.callbacks_,\n (eventType, cb) => other.callbacks_[eventType] === cb\n );\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// 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 { 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 {\n errorPrefix,\n validateArgCount,\n validateCallback,\n validateContextObject\n} from '../../utils/validation';\nimport {\n ValueEventRegistration,\n ChildEventRegistration,\n EventRegistration\n} 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(\n public repo: Repo,\n public path: Path,\n private queryParams_: QueryParams,\n private orderByCalled_: boolean\n ) {}\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 =\n 'Query: When ordering by key, you may only pass one argument to ' +\n 'startAt(), endAt(), or equalTo().';\n const wrongArgTypeError =\n '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 } else if (params.getIndex() === PRIORITY_INDEX) {\n if (\n (startNode != null && !isValidPriority(startNode)) ||\n (endNode != null && !isValidPriority(endNode))\n ) {\n throw new Error(\n '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 }\n } else {\n assert(\n params.getIndex() instanceof PathIndex ||\n params.getIndex() === VALUE_INDEX,\n 'unknown index type.'\n );\n if (\n (startNode != null && typeof startNode === 'object') ||\n (endNode != null && typeof endNode === 'object')\n ) {\n throw new Error(\n 'Query: First argument passed to startAt(), endAt(), or equalTo() cannot be ' +\n 'an object.'\n );\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 (\n params.hasStart() &&\n params.hasEnd() &&\n params.hasLimit() &&\n !params.hasAnchoredLimit()\n ) {\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(\n eventType: string,\n callback: SnapshotCallback,\n cancelCallbackOrContext?: ((a: Error) => any) | Object,\n context?: Object\n ): 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_(\n 'Query.on',\n cancelCallbackOrContext,\n context\n );\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(\n callback: (a: DataSnapshot) => void,\n cancelCallback: ((a: Error) => void) | null,\n context: Object | null\n ) {\n const container = new ValueEventRegistration(\n callback,\n cancelCallback || null,\n context || null\n );\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(\n callbacks: { [k: string]: SnapshotCallback },\n cancelCallback: ((a: Error) => any) | null,\n context: Object | null\n ) {\n const container = new ChildEventRegistration(\n callbacks,\n cancelCallback,\n context\n );\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(\n valueCallback,\n null,\n context || null\n );\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(\n eventType: string,\n userCallback?: SnapshotCallback,\n cancelOrContext?: ((a: Error) => void) | Object,\n context?: Object\n ): 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_(\n 'Query.once',\n cancelOrContext,\n context\n );\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(\n eventType,\n onceCallback,\n /*cancel=*/ err => {\n this.off(eventType, onceCallback);\n\n if (ret.cancel) ret.cancel.bind(ret.context)(err);\n deferred.reject(err);\n }\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 (\n typeof limit !== 'number' ||\n Math.floor(limit) !== limit ||\n limit <= 0\n ) {\n throw new Error(\n 'Query.limitToFirst: First argument must be a positive integer.'\n );\n }\n if (this.queryParams_.hasLimit()) {\n throw new Error(\n 'Query.limitToFirst: Limit was already set (by another call to limit, ' +\n 'limitToFirst, or limitToLast).'\n );\n }\n\n return new Query(\n this.repo,\n this.path,\n this.queryParams_.limitToFirst(limit),\n this.orderByCalled_\n );\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 (\n typeof limit !== 'number' ||\n Math.floor(limit) !== limit ||\n limit <= 0\n ) {\n throw new Error(\n 'Query.limitToLast: First argument must be a positive integer.'\n );\n }\n if (this.queryParams_.hasLimit()) {\n throw new Error(\n 'Query.limitToLast: Limit was already set (by another call to limit, ' +\n 'limitToFirst, or limitToLast).'\n );\n }\n\n return new Query(\n this.repo,\n this.path,\n this.queryParams_.limitToLast(limit),\n this.orderByCalled_\n );\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(\n 'Query.orderByChild: \"$key\" is invalid. Use Query.orderByKey() instead.'\n );\n } else if (path === '$priority') {\n throw new Error(\n 'Query.orderByChild: \"$priority\" is invalid. Use Query.orderByPriority() instead.'\n );\n } else if (path === '$value') {\n throw new Error(\n 'Query.orderByChild: \"$value\" is invalid. Use Query.orderByValue() instead.'\n );\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(\n 'Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.'\n );\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(\n value: number | string | boolean | null = null,\n name?: string | null\n ): 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(\n 'Query.startAt: Starting point was already set (by another call to startAt ' +\n 'or equalTo).'\n );\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(\n value: number | string | boolean | null = null,\n name?: string | null\n ): 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(\n 'Query.endAt: Ending point was already set (by another call to endAt or ' +\n 'equalTo).'\n );\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(\n 'Query.equalTo: Starting point was already set (by another call to startAt or ' +\n 'equalTo).'\n );\n }\n if (this.queryParams_.hasEnd()) {\n throw new Error(\n 'Query.equalTo: Ending point was already set (by another call to endAt or ' +\n 'equalTo).'\n );\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 =\n '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 =\n 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_(\n fnName: string,\n cancelOrContext?: ((a: Error) => void) | Object,\n context?: Object\n ): { cancel: ((a: Error) => void) | null; context: Object | null } {\n const ret: {\n cancel: ((a: Error) => void) | null;\n context: Object | null;\n } = { 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) {\n // we have either a cancel callback or a context.\n if (typeof cancelOrContext === 'object' && cancelOrContext !== null) {\n // it's a context!\n ret.context = cancelOrContext;\n } else if (typeof cancelOrContext === 'function') {\n ret.cancel = cancelOrContext;\n } else {\n throw new Error(\n errorPrefix(fnName, 3, true) +\n ' must either be a cancel callback or a context object.'\n );\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 { doubleToIEEE754String } 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 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(\n typeof val === 'string' ||\n typeof val === 'number' ||\n (typeof val === 'object' && contains(val, '.sv')),\n 'Priority must be a string or number.'\n );\n } else {\n assert(\n priorityNode === MAX_NODE || priorityNode.isEmpty(),\n 'priority of unexpected type.'\n );\n }\n // Don't call getPriority() on MAX_NODE to avoid hitting assertion.\n assert(\n priorityNode === MAX_NODE || priorityNode.getPriority().isEmpty(),\n \"Priority nodes can't have a priority of their own.\"\n );\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 { 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\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 { 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(\n fallbackObject && PRIORITY_INDEX,\n 'ChildrenNode.ts has not been loaded'\n );\n _defaultIndexMap =\n _defaultIndexMap ||\n new IndexMap(\n { '.priority': fallbackObject },\n { '.priority': PRIORITY_INDEX }\n );\n return _defaultIndexMap;\n }\n\n constructor(\n private indexes_: {\n [k: string]: SortedMap | /*FallbackType*/ object;\n },\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(\n indexDefinition: Index,\n existingChildren: SortedMap\n ): IndexMap {\n assert(\n indexDefinition !== KEY_INDEX,\n \"KeyIndex always exists and isn't meant to be added to the IndexMap.\"\n );\n const childList = [];\n let sawIndexedValue = false;\n const iter = existingChildren.getIterator(NamedNode.Wrap);\n let next = iter.getNext();\n while (next) {\n sawIndexedValue =\n 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 * 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(\n namedNode: NamedNode,\n existingChildren: SortedMap\n ): IndexMap {\n const newIndexes = map(\n this.indexes_,\n (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(\n new NamedNode(namedNode.name, existingSnap)\n );\n }\n return newChildren.insert(namedNode, namedNode.node);\n }\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(\n namedNode: NamedNode,\n existingChildren: SortedMap\n ): IndexMap {\n const newIndexes = map(this.indexes_, function(\n indexedChildren: SortedMap\n ) {\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(\n new NamedNode(namedNode.name, existingSnap)\n );\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 { 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) =>\n 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(\n childList: NamedNode[],\n cmp: (a: NamedNode, b: NamedNode) => number,\n keyFn?: (a: NamedNode) => K,\n mapSortFn?: (a: K, b: K) => number\n): SortedMap {\n childList.sort(cmp);\n\n const buildBalancedTree = function(\n low: number,\n high: number\n ): 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(\n key,\n (namedNode.node as any) as V,\n LLRBNode.BLACK,\n null,\n null\n );\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(\n key,\n (namedNode.node as any) as V,\n LLRBNode.BLACK,\n left,\n right\n );\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(\n new LLRBNode(key, (namedNode.node as any) as V, color, null, childTree)\n );\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\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 { 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 { 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(\n !indexPath_.isEmpty() && indexPath_.getFront() !== '.priority',\n \"Can't create PathIndex with empty path or .priority key\"\n );\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 * @inheritDoc\n */\n isDefinedOn(node: Node): boolean {\n return !node.getChild(this.indexPath_).isEmpty();\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 * @inheritDoc\n */\n makePost(indexValue: object, name: string): NamedNode {\n const valueNode = nodeFromJSON(indexValue);\n const node = ChildrenNode.EMPTY_NODE.updateChild(\n this.indexPath_,\n valueNode\n );\n return new NamedNode(name, node);\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 * @inheritDoc\n */\n toString(): string {\n return this.indexPath_.slice().join('/');\n }\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(\n 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(\n this.node_.getChild(childPath),\n childRef,\n PRIORITY_INDEX\n );\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()) 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(\n new DataSnapshot(node, this.ref_.child(key), PRIORITY_INDEX)\n );\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()) return false;\n else 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 { 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: {\n [k: string]: any;\n} | null): { [k: string]: any } {\n values = values || {};\n values['timestamp'] = values['timestamp'] || new Date().getTime();\n return values;\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(\n value: { [k: string]: any } | string | number | boolean,\n serverValues: { [k: string]: any }\n): 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 * 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(\n tree: SparseSnapshotTree,\n serverValues: Object\n): SparseSnapshotTree {\n const resolvedTree = new SparseSnapshotTree();\n tree.forEachTree(new Path(''), function(path, node) {\n resolvedTree.remember(\n path,\n resolveDeferredValueSnapshot(node, serverValues)\n );\n });\n return resolvedTree;\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(\n node: Node,\n serverValues: Object\n): Node {\n const rawPri = node.getPriority().val() as\n | object\n | boolean\n | null\n | number\n | 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 (\n value !== leafNode.getValue() ||\n priority !== leafNode.getPriority().val()\n ) {\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(\n childNode,\n serverValues\n );\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 { 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(\n childKey\n ) 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 } 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 { 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 { 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(\n private node_: Node,\n private fullyInitialized_: boolean,\n private filtered_: boolean\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 (\n (this.isFullyInitialized() && !this.filtered_) || this.node_.hasChild(key)\n );\n }\n\n /**\n * @return {!Node}\n */\n getNode(): Node {\n return this.node_;\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(\n 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(\n ChildrenNode.EMPTY_NODE,\n /*fullyInitialized=*/ false,\n /*filtered=*/ false\n ),\n new CacheNode(\n ChildrenNode.EMPTY_NODE,\n /*fullyInitialized=*/ false,\n /*filtered=*/ false\n )\n );\n\n /**\n * @param {!Node} eventSnap\n * @param {boolean} complete\n * @param {boolean} filtered\n * @return {!ViewCache}\n */\n updateEventSnap(\n eventSnap: Node,\n complete: boolean,\n filtered: boolean\n ): ViewCache {\n return new ViewCache(\n new CacheNode(eventSnap, complete, filtered),\n this.serverCache_\n );\n }\n\n /**\n * @param {!Node} serverSnap\n * @param {boolean} complete\n * @param {boolean} filtered\n * @return {!ViewCache}\n */\n updateServerSnap(\n serverSnap: Node,\n complete: boolean,\n filtered: boolean\n ): ViewCache {\n return new ViewCache(\n this.eventCache_,\n new CacheNode(serverSnap, complete, filtered)\n );\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()\n ? this.eventCache_.getNode()\n : 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()\n ? this.serverCache_.getNode()\n : null;\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 { 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(\n type == Change.CHILD_ADDED ||\n type == Change.CHILD_CHANGED ||\n type == Change.CHILD_REMOVED,\n 'Only child changes supported for tracking'\n );\n assert(\n childKey !== '.priority',\n 'Only non-priority child changes can be tracked.'\n );\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(\n childKey,\n change.snapshotNode,\n oldChange.snapshotNode\n );\n } else if (\n type == Change.CHILD_REMOVED &&\n oldType == Change.CHILD_ADDED\n ) {\n delete this.changeMap_[childKey];\n } else if (\n type == Change.CHILD_REMOVED &&\n oldType == Change.CHILD_CHANGED\n ) {\n this.changeMap_[childKey] = Change.childRemovedChange(\n childKey,\n oldChange.oldSnap\n );\n } else if (\n type == Change.CHILD_CHANGED &&\n oldType == Change.CHILD_ADDED\n ) {\n this.changeMap_[childKey] = Change.childAddedChange(\n childKey,\n change.snapshotNode\n );\n } else if (\n type == Change.CHILD_CHANGED &&\n oldType == Change.CHILD_CHANGED\n ) {\n this.changeMap_[childKey] = Change.childChangedChange(\n childKey,\n change.snapshotNode,\n oldChange.oldSnap\n );\n } else {\n throw assertionError(\n 'Illegal combination of changes: ' +\n change +\n ' occurred after ' +\n oldChange\n );\n }\n } else {\n this.changeMap_[childKey] = change;\n }\n }\n\n /**\n * @return {!Array.}\n */\n getChanges(): Change[] {\n return getValues(this.changeMap_);\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(\n index: Index,\n child: NamedNode,\n reverse: boolean\n ): NamedNode | null;\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 * @inheritDoc\n */\n getCompleteChild(childKey?: string): Node | null {\n return null;\n }\n\n /**\n * @inheritDoc\n */\n getChildAfterChild(\n index?: Index,\n child?: NamedNode,\n reverse?: boolean\n ): NamedNode | null {\n return null;\n }\n}\n\n/**\n * Singleton instance.\n * @const\n * @type {!CompleteChildSource}\n */\nexport const NO_COMPLETE_CHILD_SOURCE = new NoCompleteChildSource_();\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(\n 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 =\n this.optCompleteServerCache_ != null\n ? new CacheNode(this.optCompleteServerCache_, true, false)\n : this.viewCache_.getServerCache();\n return this.writes_.calcCompleteChild(childKey, serverNode);\n }\n }\n\n /**\n * @inheritDoc\n */\n getChildAfterChild(\n index: Index,\n child: NamedNode,\n reverse: boolean\n ): NamedNode | null {\n const completeServerData =\n this.optCompleteServerCache_ != null\n ? this.optCompleteServerCache_\n : this.viewCache_.getCompleteServerSnap();\n const nodes = this.writes_.calcIndexedSlice(\n completeServerData,\n child,\n 1,\n reverse,\n index\n );\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 {\n WriteTreeCompleteChildSource,\n NO_COMPLETE_CHILD_SOURCE,\n CompleteChildSource\n} 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(\n 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 * @param {!ViewCache} viewCache\n */\n assertIndexed(viewCache: ViewCache) {\n assert(\n viewCache.getEventCache().getNode().isIndexed(this.filter_.getIndex()),\n 'Event snap not indexed'\n );\n assert(\n viewCache.getServerCache().getNode().isIndexed(this.filter_.getIndex()),\n 'Server snap not indexed'\n );\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(\n oldViewCache: ViewCache,\n operation: Operation,\n writesCache: WriteTreeRef,\n completeCache: Node | null\n ): 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_(\n oldViewCache,\n overwrite.path,\n overwrite.snap,\n writesCache,\n completeCache,\n accumulator\n );\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 =\n overwrite.source.tagged ||\n (oldViewCache.getServerCache().isFiltered() &&\n !overwrite.path.isEmpty());\n newViewCache = this.applyServerOverwrite_(\n oldViewCache,\n overwrite.path,\n overwrite.snap,\n writesCache,\n completeCache,\n filterServerNode,\n accumulator\n );\n }\n } else if (operation.type === OperationType.MERGE) {\n const merge = operation as Merge;\n if (merge.source.fromUser) {\n newViewCache = this.applyUserMerge_(\n oldViewCache,\n merge.path,\n merge.children,\n writesCache,\n completeCache,\n accumulator\n );\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 =\n merge.source.tagged || oldViewCache.getServerCache().isFiltered();\n newViewCache = this.applyServerMerge_(\n oldViewCache,\n merge.path,\n merge.children,\n writesCache,\n completeCache,\n filterServerNode,\n accumulator\n );\n }\n } else if (operation.type === OperationType.ACK_USER_WRITE) {\n const ackUserWrite = operation as AckUserWrite;\n if (!ackUserWrite.revert) {\n newViewCache = this.ackUserWrite_(\n oldViewCache,\n ackUserWrite.path,\n ackUserWrite.affectedTree,\n writesCache,\n completeCache,\n accumulator\n );\n } else {\n newViewCache = this.revertUserWrite_(\n oldViewCache,\n ackUserWrite.path,\n writesCache,\n completeCache,\n accumulator\n );\n }\n } else if (operation.type === OperationType.LISTEN_COMPLETE) {\n newViewCache = this.listenComplete_(\n oldViewCache,\n operation.path,\n writesCache,\n accumulator\n );\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_(\n oldViewCache: ViewCache,\n newViewCache: ViewCache,\n accumulator: Change[]\n ) {\n const eventSnap = newViewCache.getEventCache();\n if (eventSnap.isFullyInitialized()) {\n const isLeafOrEmpty =\n eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty();\n const oldCompleteSnap = oldViewCache.getCompleteEventSnap();\n if (\n accumulator.length > 0 ||\n !oldViewCache.getEventCache().isFullyInitialized() ||\n (isLeafOrEmpty &&\n !eventSnap.getNode().equals /** @type {!Node} */(oldCompleteSnap)) ||\n !eventSnap.getNode().getPriority().equals(oldCompleteSnap.getPriority())\n ) {\n accumulator.push(\n Change.valueChange(\n /** @type {!Node} */ newViewCache.getCompleteEventSnap()\n )\n );\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_(\n viewCache: ViewCache,\n changePath: Path,\n writesCache: WriteTreeRef,\n source: CompleteChildSource,\n accumulator: ChildChangeAccumulator\n ): 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(\n viewCache.getServerCache().isFullyInitialized(),\n 'If change path is empty, we must have complete server data'\n );\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 =\n serverCache instanceof ChildrenNode\n ? serverCache\n : ChildrenNode.EMPTY_NODE;\n const completeEventChildren = writesCache.calcCompleteEventChildren(\n completeChildren\n );\n newEventCache = this.filter_.updateFullNode(\n viewCache.getEventCache().getNode(),\n completeEventChildren,\n accumulator\n );\n } else {\n const completeNode = writesCache.calcCompleteEventCache(\n viewCache.getCompleteServerSnap()\n );\n newEventCache = this.filter_.updateFullNode(\n viewCache.getEventCache().getNode(),\n completeNode,\n accumulator\n );\n }\n } else {\n const childKey = changePath.getFront();\n if (childKey == '.priority') {\n assert(\n changePath.getLength() == 1,\n \"Can't have a priority with additional path components\"\n );\n const oldEventNode = oldEventSnap.getNode();\n serverNode = viewCache.getServerCache().getNode();\n // we might have overwrites for this priority\n const updatedPriority = writesCache.calcEventCacheAfterServerOverwrite(\n changePath,\n oldEventNode,\n serverNode\n );\n if (updatedPriority != null) {\n newEventCache = this.filter_.updatePriority(\n oldEventNode,\n updatedPriority\n );\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(\n changePath,\n oldEventSnap.getNode(),\n serverNode\n );\n if (eventChildUpdate != null) {\n newEventChild = oldEventSnap\n .getNode()\n .getImmediateChild(childKey)\n .updateChild(childChangePath, eventChildUpdate);\n } else {\n // Nothing changed, just keep the old child\n newEventChild = oldEventSnap\n .getNode()\n .getImmediateChild(childKey);\n }\n } else {\n newEventChild = writesCache.calcCompleteChild(\n childKey,\n viewCache.getServerCache()\n );\n }\n if (newEventChild != null) {\n newEventCache = this.filter_.updateChild(\n oldEventSnap.getNode(),\n childKey,\n newEventChild,\n childChangePath,\n source,\n accumulator\n );\n } else {\n // no complete child available or no change\n newEventCache = oldEventSnap.getNode();\n }\n }\n }\n return viewCache.updateEventSnap(\n newEventCache,\n oldEventSnap.isFullyInitialized() || changePath.isEmpty(),\n this.filter_.filtersNodes()\n );\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_(\n oldViewCache: ViewCache,\n changePath: Path,\n changedSnap: Node,\n writesCache: WriteTreeRef,\n completeCache: Node | null,\n filterServerNode: boolean,\n accumulator: ChildChangeAccumulator\n ): ViewCache {\n const oldServerSnap = oldViewCache.getServerCache();\n let newServerCache;\n const serverFilter = filterServerNode\n ? this.filter_\n : this.filter_.getIndexedFilter();\n if (changePath.isEmpty()) {\n newServerCache = serverFilter.updateFullNode(\n oldServerSnap.getNode(),\n changedSnap,\n null\n );\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\n .getNode()\n .updateChild(changePath, changedSnap);\n newServerCache = serverFilter.updateFullNode(\n oldServerSnap.getNode(),\n newServerNode,\n null\n );\n } else {\n const childKey = changePath.getFront();\n if (\n !oldServerSnap.isCompleteForPath(changePath) &&\n changePath.getLength() > 1\n ) {\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(\n oldServerSnap.getNode(),\n newChildNode\n );\n } else {\n newServerCache = serverFilter.updateChild(\n oldServerSnap.getNode(),\n childKey,\n newChildNode,\n childChangePath,\n NO_COMPLETE_CHILD_SOURCE,\n null\n );\n }\n }\n const newViewCache = oldViewCache.updateServerSnap(\n newServerCache,\n oldServerSnap.isFullyInitialized() || changePath.isEmpty(),\n serverFilter.filtersNodes()\n );\n const source = new WriteTreeCompleteChildSource(\n writesCache,\n newViewCache,\n completeCache\n );\n return this.generateEventCacheAfterServerEvent_(\n newViewCache,\n changePath,\n writesCache,\n source,\n accumulator\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 {!ChildChangeAccumulator} accumulator\n * @return {!ViewCache}\n * @private\n */\n applyUserOverwrite_(\n oldViewCache: ViewCache,\n changePath: Path,\n changedSnap: Node,\n writesCache: WriteTreeRef,\n completeCache: Node | null,\n accumulator: ChildChangeAccumulator\n ): ViewCache {\n const oldEventSnap = oldViewCache.getEventCache();\n let newViewCache, newEventCache;\n const source = new WriteTreeCompleteChildSource(\n writesCache,\n oldViewCache,\n completeCache\n );\n if (changePath.isEmpty()) {\n newEventCache = this.filter_.updateFullNode(\n oldViewCache.getEventCache().getNode(),\n changedSnap,\n accumulator\n );\n newViewCache = oldViewCache.updateEventSnap(\n newEventCache,\n true,\n this.filter_.filtersNodes()\n );\n } else {\n const childKey = changePath.getFront();\n if (childKey === '.priority') {\n newEventCache = this.filter_.updatePriority(\n oldViewCache.getEventCache().getNode(),\n changedSnap\n );\n newViewCache = oldViewCache.updateEventSnap(\n newEventCache,\n oldEventSnap.isFullyInitialized(),\n oldEventSnap.isFiltered()\n );\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 (\n childChangePath.getBack() === '.priority' &&\n childNode.getChild(childChangePath.parent()).isEmpty()\n ) {\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(\n oldEventSnap.getNode(),\n childKey,\n newChild,\n childChangePath,\n source,\n accumulator\n );\n newViewCache = oldViewCache.updateEventSnap(\n newEventSnap,\n oldEventSnap.isFullyInitialized(),\n this.filter_.filtersNodes()\n );\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_(\n viewCache: ViewCache,\n childKey: string\n ): 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_(\n viewCache: ViewCache,\n path: Path,\n changedChildren: ImmutableTree,\n writesCache: WriteTreeRef,\n serverCache: Node | null,\n accumulator: ChildChangeAccumulator\n ): 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_(\n curViewCache,\n writePath,\n childNode,\n writesCache,\n serverCache,\n accumulator\n );\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_(\n curViewCache,\n writePath,\n childNode,\n writesCache,\n serverCache,\n accumulator\n );\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_(\n viewCache: ViewCache,\n path: Path,\n changedChildren: ImmutableTree,\n writesCache: WriteTreeRef,\n serverCache: Node | null,\n filterServerNode: boolean,\n accumulator: ChildChangeAccumulator\n ): 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 (\n viewCache.getServerCache().getNode().isEmpty() &&\n !viewCache.getServerCache().isFullyInitialized()\n ) {\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\n .getServerCache()\n .getNode()\n .getImmediateChild(childKey);\n const newChild = this.applyMerge_(serverChild, childTree);\n curViewCache = this.applyServerOverwrite_(\n curViewCache,\n new Path(childKey),\n newChild,\n writesCache,\n serverCache,\n filterServerNode,\n accumulator\n );\n }\n });\n viewMergeTree.children.inorderTraversal((childKey, childMergeTree) => {\n const isUnknownDeepMerge =\n !viewCache.getServerCache().isCompleteForChild(childKey) &&\n childMergeTree.value == null;\n if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {\n const serverChild = viewCache\n .getServerCache()\n .getNode()\n .getImmediateChild(childKey);\n const newChild = this.applyMerge_(serverChild, childMergeTree);\n curViewCache = this.applyServerOverwrite_(\n curViewCache,\n new Path(childKey),\n newChild,\n writesCache,\n serverCache,\n filterServerNode,\n accumulator\n );\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_(\n viewCache: ViewCache,\n ackPath: Path,\n affectedTree: ImmutableTree,\n writesCache: WriteTreeRef,\n completeCache: Node | null,\n accumulator: ChildChangeAccumulator\n ): 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 (\n (ackPath.isEmpty() && serverCache.isFullyInitialized()) ||\n serverCache.isCompleteForPath(ackPath)\n ) {\n return this.applyServerOverwrite_(\n viewCache,\n ackPath,\n serverCache.getNode().getChild(ackPath),\n writesCache,\n completeCache,\n filterServerNode,\n accumulator\n );\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_(\n viewCache,\n ackPath,\n changedChildren,\n writesCache,\n completeCache,\n filterServerNode,\n accumulator\n );\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(\n mergePath,\n serverCache.getNode().getChild(serverCachePath)\n );\n }\n });\n return this.applyServerMerge_(\n viewCache,\n ackPath,\n changedChildren,\n writesCache,\n completeCache,\n filterServerNode,\n accumulator\n );\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_(\n viewCache: ViewCache,\n path: Path,\n writesCache: WriteTreeRef,\n accumulator: ChildChangeAccumulator\n ): ViewCache {\n const oldServerNode = viewCache.getServerCache();\n const newViewCache = viewCache.updateServerSnap(\n oldServerNode.getNode(),\n oldServerNode.isFullyInitialized() || path.isEmpty(),\n oldServerNode.isFiltered()\n );\n return this.generateEventCacheAfterServerEvent_(\n newViewCache,\n path,\n writesCache,\n NO_COMPLETE_CHILD_SOURCE,\n accumulator\n );\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_(\n viewCache: ViewCache,\n path: Path,\n writesCache: WriteTreeRef,\n completeServerCache: Node | null,\n accumulator: ChildChangeAccumulator\n ): ViewCache {\n let complete;\n if (writesCache.shadowingWrite(path) != null) {\n return viewCache;\n } else {\n const source = new WriteTreeCompleteChildSource(\n writesCache,\n viewCache,\n completeServerCache\n );\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(\n viewCache.getCompleteServerSnap()\n );\n } else {\n const serverChildren = viewCache.getServerCache().getNode();\n assert(\n serverChildren instanceof ChildrenNode,\n 'serverChildren would be complete if leaf node'\n );\n newNode = writesCache.calcCompleteEventChildren(\n serverChildren as ChildrenNode\n );\n }\n newNode = newNode as Node;\n newEventCache = this.filter_.updateFullNode(\n oldEventCache,\n newNode,\n accumulator\n );\n } else {\n const childKey = path.getFront();\n let newChild = writesCache.calcCompleteChild(\n childKey,\n viewCache.getServerCache()\n );\n if (\n newChild == null &&\n viewCache.getServerCache().isCompleteForChild(childKey)\n ) {\n newChild = oldEventCache.getImmediateChild(childKey);\n }\n if (newChild != null) {\n newEventCache = this.filter_.updateChild(\n oldEventCache,\n childKey,\n newChild,\n path.popFront(),\n source,\n accumulator\n );\n } else if (viewCache.getEventCache().getNode().hasChild(childKey)) {\n // No complete child available, delete the existing one, if any\n newEventCache = this.filter_.updateChild(\n oldEventCache,\n childKey,\n ChildrenNode.EMPTY_NODE,\n path.popFront(),\n source,\n accumulator\n );\n } else {\n newEventCache = oldEventCache;\n }\n if (\n newEventCache.isEmpty() &&\n viewCache.getServerCache().isFullyInitialized()\n ) {\n // We might have reverted all child writes. Maybe the old event was a leaf node\n complete = writesCache.calcCompleteEventCache(\n viewCache.getCompleteServerSnap()\n );\n if (complete.isLeafNode()) {\n newEventCache = this.filter_.updateFullNode(\n newEventCache,\n complete,\n accumulator\n );\n }\n }\n }\n complete =\n viewCache.getServerCache().isFullyInitialized() ||\n writesCache.shadowingWrite(Path.Empty) != null;\n return viewCache.updateEventSnap(\n newEventCache,\n complete,\n 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(\n changes: Change[],\n eventCache: Node,\n eventRegistrations: EventRegistration[]\n ): Event[] {\n const events: Event[] = [];\n const moves: Change[] = [];\n\n changes.forEach(change => {\n if (\n change.type === Change.CHILD_CHANGED &&\n this.index_.indexedValueChanged(\n change.oldSnap as Node,\n change.snapshotNode\n )\n ) {\n moves.push(\n Change.childMovedChange(\n change.childName as string,\n change.snapshotNode\n )\n );\n }\n });\n\n this.generateEventsForType_(\n events,\n Change.CHILD_REMOVED,\n changes,\n eventRegistrations,\n eventCache\n );\n this.generateEventsForType_(\n events,\n Change.CHILD_ADDED,\n changes,\n eventRegistrations,\n eventCache\n );\n this.generateEventsForType_(\n events,\n Change.CHILD_MOVED,\n moves,\n eventRegistrations,\n eventCache\n );\n this.generateEventsForType_(\n events,\n Change.CHILD_CHANGED,\n changes,\n eventRegistrations,\n eventCache\n );\n this.generateEventsForType_(\n events,\n Change.VALUE,\n changes,\n eventRegistrations,\n eventCache\n );\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_(\n events: Event[],\n eventType: string,\n changes: Change[],\n registrations: EventRegistration[],\n eventCache: Node\n ) {\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_(\n change,\n eventCache\n );\n registrations.forEach(registration => {\n if (registration.respondsTo(change.type)) {\n events.push(\n registration.createEvent(materializedChange, this.query_)\n );\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(\n /** @type {!string} */\n change.childName,\n change.snapshotNode,\n this.index_\n );\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(\n ChildrenNode.EMPTY_NODE,\n initialServerCache.getNode(),\n null\n );\n const eventSnap = filter.updateFullNode(\n ChildrenNode.EMPTY_NODE,\n initialEventCache.getNode(),\n null\n );\n const newServerCache = new CacheNode(\n serverSnap,\n initialServerCache.isFullyInitialized(),\n indexFilter.filtersNodes()\n );\n const newEventCache = new CacheNode(\n eventSnap,\n initialEventCache.isFullyInitialized(),\n filter.filtersNodes()\n );\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 (\n this.query_.getQueryParams().loadsAllData() ||\n (!path.isEmpty() && !cache.getImmediateChild(path.getFront()).isEmpty())\n ) {\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(\n eventRegistration: EventRegistration | null,\n cancelError?: Error\n ): Event[] {\n const cancelEvents: CancelEvent[] = [];\n if (cancelError) {\n assert(\n eventRegistration == null,\n 'A cancel should cancel all event registrations.'\n );\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(\n operation: Operation,\n writesCache: WriteTreeRef,\n completeServerCache: Node | null\n ): Event[] {\n if (\n operation.type === OperationType.MERGE &&\n operation.source.queryId !== null\n ) {\n assert(\n this.viewCache_.getCompleteServerSnap(),\n 'We should always have a full cache before handling merges'\n );\n assert(\n this.viewCache_.getCompleteEventSnap(),\n 'Missing event cache, even though we have a server cache'\n );\n }\n\n const oldViewCache = this.viewCache_;\n const result = this.processor_.applyOperation(\n oldViewCache,\n operation,\n writesCache,\n completeServerCache\n );\n this.processor_.assertIndexed(result.viewCache);\n\n assert(\n result.viewCache.getServerCache().isFullyInitialized() ||\n !oldViewCache.getServerCache().isFullyInitialized(),\n 'Once a server snap is complete, it should never go back'\n );\n\n this.viewCache_ = result.viewCache;\n\n return this.generateEventsForChanges_(\n result.changes,\n result.viewCache.getEventCache().getNode(),\n null\n );\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_(\n initialChanges,\n eventSnap.getNode(),\n registration\n );\n }\n\n /**\n * @private\n * @param {!Array.} changes\n * @param {!Node} eventCache\n * @param {EventRegistration=} eventRegistration\n * @return {!Array.}\n */\n generateEventsForChanges_(\n changes: Change[],\n eventCache: Node,\n eventRegistration?: EventRegistration\n ): Event[] {\n const registrations = eventRegistration\n ? [eventRegistration]\n : this.eventRegistrations_;\n return this.eventGenerator_.generateEventsForChanges(\n changes,\n eventCache,\n 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 { 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(\n !__referenceConstructor,\n '__referenceConstructor has already been defined'\n );\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(\n operation: Operation,\n writesCache: WriteTreeRef,\n optCompleteServerCache: Node | null\n ): 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(\n operation,\n writesCache,\n optCompleteServerCache\n );\n } else {\n let events: Event[] = [];\n\n forEach(this.views_, function(key: string, view: View) {\n events = events.concat(\n view.applyOperation(operation, writesCache, optCompleteServerCache)\n );\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(\n query: Query,\n eventRegistration: EventRegistration,\n writesCache: WriteTreeRef,\n serverCache: Node | null,\n serverCacheComplete: boolean\n ): 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(\n serverCacheComplete ? serverCache : null\n );\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} */(\n eventCache,\n eventCacheComplete,\n false\n ),\n new CacheNode /** @type {!Node} */(\n serverCache,\n serverCacheComplete,\n false\n )\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(\n query: Query,\n eventRegistration: EventRegistration | null,\n cancelError?: Error\n ): { 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(\n view.removeEventRegistration(eventRegistration, cancelError)\n );\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(\n view.removeEventRegistration(eventRegistration, cancelError)\n );\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(\n new SyncPoint.__referenceConstructor(query.repo, query.path)\n );\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_).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) =>\n view.getQuery().getQueryParams().loadsAllData()\n );\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 { 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_: {\n [eventType: string]: Array<{\n callback(...args: any[]): void;\n context: any;\n }>;\n } = {};\n\n /**\n * @param {!Array.} allowedEvents_\n */\n constructor(private allowedEvents_: Array) {\n assert(\n Array.isArray(allowedEvents_) && allowedEvents_.length > 0,\n 'Requires a non-empty array'\n );\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 = [...this.listeners_[eventType]];\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 (\n listeners[i].callback === callback &&\n (!context || context === listeners[i].context)\n ) {\n listeners.splice(i, 1);\n return;\n }\n }\n }\n\n private validateEventType_(eventType: string) {\n assert(\n this.allowedEvents_.find(function(et) {\n return et === eventType;\n }),\n 'Unknown event: ' + eventType\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 (\n typeof document !== 'undefined' &&\n typeof document.addEventListener !== 'undefined'\n ) {\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(\n visibilityChange,\n () => {\n const visible = !document[hidden];\n if (visible !== this.visible_) {\n this.visible_ = visible;\n this.trigger('visible', visible);\n }\n },\n false\n );\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\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 (\n typeof window !== 'undefined' &&\n typeof window.addEventListener !== 'undefined' &&\n !isMobileCordova()\n ) {\n window.addEventListener(\n 'online',\n () => {\n if (!this.online_) {\n this.online_ = true;\n this.trigger('online', true);\n }\n },\n false\n );\n\n window.addEventListener(\n 'offline',\n () => {\n if (this.online_) {\n this.online_ = false;\n this.trigger('online', false);\n }\n },\n false\n );\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,\n 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 (\n now && validSince && validUntil && now >= validSince && now <= validUntil\n );\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 (\n !!decoded.signature &&\n !!claims &&\n typeof claims === 'object' &&\n claims.hasOwnProperty('iat')\n );\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 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_: {\n sendRequest(a: Object): void;\n close(): void;\n } | 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 * @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(\n private repoInfo_: RepoInfo,\n private onDataUpdate_: (\n a: string,\n b: any,\n c: boolean,\n d: number | null\n ) => void,\n private onConnectStatus_: (a: boolean) => void,\n private onServerInfoUpdate_: (a: any) => void,\n private authTokenProvider_: AuthTokenProvider,\n private authOverride_?: Object | null\n ) {\n super();\n\n if (authOverride_ && !isNodeSdk()) {\n throw new Error(\n 'Auth override specified in options, but not supported on non Node.js platforms'\n );\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(\n action: string,\n body: any,\n onResponse?: (a: any) => void\n ) {\n const curReqNum = ++this.requestNumber_;\n\n const msg = { r: curReqNum, a: action, b: body };\n this.log_(stringify(msg));\n assert(\n this.connected_,\n \"sendRequest call when we're not connected not allowed.\"\n );\n this.realtime_.sendRequest(msg);\n if (onResponse) {\n this.requestCBHash_[curReqNum] = onResponse;\n }\n }\n\n /**\n * @inheritDoc\n */\n listen(\n query: Query,\n currentHashFn: () => string,\n tag: number | null,\n onComplete: (a: string, b: any) => void\n ) {\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(\n query.getQueryParams().isDefault() ||\n !query.getQueryParams().loadsAllData(),\n 'listen() called for non-default but complete query'\n );\n assert(\n !this.listens_[pathString][queryId],\n 'listen() called twice for same path/queryId.'\n );\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 =\n 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 =\n '\".indexOn\": \"' + query.getQueryParams().getIndex().toString() + '\"';\n const indexPath = query.path.toString();\n warn(\n `Using an unspecified index. Your data will be downloaded and ` +\n `filtered on the client. Consider adding ${indexSpec} at ` +\n `${indexPath} to your security rules for better performance.`\n );\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_(\n 'Admin auth credential detected. Reducing max reconnect time.'\n );\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(\n query.getQueryParams().isDefault() ||\n !query.getQueryParams().loadsAllData(),\n 'unlisten() called for non-default but complete query'\n );\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_(\n pathString: string,\n queryId: string,\n queryObj: Object,\n tag: number | null\n ) {\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(\n pathString: string,\n data: any,\n onComplete?: (a: string, b: string) => void\n ) {\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(\n pathString: string,\n data: any,\n onComplete?: (a: string, b: string) => void\n ) {\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(\n pathString: string,\n onComplete?: (a: string, b: string) => void\n ) {\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_(\n action: string,\n pathString: string,\n data: any,\n onComplete: (a: string, b: string) => void\n ) {\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(\n pathString: string,\n data: any,\n onComplete?: (a: string, b: string) => void,\n hash?: string\n ) {\n this.putInternal('p', pathString, data, onComplete, hash);\n }\n\n /**\n * @inheritDoc\n */\n merge(\n pathString: string,\n data: any,\n onComplete: (a: string, b: string | null) => void,\n hash?: string\n ) {\n this.putInternal('m', pathString, data, onComplete, hash);\n }\n\n putInternal(\n action: string,\n pathString: string,\n data: any,\n onComplete: (a: string, b: string | null) => void,\n hash?: string\n ) {\n const request: { [k: string]: any } = {\n /*path*/ p: pathString,\n /*data*/ d: data\n };\n\n if (hash !== undefined) 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_(\n body[/*path*/ 'p'],\n body[/*data*/ 'd'],\n /*isMerge*/ false,\n body['t']\n );\n else if (action === 'm')\n this.onDataUpdate_(\n body[/*path*/ 'p'],\n body[/*data*/ 'd'],\n /*isMerge=*/ true,\n body['t']\n );\n else if (action === 'c')\n this.onListenRevoked_(body[/*path*/ 'p'], body[/*query*/ 'q']);\n else if (action === 'ac')\n this.onAuthRevoked_(\n body[/*status code*/ 's'],\n body[/* explanation */ 'd']\n );\n else if (action === 'sd') this.onSecurityDebugPacket_(body);\n else\n error(\n 'Unrecognized action received from server: ' +\n stringify(action) +\n '\\nAre you using the latest client?'\n );\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(\n !this.realtime_,\n \"Scheduling a connect when we're already connected/ing?\"\n );\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 (\n visible &&\n !this.visible_ &&\n this.reconnectDelay_ === this.maxReconnectDelay_\n ) {\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 =\n 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 =\n new Date().getTime() - this.lastConnectionAttemptTime_;\n let reconnectDelay = Math.max(\n 0,\n this.reconnectDelay_ - timeSinceLastConnectAttempt\n );\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(\n this.maxReconnectDelay_,\n this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER\n );\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(\n connection,\n \"sendRequest call when we're not connected not allowed.\"\n );\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_\n .getToken(forceRefresh)\n .then(function(result) {\n if (!canceled) {\n log('getToken() completed. Creating connection.');\n self.authToken_ = result && result.accessToken;\n connection = new Connection(\n connId,\n self.repoInfo_,\n onDataMessage,\n onReady,\n onDisconnect,\n /* onKill= */ function(reason) {\n warn(reason + ' (' + self.repoInfo_.toString() + ')');\n self.interrupt(SERVER_KILL_INTERRUPT_REASON);\n },\n lastSessionId\n );\n } else {\n log('getToken() completed but was canceled');\n }\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) 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) 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) 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]) this.sendPut_(i);\n }\n\n while (this.onDisconnectRequestQueue_.length) {\n const request = this.onDisconnectRequestQueue_.shift();\n this.sendOnDisconnect_(\n request.action,\n request.pathString,\n request.data,\n request.onComplete\n );\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[\n 'sdk.' + clientName + '.' + firebase.SDK_VERSION.replace(/\\./g, '-')\n ] = 1;\n\n if (isMobileCordova()) {\n stats['framework.cordova'] = 1;\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// 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 { 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 [BrowserPollConnection, WebSocketConnection];\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 =\n WebSocketConnection && WebSocketConnection['isAvailable']();\n let isSkipPollConnection =\n isWebSocketsAvailable && !WebSocketConnection.previouslyFailed();\n\n if (repoInfo.webSocketOnly) {\n if (!isWebSocketsAvailable)\n warn(\n \"wss:// URL used, but browser isn't known to support websockets. Trying anyway.\"\n );\n\n isSkipPollConnection = true;\n }\n\n if (isSkipPollConnection) {\n this.transports_ = [WebSocketConnection];\n } else {\n const transports = (this.transports_ = [] as TransportConstructor[]);\n each(\n TransportManager.ALL_TRANSPORTS,\n (i: number, transport: TransportConstructor) => {\n if (transport && transport['isAvailable']()) {\n transports.push(transport);\n }\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 * 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(\n 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 ) {\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(\n this.nextTransportId_(),\n this.repoInfo_,\n undefined,\n this.lastSessionId\n );\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 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 (\n this.conn_ &&\n this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE\n ) {\n this.log_(\n 'Connection exceeded healthy timeout but has received ' +\n this.conn_.bytesReceived +\n ' bytes. Marking connection healthy.'\n );\n this.isHealthy_ = true;\n this.conn_.markConnectionHealthy();\n } else if (\n this.conn_ &&\n this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE\n ) {\n this.log_(\n 'Connection exceeded healthy timeout but has sent ' +\n this.conn_.bytesSent +\n ' bytes. Leaving connection alive.'\n );\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_(\n 'cleaning up and promoting a connection: ' + this.secondaryConn_.connId\n );\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 (\n this.tx_ === this.secondaryConn_ ||\n this.rx_ === this.secondaryConn_\n ) {\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: {\n ts: number;\n v: string;\n h: string;\n s: string;\n }) {\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(\n this.nextTransportId_(),\n this.repoInfo_,\n this.sessionId\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.secondaryResponsesRequired_ =\n 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 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// 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 { 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 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// 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(\n public connId: string,\n public repoInfo: RepoInfo,\n public transportSessionId?: string,\n public lastSessionId?: string\n ) {\n this.log_ = logWrapper(connId);\n this.stats_ = StatsManager.getCollection(repoInfo);\n this.urlFn = (params: { [k: string]: string }) =>\n 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_) return;\n\n //Set up a callback that gets triggered once a connection is set up.\n this.scriptTagHolder = new FirebaseIFrameScriptHolder(\n (...args) => {\n const [command, arg1, arg2, arg3, arg4] = args;\n this.incrementIncomingBytes_(args);\n if (!this.scriptTagHolder) 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, () => {\n this.onClosed_();\n });\n } else {\n this.onClosed_();\n }\n } else {\n throw new Error('Unrecognized command received: ' + command);\n }\n },\n (...args) => {\n const [pN, data] = args;\n this.incrementIncomingBytes_(args);\n this.myPacketOrderer.handleResponse(pN, data);\n },\n () => {\n this.onClosed_();\n },\n this.urlFn\n );\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(\n Math.random() * 100000000\n );\n if (this.scriptTagHolder.uniqueCallbackIdentifier)\n urlParams[\n FIREBASE_LONGPOLL_CALLBACK_ID_PARAM\n ] = 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 (\n !isNodeSdk() &&\n typeof location !== 'undefined' &&\n location.href &&\n location.href.indexOf(FORGE_DOMAIN) !== -1\n ) {\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, () => {\n /* do nothing */\n });\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 (\n BrowserPollConnection.forceAllow_ ||\n (!BrowserPollConnection.forceDisallow_ &&\n typeof document !== 'undefined' &&\n 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(\n this.curSegmentNum,\n dataSegs.length,\n dataSegs[i]\n );\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(\n commandCB: (command: string, ...args: any[]) => void,\n onMessageCB: (...args: any[]) => void,\n public onDisconnect: () => void,\n public urlFn: (a: object) => string\n ) {\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)[\n FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier\n ] = commandCB;\n (window as any)[\n FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier\n ] = 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 (\n this.myIFrame.src &&\n this.myIFrame.src.substr(0, 'javascript:'.length) === 'javascript:'\n ) {\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 =\n \"javascript:void((function(){document.open();document.domain='\" +\n 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 (\n this.alive &&\n this.sendNewPolls &&\n this.outstandingRequests.count() < (this.pendingSegs.length > 0 ? 2 : 1)\n ) {\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 (\n nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <=\n MAX_URL_DATA_SIZE\n ) {\n //great, the segment will fit. Lets append it.\n const theSeg = this.pendingSegs.shift();\n curDataString =\n curDataString +\n '&' +\n FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM +\n i +\n '=' +\n theSeg.seg +\n '&' +\n FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET +\n i +\n '=' +\n theSeg.ts +\n '&' +\n FIREBASE_LONGPOLL_DATA_PARAM +\n i +\n '=' +\n 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(\n doNewRequest,\n Math.floor(KEEPALIVE_REQUEST_INTERVAL)\n );\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 { 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(\n public connId: string,\n repoInfo: RepoInfo,\n transportSessionId?: string,\n lastSessionId?: string\n ) {\n this.log_ = logWrapper(this.connId);\n this.stats_ = StatsManager.getCollection(repoInfo);\n this.connURL = WebSocketConnection.connectionURL_(\n repoInfo,\n transportSessionId,\n lastSessionId\n );\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_(\n repoInfo: RepoInfo,\n transportSessionId?: string,\n lastSessionId?: string\n ): string {\n const urlParams: { [k: string]: string } = {};\n urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\n\n if (\n !isNodeSdk() &&\n typeof location !== 'undefined' &&\n location.href &&\n location.href.indexOf(FORGE_DOMAIN) !== -1\n ) {\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\n // Plumb appropriate http_proxy environment variable into faye-websocket if it exists.\n const env = process['env'];\n const proxy =\n 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 (\n !isOldAndroid &&\n WebSocketImpl !== null &&\n !WebSocketConnection.forceDisallow_\n );\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 (\n PersistentStorage.isInMemoryStorage ||\n PersistentStorage.get('previous_websocket_failure') === true\n );\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) 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 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_(\n 'Exception thrown from WebSocket.send():',\n e.message || e.data,\n 'Closing connection.'\n );\n setTimeout(this.onClosed_.bind(this), 0);\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 { 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 * @param {!Query} query\n * @param {function():string} currentHashFn\n * @param {?number} tag\n * @param {function(string, *)} onComplete\n */\n abstract listen(\n query: Query,\n currentHashFn: () => string,\n tag: number | null,\n onComplete: (a: string, b: any) => void\n ): 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(\n pathString: string,\n data: any,\n onComplete?: (a: string, b: string) => void,\n hash?: string\n ) {}\n\n /**\n * @param {string} pathString\n * @param {*} data\n * @param {function(string, ?string)} onComplete\n * @param {string=} hash\n */\n merge(\n pathString: string,\n data: any,\n onComplete: (a: string, b: string | null) => void,\n hash?: string\n ) {}\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(\n pathString: string,\n data: any,\n onComplete?: (a: string, b: string) => void\n ) {}\n\n /**\n * @param {string} pathString\n * @param {*} data\n * @param {function(string, string)=} onComplete\n */\n onDisconnectMerge(\n pathString: string,\n data: any,\n onComplete?: (a: string, b: string) => void\n ) {}\n\n /**\n * @param {string} pathString\n * @param {function(string, string)=} onComplete\n */\n onDisconnectCancel(\n pathString: string,\n onComplete?: (a: string, b: string) => void\n ) {}\n\n /**\n * @param {Object.} stats\n */\n reportStats(stats: { [k: string]: any }) {}\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 { 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, unused, url) => RepoManager.getInstance().databaseFromApp(app, url),\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 null,\n true\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 = 63\n// module chunks = 0","/**\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(\n ref: Reference,\n callback: (a: Object) => void\n) {\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(\n ref: Reference,\n callback: ((a: string, b: any) => void) | null\n) {\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(\n pathString: string,\n onComplete: (a: any) => void\n) {\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(\n data: any,\n onEcho: (a: any) => void\n) {\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(\n pathString,\n data,\n opt_onComplete,\n opt_hash\n ) {\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"],"sourceRoot":""}