{"version":3,"file":"firebase-database.js","sources":["../../node_modules/tslib/tslib.es6.js","../util/dist/index.esm.js","../logger/dist/index.esm.js","../database/dist/index.esm.js"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [0, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; }; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator];\r\n return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","import { __extends } from 'tslib';\n\n/**\r\n * @license\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 */\r\n/**\r\n * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.\r\n */\r\nvar CONSTANTS = {\r\n /**\r\n * @define {boolean} Whether this is the client Node.js SDK.\r\n */\r\n NODE_CLIENT: false,\r\n /**\r\n * @define {boolean} Whether this is the Admin Node.js SDK.\r\n */\r\n NODE_ADMIN: false,\r\n /**\r\n * Firebase SDK Version\r\n */\r\n SDK_VERSION: '${JSCORE_VERSION}'\r\n};\n\n/**\r\n * @license\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 */\r\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 */\r\nvar assert = function (assertion, message) {\r\n if (!assertion) {\r\n throw assertionError(message);\r\n }\r\n};\r\n/**\r\n * Returns an Error object suitable for throwing.\r\n * @param {string} message\r\n * @return {!Error}\r\n */\r\nvar assertionError = function (message) {\r\n return new Error('Firebase Database (' +\r\n CONSTANTS.SDK_VERSION +\r\n ') INTERNAL ASSERT FAILED: ' +\r\n message);\r\n};\n\n/**\r\n * @license\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 */\r\nvar stringToByteArray = function (str) {\r\n // TODO(user): Use native implementations if/when available\r\n var out = [], p = 0;\r\n for (var i = 0; i < str.length; i++) {\r\n var c = str.charCodeAt(i);\r\n if (c < 128) {\r\n out[p++] = c;\r\n }\r\n else if (c < 2048) {\r\n out[p++] = (c >> 6) | 192;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else if ((c & 0xfc00) == 0xd800 &&\r\n i + 1 < str.length &&\r\n (str.charCodeAt(i + 1) & 0xfc00) == 0xdc00) {\r\n // Surrogate Pair\r\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\r\n out[p++] = (c >> 18) | 240;\r\n out[p++] = ((c >> 12) & 63) | 128;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else {\r\n out[p++] = (c >> 12) | 224;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n }\r\n return out;\r\n};\r\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 */\r\nvar byteArrayToString = function (bytes) {\r\n // TODO(user): Use native implementations if/when available\r\n var out = [], pos = 0, c = 0;\r\n while (pos < bytes.length) {\r\n var c1 = bytes[pos++];\r\n if (c1 < 128) {\r\n out[c++] = String.fromCharCode(c1);\r\n }\r\n else if (c1 > 191 && c1 < 224) {\r\n var c2 = bytes[pos++];\r\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\r\n }\r\n else if (c1 > 239 && c1 < 365) {\r\n // Surrogate Pair\r\n var c2 = bytes[pos++];\r\n var c3 = bytes[pos++];\r\n var c4 = bytes[pos++];\r\n var u = (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\r\n 0x10000;\r\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\r\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\r\n }\r\n else {\r\n var c2 = bytes[pos++];\r\n var c3 = bytes[pos++];\r\n out[c++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\r\n }\r\n }\r\n return out.join('');\r\n};\r\n// Static lookup maps, lazily populated by init_()\r\nvar base64 = {\r\n /**\r\n * Maps bytes to characters.\r\n * @type {Object}\r\n * @private\r\n */\r\n byteToCharMap_: null,\r\n /**\r\n * Maps characters to bytes.\r\n * @type {Object}\r\n * @private\r\n */\r\n charToByteMap_: null,\r\n /**\r\n * Maps bytes to websafe characters.\r\n * @type {Object}\r\n * @private\r\n */\r\n byteToCharMapWebSafe_: null,\r\n /**\r\n * Maps websafe characters to bytes.\r\n * @type {Object}\r\n * @private\r\n */\r\n charToByteMapWebSafe_: null,\r\n /**\r\n * Our default alphabet, shared between\r\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\r\n * @type {string}\r\n */\r\n ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\r\n /**\r\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\r\n * @type {string}\r\n */\r\n get ENCODED_VALS() {\r\n return this.ENCODED_VALS_BASE + '+/=';\r\n },\r\n /**\r\n * Our websafe alphabet.\r\n * @type {string}\r\n */\r\n get ENCODED_VALS_WEBSAFE() {\r\n return this.ENCODED_VALS_BASE + '-_.';\r\n },\r\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 */\r\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\r\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 */\r\n encodeByteArray: function (input, opt_webSafe) {\r\n if (!Array.isArray(input)) {\r\n throw Error('encodeByteArray takes an array as a parameter');\r\n }\r\n this.init_();\r\n var byteToCharMap = opt_webSafe\r\n ? this.byteToCharMapWebSafe_\r\n : this.byteToCharMap_;\r\n var output = [];\r\n for (var i = 0; i < input.length; i += 3) {\r\n var byte1 = input[i];\r\n var haveByte2 = i + 1 < input.length;\r\n var byte2 = haveByte2 ? input[i + 1] : 0;\r\n var haveByte3 = i + 2 < input.length;\r\n var byte3 = haveByte3 ? input[i + 2] : 0;\r\n var outByte1 = byte1 >> 2;\r\n var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\r\n var outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\r\n var outByte4 = byte3 & 0x3f;\r\n if (!haveByte3) {\r\n outByte4 = 64;\r\n if (!haveByte2) {\r\n outByte3 = 64;\r\n }\r\n }\r\n output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);\r\n }\r\n return output.join('');\r\n },\r\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 */\r\n encodeString: function (input, opt_webSafe) {\r\n // Shortcut for Mozilla browsers that implement\r\n // a native base64 encoder in the form of \"btoa/atob\"\r\n if (this.HAS_NATIVE_SUPPORT && !opt_webSafe) {\r\n return btoa(input);\r\n }\r\n return this.encodeByteArray(stringToByteArray(input), opt_webSafe);\r\n },\r\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 */\r\n decodeString: function (input, opt_webSafe) {\r\n // Shortcut for Mozilla browsers that implement\r\n // a native base64 encoder in the form of \"btoa/atob\"\r\n if (this.HAS_NATIVE_SUPPORT && !opt_webSafe) {\r\n return atob(input);\r\n }\r\n return byteArrayToString(this.decodeStringToByteArray(input, opt_webSafe));\r\n },\r\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 */\r\n decodeStringToByteArray: function (input, opt_webSafe) {\r\n this.init_();\r\n var charToByteMap = opt_webSafe\r\n ? this.charToByteMapWebSafe_\r\n : this.charToByteMap_;\r\n var output = [];\r\n for (var i = 0; i < input.length;) {\r\n var byte1 = charToByteMap[input.charAt(i++)];\r\n var haveByte2 = i < input.length;\r\n var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\r\n ++i;\r\n var haveByte3 = i < input.length;\r\n var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\r\n ++i;\r\n var haveByte4 = i < input.length;\r\n var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\r\n ++i;\r\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\r\n throw Error();\r\n }\r\n var outByte1 = (byte1 << 2) | (byte2 >> 4);\r\n output.push(outByte1);\r\n if (byte3 != 64) {\r\n var outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\r\n output.push(outByte2);\r\n if (byte4 != 64) {\r\n var outByte3 = ((byte3 << 6) & 0xc0) | byte4;\r\n output.push(outByte3);\r\n }\r\n }\r\n }\r\n return output;\r\n },\r\n /**\r\n * Lazy static initialization function. Called before\r\n * accessing any of the static map variables.\r\n * @private\r\n */\r\n init_: function () {\r\n if (!this.byteToCharMap_) {\r\n this.byteToCharMap_ = {};\r\n this.charToByteMap_ = {};\r\n this.byteToCharMapWebSafe_ = {};\r\n this.charToByteMapWebSafe_ = {};\r\n // We want quick mappings back and forth, so we precompute two maps.\r\n for (var i = 0; i < this.ENCODED_VALS.length; i++) {\r\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\r\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\r\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\r\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\r\n // Be forgiving when decoding and correctly decode both encodings.\r\n if (i >= this.ENCODED_VALS_BASE.length) {\r\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\r\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\r\n }\r\n }\r\n }\r\n }\r\n};\r\n/**\r\n * URL-safe base64 encoding\r\n * @param {!string} str\r\n * @return {!string}\r\n */\r\nvar base64Encode = function (str) {\r\n var utf8Bytes = stringToByteArray(str);\r\n return base64.encodeByteArray(utf8Bytes, true);\r\n};\r\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 */\r\nvar base64Decode = function (str) {\r\n try {\r\n return base64.decodeString(str, true);\r\n }\r\n catch (e) {\r\n console.error('base64Decode failed: ', e);\r\n }\r\n return null;\r\n};\n\n/**\r\n * @license\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 */\r\n/**\r\n * Do a deep-copy of basic JavaScript Objects or Arrays.\r\n */\r\nfunction deepCopy(value) {\r\n return deepExtend(undefined, value);\r\n}\r\n/**\r\n * Copy properties from source to target (recursively allows extension\r\n * of Objects and Arrays). Scalar values in the target are over-written.\r\n * If target is undefined, an object of the appropriate type will be created\r\n * (and returned).\r\n *\r\n * We recursively copy all child properties of plain Objects in the source- so\r\n * that namespace- like dictionaries are merged.\r\n *\r\n * Note that the target can be a function, in which case the properties in\r\n * the source Object are copied onto it as static properties of the Function.\r\n */\r\nfunction deepExtend(target, source) {\r\n if (!(source instanceof Object)) {\r\n return source;\r\n }\r\n switch (source.constructor) {\r\n case Date:\r\n // Treat Dates like scalars; if the target date object had any child\r\n // properties - they will be lost!\r\n var dateValue = source;\r\n return new Date(dateValue.getTime());\r\n case Object:\r\n if (target === undefined) {\r\n target = {};\r\n }\r\n break;\r\n case Array:\r\n // Always copy the array source and overwrite the target.\r\n target = [];\r\n break;\r\n default:\r\n // Not a plain Object - treat it as a scalar.\r\n return source;\r\n }\r\n for (var prop in source) {\r\n if (!source.hasOwnProperty(prop)) {\r\n continue;\r\n }\r\n target[prop] = deepExtend(target[prop], source[prop]);\r\n }\r\n return target;\r\n}\r\n// TODO: Really needed (for JSCompiler type checking)?\r\nfunction patchProperty(obj, prop, value) {\r\n obj[prop] = value;\r\n}\n\n/**\r\n * @license\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 */\r\nvar Deferred = /** @class */ (function () {\r\n function Deferred() {\r\n var _this = this;\r\n this.promise = new Promise(function (resolve, reject) {\r\n _this.resolve = resolve;\r\n _this.reject = reject;\r\n });\r\n }\r\n /**\r\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\r\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\r\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\r\n * @param {((?function(?(Error)): (?|undefined))| (?function(?(Error),?=): (?|undefined)))=} callback\r\n * @return {!function(?(Error), ?=)}\r\n */\r\n Deferred.prototype.wrapCallback = function (callback) {\r\n var _this = this;\r\n return function (error, value) {\r\n if (error) {\r\n _this.reject(error);\r\n }\r\n else {\r\n _this.resolve(value);\r\n }\r\n if (typeof callback === 'function') {\r\n // Attaching noop handler just in case developer wasn't expecting\r\n // promises\r\n _this.promise.catch(function () { });\r\n // Some of our callbacks don't expect a value and our own tests\r\n // assert that the parameter length is 1\r\n if (callback.length === 1) {\r\n callback(error);\r\n }\r\n else {\r\n callback(error, value);\r\n }\r\n }\r\n };\r\n };\r\n return Deferred;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Returns navigator.userAgent string or '' if it's not defined.\r\n * @return {string} user agent string\r\n */\r\nvar getUA = function () {\r\n if (typeof navigator !== 'undefined' &&\r\n typeof navigator['userAgent'] === 'string') {\r\n return navigator['userAgent'];\r\n }\r\n else {\r\n return '';\r\n }\r\n};\r\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 */\r\nvar isMobileCordova = function () {\r\n return (typeof window !== 'undefined' &&\r\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\r\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()));\r\n};\r\n/**\r\n * Detect React Native.\r\n *\r\n * @return {boolean} True if ReactNative environment is detected.\r\n */\r\nvar isReactNative = function () {\r\n return (typeof navigator === 'object' && navigator['product'] === 'ReactNative');\r\n};\r\n/**\r\n * Detect Node.js.\r\n *\r\n * @return {boolean} True if Node.js environment is detected.\r\n */\r\nvar isNodeSdk = function () {\r\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\r\n};\n\nvar ERROR_NAME = 'FirebaseError';\r\nvar captureStackTrace = Error\r\n .captureStackTrace;\r\n// Export for faking in tests\r\nfunction patchCapture(captureFake) {\r\n var result = captureStackTrace;\r\n captureStackTrace = captureFake;\r\n return result;\r\n}\r\nvar FirebaseError = /** @class */ (function () {\r\n function FirebaseError(code, message) {\r\n this.code = code;\r\n this.message = message;\r\n // We want the stack value, if implemented by Error\r\n if (captureStackTrace) {\r\n // Patches this.stack, omitted calls above ErrorFactory#create\r\n captureStackTrace(this, ErrorFactory.prototype.create);\r\n }\r\n else {\r\n try {\r\n // In case of IE11, stack will be set only after error is raised.\r\n // https://docs.microsoft.com/en-us/scripting/javascript/reference/stack-property-error-javascript\r\n throw Error.apply(this, arguments);\r\n }\r\n catch (err) {\r\n this.name = ERROR_NAME;\r\n // Make non-enumerable getter for the property.\r\n Object.defineProperty(this, 'stack', {\r\n get: function () {\r\n return err.stack;\r\n }\r\n });\r\n }\r\n }\r\n }\r\n return FirebaseError;\r\n}());\r\n// Back-door inheritance\r\nFirebaseError.prototype = Object.create(Error.prototype);\r\nFirebaseError.prototype.constructor = FirebaseError;\r\nFirebaseError.prototype.name = ERROR_NAME;\r\nvar ErrorFactory = /** @class */ (function () {\r\n function ErrorFactory(service, serviceName, errors) {\r\n this.service = service;\r\n this.serviceName = serviceName;\r\n this.errors = errors;\r\n // Matches {$name}, by default.\r\n this.pattern = /\\{\\$([^}]+)}/g;\r\n // empty\r\n }\r\n ErrorFactory.prototype.create = function (code, data) {\r\n if (data === undefined) {\r\n data = {};\r\n }\r\n var template = this.errors[code];\r\n var fullCode = this.service + '/' + code;\r\n var message;\r\n if (template === undefined) {\r\n message = 'Error';\r\n }\r\n else {\r\n message = template.replace(this.pattern, function (match, key) {\r\n var value = data[key];\r\n return value !== undefined ? value.toString() : '<' + key + '?>';\r\n });\r\n }\r\n // Service: Error message (service/code).\r\n message = this.serviceName + ': ' + message + ' (' + fullCode + ').';\r\n var err = new FirebaseError(fullCode, message);\r\n // Populate the Error object with message parts for programmatic\r\n // accesses (e.g., e.file).\r\n for (var prop in data) {\r\n if (!data.hasOwnProperty(prop) || prop.slice(-1) === '_') {\r\n continue;\r\n }\r\n err[prop] = data[prop];\r\n }\r\n return err;\r\n };\r\n return ErrorFactory;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nfunction jsonEval(str) {\r\n return JSON.parse(str);\r\n}\r\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 */\r\nfunction stringify(data) {\r\n return JSON.stringify(data);\r\n}\n\n/**\r\n * @license\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 */\r\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 */\r\nvar decode = function (token) {\r\n var header = {}, claims = {}, data = {}, signature = '';\r\n try {\r\n var parts = token.split('.');\r\n header = jsonEval(base64Decode(parts[0]) || '');\r\n claims = jsonEval(base64Decode(parts[1]) || '');\r\n signature = parts[2];\r\n data = claims['d'] || {};\r\n delete claims['d'];\r\n }\r\n catch (e) { }\r\n return {\r\n header: header,\r\n claims: claims,\r\n data: data,\r\n signature: signature\r\n };\r\n};\r\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 */\r\nvar isValidTimestamp = function (token) {\r\n var claims = decode(token).claims, now = Math.floor(new Date().getTime() / 1000), validSince, validUntil;\r\n if (typeof claims === 'object') {\r\n if (claims.hasOwnProperty('nbf')) {\r\n validSince = claims['nbf'];\r\n }\r\n else if (claims.hasOwnProperty('iat')) {\r\n validSince = claims['iat'];\r\n }\r\n if (claims.hasOwnProperty('exp')) {\r\n validUntil = claims['exp'];\r\n }\r\n else {\r\n // token will expire after 24h by default\r\n validUntil = validSince + 86400;\r\n }\r\n }\r\n return (now && validSince && validUntil && now >= validSince && now <= validUntil);\r\n};\r\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 */\r\nvar issuedAtTime = function (token) {\r\n var claims = decode(token).claims;\r\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\r\n return claims['iat'];\r\n }\r\n return null;\r\n};\r\n/**\r\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.\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 */\r\nvar isValidFormat = function (token) {\r\n var decoded = decode(token), claims = decoded.claims;\r\n return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');\r\n};\r\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 */\r\nvar isAdmin = function (token) {\r\n var claims = decode(token).claims;\r\n return typeof claims === 'object' && claims['admin'] === true;\r\n};\n\n/**\r\n * @license\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 */\r\n// See http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/\r\nvar contains = function (obj, key) {\r\n return Object.prototype.hasOwnProperty.call(obj, key);\r\n};\r\nvar safeGet = function (obj, key) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key))\r\n return obj[key];\r\n // else return undefined.\r\n};\r\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 */\r\nvar forEach = function (obj, fn) {\r\n for (var key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n fn(key, obj[key]);\r\n }\r\n }\r\n};\r\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 */\r\nvar extend = function (objTo, objFrom) {\r\n forEach(objFrom, function (key, value) {\r\n objTo[key] = value;\r\n });\r\n return objTo;\r\n};\r\n/**\r\n * Returns a clone of the specified object.\r\n * @param {!Object} obj\r\n * @return {!Object} cloned obj.\r\n */\r\nvar clone = function (obj) {\r\n return extend({}, obj);\r\n};\r\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 */\r\nvar isNonNullObject = function (obj) {\r\n return typeof obj === 'object' && obj !== null;\r\n};\r\nvar isEmpty = function (obj) {\r\n for (var key in obj) {\r\n return false;\r\n }\r\n return true;\r\n};\r\nvar getCount = function (obj) {\r\n var rv = 0;\r\n for (var key in obj) {\r\n rv++;\r\n }\r\n return rv;\r\n};\r\nvar map = function (obj, f, opt_obj) {\r\n var res = {};\r\n for (var key in obj) {\r\n res[key] = f.call(opt_obj, obj[key], key, obj);\r\n }\r\n return res;\r\n};\r\nvar findKey = function (obj, fn, opt_this) {\r\n for (var key in obj) {\r\n if (fn.call(opt_this, obj[key], key, obj)) {\r\n return key;\r\n }\r\n }\r\n return undefined;\r\n};\r\nvar findValue = function (obj, fn, opt_this) {\r\n var key = findKey(obj, fn, opt_this);\r\n return key && obj[key];\r\n};\r\nvar getAnyKey = function (obj) {\r\n for (var key in obj) {\r\n return key;\r\n }\r\n};\r\nvar getValues = function (obj) {\r\n var res = [];\r\n var i = 0;\r\n for (var key in obj) {\r\n res[i++] = obj[key];\r\n }\r\n return res;\r\n};\r\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 */\r\nvar every = function (obj, fn) {\r\n for (var key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n if (!fn(key, obj[key])) {\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n};\n\n/**\r\n * @license\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 */\r\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 */\r\nvar querystring = function (querystringParams) {\r\n var params = [];\r\n forEach(querystringParams, function (key, value) {\r\n if (Array.isArray(value)) {\r\n value.forEach(function (arrayVal) {\r\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal));\r\n });\r\n }\r\n else {\r\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\r\n }\r\n });\r\n return params.length ? '&' + params.join('&') : '';\r\n};\r\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 */\r\nvar querystringDecode = function (querystring) {\r\n var obj = {};\r\n var tokens = querystring.replace(/^\\?/, '').split('&');\r\n tokens.forEach(function (token) {\r\n if (token) {\r\n var key = token.split('=');\r\n obj[key[0]] = key[1];\r\n }\r\n });\r\n return obj;\r\n};\n\n/**\r\n * @license\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 */\r\n// Copyright 2011 The Closure Library Authors. All Rights Reserved.\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/**\r\n * @fileoverview Abstract cryptographic hash interface.\r\n *\r\n * See Sha1 and Md5 for sample implementations.\r\n *\r\n */\r\n/**\r\n * Create a cryptographic hash instance.\r\n *\r\n * @constructor\r\n * @struct\r\n */\r\nvar Hash = /** @class */ (function () {\r\n function Hash() {\r\n /**\r\n * The block size for the hasher.\r\n * @type {number}\r\n */\r\n this.blockSize = -1;\r\n }\r\n return Hash;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\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 */\r\nvar Sha1 = /** @class */ (function (_super) {\r\n __extends(Sha1, _super);\r\n function Sha1() {\r\n var _this = _super.call(this) || this;\r\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 */\r\n _this.chain_ = [];\r\n /**\r\n * A buffer holding the partially computed hash result.\r\n * @type {!Array}\r\n * @private\r\n */\r\n _this.buf_ = [];\r\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 */\r\n _this.W_ = [];\r\n /**\r\n * Contains data needed to pad messages less than 64 bytes.\r\n * @type {!Array}\r\n * @private\r\n */\r\n _this.pad_ = [];\r\n /**\r\n * @private {number}\r\n */\r\n _this.inbuf_ = 0;\r\n /**\r\n * @private {number}\r\n */\r\n _this.total_ = 0;\r\n _this.blockSize = 512 / 8;\r\n _this.pad_[0] = 128;\r\n for (var i = 1; i < _this.blockSize; ++i) {\r\n _this.pad_[i] = 0;\r\n }\r\n _this.reset();\r\n return _this;\r\n }\r\n Sha1.prototype.reset = function () {\r\n this.chain_[0] = 0x67452301;\r\n this.chain_[1] = 0xefcdab89;\r\n this.chain_[2] = 0x98badcfe;\r\n this.chain_[3] = 0x10325476;\r\n this.chain_[4] = 0xc3d2e1f0;\r\n this.inbuf_ = 0;\r\n this.total_ = 0;\r\n };\r\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 */\r\n Sha1.prototype.compress_ = function (buf, opt_offset) {\r\n if (!opt_offset) {\r\n opt_offset = 0;\r\n }\r\n var W = this.W_;\r\n // get 16 big endian words\r\n if (typeof buf === 'string') {\r\n for (var i = 0; i < 16; i++) {\r\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\r\n // have a bug that turns the post-increment ++ operator into pre-increment\r\n // during JIT compilation. We have code that depends heavily on SHA-1 for\r\n // correctness and which is affected by this bug, so I've removed all uses\r\n // of post-increment ++ in which the result value is used. We can revert\r\n // this change once the Safari bug\r\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\r\n // most clients have been updated.\r\n W[i] =\r\n (buf.charCodeAt(opt_offset) << 24) |\r\n (buf.charCodeAt(opt_offset + 1) << 16) |\r\n (buf.charCodeAt(opt_offset + 2) << 8) |\r\n buf.charCodeAt(opt_offset + 3);\r\n opt_offset += 4;\r\n }\r\n }\r\n else {\r\n for (var i = 0; i < 16; i++) {\r\n W[i] =\r\n (buf[opt_offset] << 24) |\r\n (buf[opt_offset + 1] << 16) |\r\n (buf[opt_offset + 2] << 8) |\r\n buf[opt_offset + 3];\r\n opt_offset += 4;\r\n }\r\n }\r\n // expand to 80 words\r\n for (var i = 16; i < 80; i++) {\r\n var t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\r\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\r\n }\r\n var a = this.chain_[0];\r\n var b = this.chain_[1];\r\n var c = this.chain_[2];\r\n var d = this.chain_[3];\r\n var e = this.chain_[4];\r\n var f, k;\r\n // TODO(user): Try to unroll this loop to speed up the computation.\r\n for (var i = 0; i < 80; i++) {\r\n if (i < 40) {\r\n if (i < 20) {\r\n f = d ^ (b & (c ^ d));\r\n k = 0x5a827999;\r\n }\r\n else {\r\n f = b ^ c ^ d;\r\n k = 0x6ed9eba1;\r\n }\r\n }\r\n else {\r\n if (i < 60) {\r\n f = (b & c) | (d & (b | c));\r\n k = 0x8f1bbcdc;\r\n }\r\n else {\r\n f = b ^ c ^ d;\r\n k = 0xca62c1d6;\r\n }\r\n }\r\n var t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\r\n e = d;\r\n d = c;\r\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\r\n b = a;\r\n a = t;\r\n }\r\n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\r\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\r\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\r\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\r\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\r\n };\r\n Sha1.prototype.update = function (bytes, opt_length) {\r\n // TODO(johnlenz): tighten the function signature and remove this check\r\n if (bytes == null) {\r\n return;\r\n }\r\n if (opt_length === undefined) {\r\n opt_length = bytes.length;\r\n }\r\n var lengthMinusBlock = opt_length - this.blockSize;\r\n var n = 0;\r\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\r\n var buf = this.buf_;\r\n var inbuf = this.inbuf_;\r\n // The outer while loop should execute at most twice.\r\n while (n < opt_length) {\r\n // When we have no data in the block to top up, we can directly process the\r\n // input buffer (assuming it contains sufficient data). This gives ~25%\r\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\r\n // the data is provided in large chunks (or in multiples of 64 bytes).\r\n if (inbuf == 0) {\r\n while (n <= lengthMinusBlock) {\r\n this.compress_(bytes, n);\r\n n += this.blockSize;\r\n }\r\n }\r\n if (typeof bytes === 'string') {\r\n while (n < opt_length) {\r\n buf[inbuf] = bytes.charCodeAt(n);\r\n ++inbuf;\r\n ++n;\r\n if (inbuf == this.blockSize) {\r\n this.compress_(buf);\r\n inbuf = 0;\r\n // Jump to the outer loop so we use the full-block optimization.\r\n break;\r\n }\r\n }\r\n }\r\n else {\r\n while (n < opt_length) {\r\n buf[inbuf] = bytes[n];\r\n ++inbuf;\r\n ++n;\r\n if (inbuf == this.blockSize) {\r\n this.compress_(buf);\r\n inbuf = 0;\r\n // Jump to the outer loop so we use the full-block optimization.\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n this.inbuf_ = inbuf;\r\n this.total_ += opt_length;\r\n };\r\n /** @override */\r\n Sha1.prototype.digest = function () {\r\n var digest = [];\r\n var totalBits = this.total_ * 8;\r\n // Add pad 0x80 0x00*.\r\n if (this.inbuf_ < 56) {\r\n this.update(this.pad_, 56 - this.inbuf_);\r\n }\r\n else {\r\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\r\n }\r\n // Add # bits.\r\n for (var i = this.blockSize - 1; i >= 56; i--) {\r\n this.buf_[i] = totalBits & 255;\r\n totalBits /= 256; // Don't use bit-shifting here!\r\n }\r\n this.compress_(this.buf_);\r\n var n = 0;\r\n for (var i = 0; i < 5; i++) {\r\n for (var j = 24; j >= 0; j -= 8) {\r\n digest[n] = (this.chain_[i] >> j) & 255;\r\n ++n;\r\n }\r\n }\r\n return digest;\r\n };\r\n return Sha1;\r\n}(Hash));\n\n/**\r\n * Helper to make a Subscribe function (just like Promise helps make a\r\n * Thenable).\r\n *\r\n * @param executor Function which can make calls to a single Observer\r\n * as a proxy.\r\n * @param onNoObservers Callback when count of Observers goes to zero.\r\n */\r\nfunction createSubscribe(executor, onNoObservers) {\r\n var proxy = new ObserverProxy(executor, onNoObservers);\r\n return proxy.subscribe.bind(proxy);\r\n}\r\n/**\r\n * Implement fan-out for any number of Observers attached via a subscribe\r\n * function.\r\n */\r\nvar ObserverProxy = /** @class */ (function () {\r\n /**\r\n * @param executor Function which can make calls to a single Observer\r\n * as a proxy.\r\n * @param onNoObservers Callback when count of Observers goes to zero.\r\n */\r\n function ObserverProxy(executor, onNoObservers) {\r\n var _this = this;\r\n this.observers = [];\r\n this.unsubscribes = [];\r\n this.observerCount = 0;\r\n // Micro-task scheduling by calling task.then().\r\n this.task = Promise.resolve();\r\n this.finalized = false;\r\n this.onNoObservers = onNoObservers;\r\n // Call the executor asynchronously so subscribers that are called\r\n // synchronously after the creation of the subscribe function\r\n // can still receive the very first value generated in the executor.\r\n this.task\r\n .then(function () {\r\n executor(_this);\r\n })\r\n .catch(function (e) {\r\n _this.error(e);\r\n });\r\n }\r\n ObserverProxy.prototype.next = function (value) {\r\n this.forEachObserver(function (observer) {\r\n observer.next(value);\r\n });\r\n };\r\n ObserverProxy.prototype.error = function (error) {\r\n this.forEachObserver(function (observer) {\r\n observer.error(error);\r\n });\r\n this.close(error);\r\n };\r\n ObserverProxy.prototype.complete = function () {\r\n this.forEachObserver(function (observer) {\r\n observer.complete();\r\n });\r\n this.close();\r\n };\r\n /**\r\n * Subscribe function that can be used to add an Observer to the fan-out list.\r\n *\r\n * - We require that no event is sent to a subscriber sychronously to their\r\n * call to subscribe().\r\n */\r\n ObserverProxy.prototype.subscribe = function (nextOrObserver, error, complete) {\r\n var _this = this;\r\n var observer;\r\n if (nextOrObserver === undefined &&\r\n error === undefined &&\r\n complete === undefined) {\r\n throw new Error('Missing Observer.');\r\n }\r\n // Assemble an Observer object when passed as callback functions.\r\n if (implementsAnyMethods(nextOrObserver, ['next', 'error', 'complete'])) {\r\n observer = nextOrObserver;\r\n }\r\n else {\r\n observer = {\r\n next: nextOrObserver,\r\n error: error,\r\n complete: complete\r\n };\r\n }\r\n if (observer.next === undefined) {\r\n observer.next = noop;\r\n }\r\n if (observer.error === undefined) {\r\n observer.error = noop;\r\n }\r\n if (observer.complete === undefined) {\r\n observer.complete = noop;\r\n }\r\n var unsub = this.unsubscribeOne.bind(this, this.observers.length);\r\n // Attempt to subscribe to a terminated Observable - we\r\n // just respond to the Observer with the final error or complete\r\n // event.\r\n if (this.finalized) {\r\n this.task.then(function () {\r\n try {\r\n if (_this.finalError) {\r\n observer.error(_this.finalError);\r\n }\r\n else {\r\n observer.complete();\r\n }\r\n }\r\n catch (e) {\r\n // nothing\r\n }\r\n return;\r\n });\r\n }\r\n this.observers.push(observer);\r\n return unsub;\r\n };\r\n // Unsubscribe is synchronous - we guarantee that no events are sent to\r\n // any unsubscribed Observer.\r\n ObserverProxy.prototype.unsubscribeOne = function (i) {\r\n if (this.observers === undefined || this.observers[i] === undefined) {\r\n return;\r\n }\r\n delete this.observers[i];\r\n this.observerCount -= 1;\r\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\r\n this.onNoObservers(this);\r\n }\r\n };\r\n ObserverProxy.prototype.forEachObserver = function (fn) {\r\n if (this.finalized) {\r\n // Already closed by previous event....just eat the additional values.\r\n return;\r\n }\r\n // Since sendOne calls asynchronously - there is no chance that\r\n // this.observers will become undefined.\r\n for (var i = 0; i < this.observers.length; i++) {\r\n this.sendOne(i, fn);\r\n }\r\n };\r\n // Call the Observer via one of it's callback function. We are careful to\r\n // confirm that the observe has not been unsubscribed since this asynchronous\r\n // function had been queued.\r\n ObserverProxy.prototype.sendOne = function (i, fn) {\r\n var _this = this;\r\n // Execute the callback asynchronously\r\n this.task.then(function () {\r\n if (_this.observers !== undefined && _this.observers[i] !== undefined) {\r\n try {\r\n fn(_this.observers[i]);\r\n }\r\n catch (e) {\r\n // Ignore exceptions raised in Observers or missing methods of an\r\n // Observer.\r\n // Log error to console. b/31404806\r\n if (typeof console !== 'undefined' && console.error) {\r\n console.error(e);\r\n }\r\n }\r\n }\r\n });\r\n };\r\n ObserverProxy.prototype.close = function (err) {\r\n var _this = this;\r\n if (this.finalized) {\r\n return;\r\n }\r\n this.finalized = true;\r\n if (err !== undefined) {\r\n this.finalError = err;\r\n }\r\n // Proxy is no longer needed - garbage collect references\r\n this.task.then(function () {\r\n _this.observers = undefined;\r\n _this.onNoObservers = undefined;\r\n });\r\n };\r\n return ObserverProxy;\r\n}());\r\n/** Turn synchronous function into one called asynchronously. */\r\nfunction async(fn, onError) {\r\n return function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n Promise.resolve(true)\r\n .then(function () {\r\n fn.apply(void 0, args);\r\n })\r\n .catch(function (error) {\r\n if (onError) {\r\n onError(error);\r\n }\r\n });\r\n };\r\n}\r\n/**\r\n * Return true if the object passed in implements any of the named methods.\r\n */\r\nfunction implementsAnyMethods(obj, methods) {\r\n if (typeof obj !== 'object' || obj === null) {\r\n return false;\r\n }\r\n for (var _i = 0, methods_1 = methods; _i < methods_1.length; _i++) {\r\n var method = methods_1[_i];\r\n if (method in obj && typeof obj[method] === 'function') {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\nfunction noop() {\r\n // do nothing\r\n}\n\n/**\r\n * @license\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 */\r\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 */\r\nvar validateArgCount = function (fnName, minCount, maxCount, argCount) {\r\n var argError;\r\n if (argCount < minCount) {\r\n argError = 'at least ' + minCount;\r\n }\r\n else if (argCount > maxCount) {\r\n argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;\r\n }\r\n if (argError) {\r\n var error = fnName +\r\n ' failed: Was called with ' +\r\n argCount +\r\n (argCount === 1 ? ' argument.' : ' arguments.') +\r\n ' Expects ' +\r\n argError +\r\n '.';\r\n throw new Error(error);\r\n }\r\n};\r\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 */\r\nfunction errorPrefix(fnName, argumentNumber, optional) {\r\n var argName = '';\r\n switch (argumentNumber) {\r\n case 1:\r\n argName = optional ? 'first' : 'First';\r\n break;\r\n case 2:\r\n argName = optional ? 'second' : 'Second';\r\n break;\r\n case 3:\r\n argName = optional ? 'third' : 'Third';\r\n break;\r\n case 4:\r\n argName = optional ? 'fourth' : 'Fourth';\r\n break;\r\n default:\r\n throw new Error('errorPrefix called with argumentNumber > 4. Need to update it?');\r\n }\r\n var error = fnName + ' failed: ';\r\n error += argName + ' argument ';\r\n return error;\r\n}\r\n/**\r\n * @param {!string} fnName\r\n * @param {!number} argumentNumber\r\n * @param {!string} namespace\r\n * @param {boolean} optional\r\n */\r\nfunction validateNamespace(fnName, argumentNumber, namespace, optional) {\r\n if (optional && !namespace)\r\n return;\r\n if (typeof namespace !== 'string') {\r\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'must be a valid firebase namespace.');\r\n }\r\n}\r\nfunction validateCallback(fnName, argumentNumber, callback, optional) {\r\n if (optional && !callback)\r\n return;\r\n if (typeof callback !== 'function')\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'must be a valid function.');\r\n}\r\nfunction validateContextObject(fnName, argumentNumber, context, optional) {\r\n if (optional && !context)\r\n return;\r\n if (typeof context !== 'object' || context === null)\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'must be a valid context object.');\r\n}\n\n/**\r\n * @license\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 */\r\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\r\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\r\n// so it's been modified.\r\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\r\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\r\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\r\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\r\n// pair).\r\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\r\n/**\r\n * @param {string} str\r\n * @return {Array}\r\n */\r\nvar stringToByteArray$1 = function (str) {\r\n var out = [], p = 0;\r\n for (var i = 0; i < str.length; i++) {\r\n var c = str.charCodeAt(i);\r\n // Is this the lead surrogate in a surrogate pair?\r\n if (c >= 0xd800 && c <= 0xdbff) {\r\n var high = c - 0xd800; // the high 10 bits.\r\n i++;\r\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\r\n var low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\r\n c = 0x10000 + (high << 10) + low;\r\n }\r\n if (c < 128) {\r\n out[p++] = c;\r\n }\r\n else if (c < 2048) {\r\n out[p++] = (c >> 6) | 192;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else if (c < 65536) {\r\n out[p++] = (c >> 12) | 224;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else {\r\n out[p++] = (c >> 18) | 240;\r\n out[p++] = ((c >> 12) & 63) | 128;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n }\r\n return out;\r\n};\r\n/**\r\n * Calculate length without actually converting; useful for doing cheaper validation.\r\n * @param {string} str\r\n * @return {number}\r\n */\r\nvar stringLength = function (str) {\r\n var p = 0;\r\n for (var i = 0; i < str.length; i++) {\r\n var c = str.charCodeAt(i);\r\n if (c < 128) {\r\n p++;\r\n }\r\n else if (c < 2048) {\r\n p += 2;\r\n }\r\n else if (c >= 0xd800 && c <= 0xdbff) {\r\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\r\n p += 4;\r\n i++; // skip trail surrogate.\r\n }\r\n else {\r\n p += 3;\r\n }\r\n }\r\n return p;\r\n};\n\n/**\r\n * @license\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\nexport { assert, assertionError, base64, base64Decode, base64Encode, CONSTANTS, deepCopy, deepExtend, patchProperty, Deferred, getUA, isMobileCordova, isNodeSdk, isReactNative, ErrorFactory, FirebaseError, patchCapture, jsonEval, stringify, decode, isAdmin, issuedAtTime, isValidFormat, isValidTimestamp, clone, contains, every, extend, findKey, findValue, forEach, getAnyKey, getCount, getValues, isEmpty, isNonNullObject, map, safeGet, querystring, querystringDecode, Sha1, async, createSubscribe, errorPrefix, validateArgCount, validateCallback, validateContextObject, validateNamespace, stringLength, stringToByteArray$1 as stringToByteArray };\n","/**\r\n * @license\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 */\r\n/**\r\n * A container for all of the Logger instances\r\n */\r\nvar instances = [];\r\n/**\r\n * The JS SDK supports 5 log levels and also allows a user the ability to\r\n * silence the logs altogether.\r\n *\r\n * The order is a follows:\r\n * DEBUG < VERBOSE < INFO < WARN < ERROR\r\n *\r\n * All of the log types above the current log level will be captured (i.e. if\r\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\r\n * `VERBOSE` logs will not)\r\n */\r\nvar LogLevel;\r\n(function (LogLevel) {\r\n LogLevel[LogLevel[\"DEBUG\"] = 0] = \"DEBUG\";\r\n LogLevel[LogLevel[\"VERBOSE\"] = 1] = \"VERBOSE\";\r\n LogLevel[LogLevel[\"INFO\"] = 2] = \"INFO\";\r\n LogLevel[LogLevel[\"WARN\"] = 3] = \"WARN\";\r\n LogLevel[LogLevel[\"ERROR\"] = 4] = \"ERROR\";\r\n LogLevel[LogLevel[\"SILENT\"] = 5] = \"SILENT\";\r\n})(LogLevel || (LogLevel = {}));\r\n/**\r\n * The default log level\r\n */\r\nvar defaultLogLevel = LogLevel.INFO;\r\n/**\r\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\r\n * messages on to their corresponding console counterparts (if the log method\r\n * is supported by the current log level)\r\n */\r\nvar defaultLogHandler = function (instance, logType) {\r\n var args = [];\r\n for (var _i = 2; _i < arguments.length; _i++) {\r\n args[_i - 2] = arguments[_i];\r\n }\r\n if (logType < instance.logLevel)\r\n return;\r\n var now = new Date().toISOString();\r\n switch (logType) {\r\n /**\r\n * By default, `console.debug` is not displayed in the developer console (in\r\n * chrome). To avoid forcing users to have to opt-in to these logs twice\r\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\r\n * logs to the `console.log` function.\r\n */\r\n case LogLevel.DEBUG:\r\n console.log.apply(console, [\"[\" + now + \"] \" + instance.name + \":\"].concat(args));\r\n break;\r\n case LogLevel.VERBOSE:\r\n console.log.apply(console, [\"[\" + now + \"] \" + instance.name + \":\"].concat(args));\r\n break;\r\n case LogLevel.INFO:\r\n console.info.apply(console, [\"[\" + now + \"] \" + instance.name + \":\"].concat(args));\r\n break;\r\n case LogLevel.WARN:\r\n console.warn.apply(console, [\"[\" + now + \"] \" + instance.name + \":\"].concat(args));\r\n break;\r\n case LogLevel.ERROR:\r\n console.error.apply(console, [\"[\" + now + \"] \" + instance.name + \":\"].concat(args));\r\n break;\r\n default:\r\n throw new Error(\"Attempted to log a message with an invalid logType (value: \" + logType + \")\");\r\n }\r\n};\r\nvar Logger = /** @class */ (function () {\r\n /**\r\n * Gives you an instance of a Logger to capture messages according to\r\n * Firebase's logging scheme.\r\n *\r\n * @param name The name that the logs will be associated with\r\n */\r\n function Logger(name) {\r\n this.name = name;\r\n /**\r\n * The log level of the given Logger instance.\r\n */\r\n this._logLevel = defaultLogLevel;\r\n /**\r\n * The log handler for the Logger instance.\r\n */\r\n this._logHandler = defaultLogHandler;\r\n /**\r\n * Capture the current instance for later use\r\n */\r\n instances.push(this);\r\n }\r\n Object.defineProperty(Logger.prototype, \"logLevel\", {\r\n get: function () {\r\n return this._logLevel;\r\n },\r\n set: function (val) {\r\n if (!(val in LogLevel)) {\r\n throw new TypeError('Invalid value assigned to `logLevel`');\r\n }\r\n this._logLevel = val;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(Logger.prototype, \"logHandler\", {\r\n get: function () {\r\n return this._logHandler;\r\n },\r\n set: function (val) {\r\n if (typeof val !== 'function') {\r\n throw new TypeError('Value assigned to `logHandler` must be a function');\r\n }\r\n this._logHandler = val;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * The functions below are all based on the `console` interface\r\n */\r\n Logger.prototype.debug = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._logHandler.apply(this, [this, LogLevel.DEBUG].concat(args));\r\n };\r\n Logger.prototype.log = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._logHandler.apply(this, [this, LogLevel.VERBOSE].concat(args));\r\n };\r\n Logger.prototype.info = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._logHandler.apply(this, [this, LogLevel.INFO].concat(args));\r\n };\r\n Logger.prototype.warn = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._logHandler.apply(this, [this, LogLevel.WARN].concat(args));\r\n };\r\n Logger.prototype.error = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._logHandler.apply(this, [this, LogLevel.ERROR].concat(args));\r\n };\r\n return Logger;\r\n}());\n\n/**\r\n * @license\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 */\r\nfunction setLogLevel(level) {\r\n instances.forEach(function (inst) {\r\n inst.logLevel = level;\r\n });\r\n}\n\nexport { setLogLevel, Logger, LogLevel };\n","import firebase from '@firebase/app';\nimport { __extends, __awaiter, __generator } from 'tslib';\nimport { stringify, jsonEval, contains, assert, base64, stringToByteArray, Sha1, isNodeSdk, forEach, stringLength, errorPrefix, validateArgCount, validateCallback, Deferred, assertionError, safeGet, clone, map, getCount, getAnyKey, every, validateContextObject, isEmpty, getValues, findValue, findKey, deepCopy, isMobileCordova, base64Encode, CONSTANTS, isAdmin, isValidFormat, isReactNative, querystring } from '@firebase/util';\nimport { Logger, LogLevel } from '@firebase/logger';\n\n/**\r\n * @license\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 */\r\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 */\r\nvar DOMStorageWrapper = /** @class */ (function () {\r\n /**\r\n * @param {Storage} domStorage_ The underlying storage object (e.g. localStorage or sessionStorage)\r\n */\r\n function DOMStorageWrapper(domStorage_) {\r\n this.domStorage_ = domStorage_;\r\n // Use a prefix to avoid collisions with other stuff saved by the app.\r\n this.prefix_ = 'firebase:';\r\n }\r\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 */\r\n DOMStorageWrapper.prototype.set = function (key, value) {\r\n if (value == null) {\r\n this.domStorage_.removeItem(this.prefixedName_(key));\r\n }\r\n else {\r\n this.domStorage_.setItem(this.prefixedName_(key), stringify(value));\r\n }\r\n };\r\n /**\r\n * @param {string} key\r\n * @return {*} The value that was stored under this key, or null\r\n */\r\n DOMStorageWrapper.prototype.get = function (key) {\r\n var storedVal = this.domStorage_.getItem(this.prefixedName_(key));\r\n if (storedVal == null) {\r\n return null;\r\n }\r\n else {\r\n return jsonEval(storedVal);\r\n }\r\n };\r\n /**\r\n * @param {string} key\r\n */\r\n DOMStorageWrapper.prototype.remove = function (key) {\r\n this.domStorage_.removeItem(this.prefixedName_(key));\r\n };\r\n /**\r\n * @param {string} name\r\n * @return {string}\r\n */\r\n DOMStorageWrapper.prototype.prefixedName_ = function (name) {\r\n return this.prefix_ + name;\r\n };\r\n DOMStorageWrapper.prototype.toString = function () {\r\n return this.domStorage_.toString();\r\n };\r\n return DOMStorageWrapper;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar MemoryStorage = /** @class */ (function () {\r\n function MemoryStorage() {\r\n this.cache_ = {};\r\n this.isInMemoryStorage = true;\r\n }\r\n MemoryStorage.prototype.set = function (key, value) {\r\n if (value == null) {\r\n delete this.cache_[key];\r\n }\r\n else {\r\n this.cache_[key] = value;\r\n }\r\n };\r\n MemoryStorage.prototype.get = function (key) {\r\n if (contains(this.cache_, key)) {\r\n return this.cache_[key];\r\n }\r\n return null;\r\n };\r\n MemoryStorage.prototype.remove = function (key) {\r\n delete this.cache_[key];\r\n };\r\n return MemoryStorage;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar createStoragefor = function (domStorageName) {\r\n try {\r\n // NOTE: just accessing \"localStorage\" or \"window['localStorage']\" may throw a security exception,\r\n // so it must be inside the try/catch.\r\n if (typeof window !== 'undefined' &&\r\n typeof window[domStorageName] !== 'undefined') {\r\n // Need to test cache. Just because it's here doesn't mean it works\r\n var domStorage = window[domStorageName];\r\n domStorage.setItem('firebase:sentinel', 'cache');\r\n domStorage.removeItem('firebase:sentinel');\r\n return new DOMStorageWrapper(domStorage);\r\n }\r\n }\r\n catch (e) { }\r\n // Failed to create wrapper. Just return in-memory storage.\r\n // TODO: log?\r\n return new MemoryStorage();\r\n};\r\n/** A storage object that lasts across sessions */\r\nvar PersistentStorage = createStoragefor('localStorage');\r\n/** A storage object that only lasts one session */\r\nvar SessionStorage = createStoragefor('sessionStorage');\n\n/**\r\n * @license\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 */\r\nvar logClient = new Logger('@firebase/database');\r\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 */\r\nvar LUIDGenerator = (function () {\r\n var id = 1;\r\n return function () {\r\n return id++;\r\n };\r\n})();\r\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 */\r\nvar sha1 = function (str) {\r\n var utf8Bytes = stringToByteArray(str);\r\n var sha1 = new Sha1();\r\n sha1.update(utf8Bytes);\r\n var sha1Bytes = sha1.digest();\r\n return base64.encodeByteArray(sha1Bytes);\r\n};\r\n/**\r\n * @param {...*} var_args\r\n * @return {string}\r\n * @private\r\n */\r\nvar buildLogMessage_ = function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n var message = '';\r\n for (var i = 0; i < var_args.length; i++) {\r\n if (Array.isArray(var_args[i]) ||\r\n (var_args[i] &&\r\n typeof var_args[i] === 'object' &&\r\n typeof var_args[i].length === 'number')) {\r\n message += buildLogMessage_.apply(null, var_args[i]);\r\n }\r\n else if (typeof var_args[i] === 'object') {\r\n message += stringify(var_args[i]);\r\n }\r\n else {\r\n message += var_args[i];\r\n }\r\n message += ' ';\r\n }\r\n return message;\r\n};\r\n/**\r\n * Use this for all debug messages in Firebase.\r\n * @type {?function(string)}\r\n */\r\nvar logger = null;\r\n/**\r\n * Flag to check for log availability on first log message\r\n * @type {boolean}\r\n * @private\r\n */\r\nvar firstLog_ = true;\r\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 */\r\nvar enableLogging = function (logger_, persistent) {\r\n assert(!persistent || (logger_ === true || logger_ === false), \"Can't turn on custom loggers persistently.\");\r\n if (logger_ === true) {\r\n logClient.logLevel = LogLevel.VERBOSE;\r\n logger = logClient.log.bind(logClient);\r\n if (persistent)\r\n SessionStorage.set('logging_enabled', true);\r\n }\r\n else if (typeof logger_ === 'function') {\r\n logger = logger_;\r\n }\r\n else {\r\n logger = null;\r\n SessionStorage.remove('logging_enabled');\r\n }\r\n};\r\n/**\r\n *\r\n * @param {...(string|Arguments)} var_args\r\n */\r\nvar log = function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n if (firstLog_ === true) {\r\n firstLog_ = false;\r\n if (logger === null && SessionStorage.get('logging_enabled') === true)\r\n enableLogging(true);\r\n }\r\n if (logger) {\r\n var message = buildLogMessage_.apply(null, var_args);\r\n logger(message);\r\n }\r\n};\r\n/**\r\n * @param {!string} prefix\r\n * @return {function(...[*])}\r\n */\r\nvar logWrapper = function (prefix) {\r\n return function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n log.apply(void 0, [prefix].concat(var_args));\r\n };\r\n};\r\n/**\r\n * @param {...string} var_args\r\n */\r\nvar error = function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n var message = 'FIREBASE INTERNAL ERROR: ' + buildLogMessage_.apply(void 0, var_args);\r\n logClient.error(message);\r\n};\r\n/**\r\n * @param {...string} var_args\r\n */\r\nvar fatal = function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n var message = \"FIREBASE FATAL ERROR: \" + buildLogMessage_.apply(void 0, var_args);\r\n logClient.error(message);\r\n throw new Error(message);\r\n};\r\n/**\r\n * @param {...*} var_args\r\n */\r\nvar warn = function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n var message = 'FIREBASE WARNING: ' + buildLogMessage_.apply(void 0, var_args);\r\n logClient.warn(message);\r\n};\r\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 */\r\nvar warnIfPageIsSecure = function () {\r\n // Be very careful accessing browser globals. Who knows what may or may not exist.\r\n if (typeof window !== 'undefined' &&\r\n window.location &&\r\n window.location.protocol &&\r\n window.location.protocol.indexOf('https:') !== -1) {\r\n warn('Insecure Firebase access from a secure page. ' +\r\n 'Please use https in calls to new Firebase().');\r\n }\r\n};\r\n/**\r\n * Returns true if data is NaN, or +/- Infinity.\r\n * @param {*} data\r\n * @return {boolean}\r\n */\r\nvar isInvalidJSONNumber = function (data) {\r\n return (typeof data === 'number' &&\r\n (data != data || // NaN\r\n data == Number.POSITIVE_INFINITY ||\r\n data == Number.NEGATIVE_INFINITY));\r\n};\r\n/**\r\n * @param {function()} fn\r\n */\r\nvar executeWhenDOMReady = function (fn) {\r\n if (isNodeSdk() || document.readyState === 'complete') {\r\n fn();\r\n }\r\n else {\r\n // Modeled after jQuery. Try DOMContentLoaded and onreadystatechange (which\r\n // fire before onload), but fall back to onload.\r\n var called_1 = false;\r\n var wrappedFn_1 = function () {\r\n if (!document.body) {\r\n setTimeout(wrappedFn_1, Math.floor(10));\r\n return;\r\n }\r\n if (!called_1) {\r\n called_1 = true;\r\n fn();\r\n }\r\n };\r\n if (document.addEventListener) {\r\n document.addEventListener('DOMContentLoaded', wrappedFn_1, false);\r\n // fallback to onload.\r\n window.addEventListener('load', wrappedFn_1, false);\r\n }\r\n else if (document.attachEvent) {\r\n // IE.\r\n document.attachEvent('onreadystatechange', function () {\r\n if (document.readyState === 'complete')\r\n wrappedFn_1();\r\n });\r\n // fallback to onload.\r\n window.attachEvent('onload', wrappedFn_1);\r\n // jQuery has an extra hack for IE that we could employ (based on\r\n // http://javascript.nwbox.com/IEContentLoaded/) But it looks really old.\r\n // I'm hoping we don't need it.\r\n }\r\n }\r\n};\r\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 */\r\nvar MIN_NAME = '[MIN_NAME]';\r\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 */\r\nvar MAX_NAME = '[MAX_NAME]';\r\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 */\r\nvar nameCompare = function (a, b) {\r\n if (a === b) {\r\n return 0;\r\n }\r\n else if (a === MIN_NAME || b === MAX_NAME) {\r\n return -1;\r\n }\r\n else if (b === MIN_NAME || a === MAX_NAME) {\r\n return 1;\r\n }\r\n else {\r\n var aAsInt = tryParseInt(a), bAsInt = tryParseInt(b);\r\n if (aAsInt !== null) {\r\n if (bAsInt !== null) {\r\n return aAsInt - bAsInt == 0 ? a.length - b.length : aAsInt - bAsInt;\r\n }\r\n else {\r\n return -1;\r\n }\r\n }\r\n else if (bAsInt !== null) {\r\n return 1;\r\n }\r\n else {\r\n return a < b ? -1 : 1;\r\n }\r\n }\r\n};\r\n/**\r\n * @param {!string} a\r\n * @param {!string} b\r\n * @return {!number} comparison result.\r\n */\r\nvar stringCompare = function (a, b) {\r\n if (a === b) {\r\n return 0;\r\n }\r\n else if (a < b) {\r\n return -1;\r\n }\r\n else {\r\n return 1;\r\n }\r\n};\r\n/**\r\n * @param {string} key\r\n * @param {Object} obj\r\n * @return {*}\r\n */\r\nvar requireKey = function (key, obj) {\r\n if (obj && key in obj) {\r\n return obj[key];\r\n }\r\n else {\r\n throw new Error('Missing required key (' + key + ') in object: ' + stringify(obj));\r\n }\r\n};\r\n/**\r\n * @param {*} obj\r\n * @return {string}\r\n */\r\nvar ObjectToUniqueKey = function (obj) {\r\n if (typeof obj !== 'object' || obj === null)\r\n return stringify(obj);\r\n var keys = [];\r\n for (var k in obj) {\r\n keys.push(k);\r\n }\r\n // Export as json, but with the keys sorted.\r\n keys.sort();\r\n var key = '{';\r\n for (var i = 0; i < keys.length; i++) {\r\n if (i !== 0)\r\n key += ',';\r\n key += stringify(keys[i]);\r\n key += ':';\r\n key += ObjectToUniqueKey(obj[keys[i]]);\r\n }\r\n key += '}';\r\n return key;\r\n};\r\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 */\r\nvar splitStringBySize = function (str, segsize) {\r\n var len = str.length;\r\n if (len <= segsize) {\r\n return [str];\r\n }\r\n var dataSegs = [];\r\n for (var c = 0; c < len; c += segsize) {\r\n if (c + segsize > len) {\r\n dataSegs.push(str.substring(c, len));\r\n }\r\n else {\r\n dataSegs.push(str.substring(c, c + segsize));\r\n }\r\n }\r\n return dataSegs;\r\n};\r\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 */\r\nvar each = function (obj, fn) {\r\n if (Array.isArray(obj)) {\r\n for (var i = 0; i < obj.length; ++i) {\r\n fn(i, obj[i]);\r\n }\r\n }\r\n else {\r\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 */\r\n forEach(obj, function (key, val) { return fn(val, key); });\r\n }\r\n};\r\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 */\r\nvar doubleToIEEE754String = function (v) {\r\n assert(!isInvalidJSONNumber(v), 'Invalid JSON number'); // MJL\r\n var ebits = 11, fbits = 52;\r\n var bias = (1 << (ebits - 1)) - 1, s, e, f, ln, i, bits, str;\r\n // Compute sign, exponent, fraction\r\n // Skip NaN / Infinity handling --MJL.\r\n if (v === 0) {\r\n e = 0;\r\n f = 0;\r\n s = 1 / v === -Infinity ? 1 : 0;\r\n }\r\n else {\r\n s = v < 0;\r\n v = Math.abs(v);\r\n if (v >= Math.pow(2, 1 - bias)) {\r\n // Normalized\r\n ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);\r\n e = ln + bias;\r\n f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits));\r\n }\r\n else {\r\n // Denormalized\r\n e = 0;\r\n f = Math.round(v / Math.pow(2, 1 - bias - fbits));\r\n }\r\n }\r\n // Pack sign, exponent, fraction\r\n bits = [];\r\n for (i = fbits; i; i -= 1) {\r\n bits.push(f % 2 ? 1 : 0);\r\n f = Math.floor(f / 2);\r\n }\r\n for (i = ebits; i; i -= 1) {\r\n bits.push(e % 2 ? 1 : 0);\r\n e = Math.floor(e / 2);\r\n }\r\n bits.push(s ? 1 : 0);\r\n bits.reverse();\r\n str = bits.join('');\r\n // Return the data as a hex string. --MJL\r\n var hexByteString = '';\r\n for (i = 0; i < 64; i += 8) {\r\n var hexByte = parseInt(str.substr(i, 8), 2).toString(16);\r\n if (hexByte.length === 1)\r\n hexByte = '0' + hexByte;\r\n hexByteString = hexByteString + hexByte;\r\n }\r\n return hexByteString.toLowerCase();\r\n};\r\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 */\r\nvar isChromeExtensionContentScript = function () {\r\n return !!(typeof window === 'object' &&\r\n window['chrome'] &&\r\n window['chrome']['extension'] &&\r\n !/^chrome/.test(window.location.href));\r\n};\r\n/**\r\n * Used to detect if we're in a Windows 8 Store app.\r\n * @return {boolean}\r\n */\r\nvar isWindowsStoreApp = function () {\r\n // Check for the presence of a couple WinRT globals\r\n return typeof Windows === 'object' && typeof Windows.UI === 'object';\r\n};\r\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 */\r\nvar errorForServerCode = function (code, query) {\r\n var reason = 'Unknown Error';\r\n if (code === 'too_big') {\r\n reason =\r\n 'The data requested exceeds the maximum size ' +\r\n 'that can be accessed with a single request.';\r\n }\r\n else if (code == 'permission_denied') {\r\n reason = \"Client doesn't have permission to access the desired data.\";\r\n }\r\n else if (code == 'unavailable') {\r\n reason = 'The service is unavailable';\r\n }\r\n var error = new Error(code + ' at ' + query.path.toString() + ': ' + reason);\r\n error.code = code.toUpperCase();\r\n return error;\r\n};\r\n/**\r\n * Used to test for integer-looking strings\r\n * @type {RegExp}\r\n * @private\r\n */\r\nvar INTEGER_REGEXP_ = new RegExp('^-?\\\\d{1,10}$');\r\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 */\r\nvar tryParseInt = function (str) {\r\n if (INTEGER_REGEXP_.test(str)) {\r\n var intVal = Number(str);\r\n if (intVal >= -2147483648 && intVal <= 2147483647) {\r\n return intVal;\r\n }\r\n }\r\n return null;\r\n};\r\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 */\r\nvar exceptionGuard = function (fn) {\r\n try {\r\n fn();\r\n }\r\n catch (e) {\r\n // Re-throw exception when it's safe.\r\n setTimeout(function () {\r\n // It used to be that \"throw e\" would result in a good console error with\r\n // relevant context, but as of Chrome 39, you just get the firebase.js\r\n // file/line number where we re-throw it, which is useless. So we log\r\n // e.stack explicitly.\r\n var stack = e.stack || '';\r\n warn('Exception was thrown by user callback.', stack);\r\n throw e;\r\n }, Math.floor(0));\r\n }\r\n};\r\n/**\r\n * @return {boolean} true if we think we're currently being crawled.\r\n */\r\nvar beingCrawled = function () {\r\n var userAgent = (typeof window === 'object' &&\r\n window['navigator'] &&\r\n window['navigator']['userAgent']) ||\r\n '';\r\n // For now we whitelist the most popular crawlers. We should refine this to be the set of crawlers we\r\n // believe to support JavaScript/AJAX rendering.\r\n // NOTE: Google Webmaster Tools doesn't really belong, but their \"This is how a visitor to your website\r\n // would have seen the page\" is flaky if we don't treat it as a crawler.\r\n return (userAgent.search(/googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i) >= 0);\r\n};\r\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 */\r\nvar setTimeoutNonBlocking = function (fn, time) {\r\n var timeout = setTimeout(fn, time);\r\n if (typeof timeout === 'object' && timeout['unref']) {\r\n timeout['unref']();\r\n }\r\n return timeout;\r\n};\n\n/**\r\n * @license\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 */\r\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 */\r\nvar Path = /** @class */ (function () {\r\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 */\r\n function Path(pathOrString, pieceNum) {\r\n if (pieceNum === void 0) {\r\n this.pieces_ = pathOrString.split('/');\r\n // Remove empty pieces.\r\n var copyTo = 0;\r\n for (var i = 0; i < this.pieces_.length; i++) {\r\n if (this.pieces_[i].length > 0) {\r\n this.pieces_[copyTo] = this.pieces_[i];\r\n copyTo++;\r\n }\r\n }\r\n this.pieces_.length = copyTo;\r\n this.pieceNum_ = 0;\r\n }\r\n else {\r\n this.pieces_ = pathOrString;\r\n this.pieceNum_ = pieceNum;\r\n }\r\n }\r\n Object.defineProperty(Path, \"Empty\", {\r\n /**\r\n * Singleton to represent an empty path\r\n *\r\n * @const\r\n */\r\n get: function () {\r\n return new Path('');\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Path.prototype.getFront = function () {\r\n if (this.pieceNum_ >= this.pieces_.length)\r\n return null;\r\n return this.pieces_[this.pieceNum_];\r\n };\r\n /**\r\n * @return {number} The number of segments in this path\r\n */\r\n Path.prototype.getLength = function () {\r\n return this.pieces_.length - this.pieceNum_;\r\n };\r\n /**\r\n * @return {!Path}\r\n */\r\n Path.prototype.popFront = function () {\r\n var pieceNum = this.pieceNum_;\r\n if (pieceNum < this.pieces_.length) {\r\n pieceNum++;\r\n }\r\n return new Path(this.pieces_, pieceNum);\r\n };\r\n /**\r\n * @return {?string}\r\n */\r\n Path.prototype.getBack = function () {\r\n if (this.pieceNum_ < this.pieces_.length)\r\n return this.pieces_[this.pieces_.length - 1];\r\n return null;\r\n };\r\n Path.prototype.toString = function () {\r\n var pathString = '';\r\n for (var i = this.pieceNum_; i < this.pieces_.length; i++) {\r\n if (this.pieces_[i] !== '')\r\n pathString += '/' + this.pieces_[i];\r\n }\r\n return pathString || '/';\r\n };\r\n Path.prototype.toUrlEncodedString = function () {\r\n var pathString = '';\r\n for (var i = this.pieceNum_; i < this.pieces_.length; i++) {\r\n if (this.pieces_[i] !== '')\r\n pathString += '/' + encodeURIComponent(String(this.pieces_[i]));\r\n }\r\n return pathString || '/';\r\n };\r\n /**\r\n * Shallow copy of the parts of the path.\r\n *\r\n * @param {number=} begin\r\n * @return {!Array}\r\n */\r\n Path.prototype.slice = function (begin) {\r\n if (begin === void 0) { begin = 0; }\r\n return this.pieces_.slice(this.pieceNum_ + begin);\r\n };\r\n /**\r\n * @return {?Path}\r\n */\r\n Path.prototype.parent = function () {\r\n if (this.pieceNum_ >= this.pieces_.length)\r\n return null;\r\n var pieces = [];\r\n for (var i = this.pieceNum_; i < this.pieces_.length - 1; i++)\r\n pieces.push(this.pieces_[i]);\r\n return new Path(pieces, 0);\r\n };\r\n /**\r\n * @param {string|!Path} childPathObj\r\n * @return {!Path}\r\n */\r\n Path.prototype.child = function (childPathObj) {\r\n var pieces = [];\r\n for (var i = this.pieceNum_; i < this.pieces_.length; i++)\r\n pieces.push(this.pieces_[i]);\r\n if (childPathObj instanceof Path) {\r\n for (var i = childPathObj.pieceNum_; i < childPathObj.pieces_.length; i++) {\r\n pieces.push(childPathObj.pieces_[i]);\r\n }\r\n }\r\n else {\r\n var childPieces = childPathObj.split('/');\r\n for (var i = 0; i < childPieces.length; i++) {\r\n if (childPieces[i].length > 0)\r\n pieces.push(childPieces[i]);\r\n }\r\n }\r\n return new Path(pieces, 0);\r\n };\r\n /**\r\n * @return {boolean} True if there are no segments in this path\r\n */\r\n Path.prototype.isEmpty = function () {\r\n return this.pieceNum_ >= this.pieces_.length;\r\n };\r\n /**\r\n * @param {!Path} outerPath\r\n * @param {!Path} innerPath\r\n * @return {!Path} The path from outerPath to innerPath\r\n */\r\n Path.relativePath = function (outerPath, innerPath) {\r\n var outer = outerPath.getFront(), inner = innerPath.getFront();\r\n if (outer === null) {\r\n return innerPath;\r\n }\r\n else if (outer === inner) {\r\n return Path.relativePath(outerPath.popFront(), innerPath.popFront());\r\n }\r\n else {\r\n throw new Error('INTERNAL ERROR: innerPath (' +\r\n innerPath +\r\n ') is not within ' +\r\n 'outerPath (' +\r\n outerPath +\r\n ')');\r\n }\r\n };\r\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 */\r\n Path.comparePaths = function (left, right) {\r\n var leftKeys = left.slice();\r\n var rightKeys = right.slice();\r\n for (var i = 0; i < leftKeys.length && i < rightKeys.length; i++) {\r\n var cmp = nameCompare(leftKeys[i], rightKeys[i]);\r\n if (cmp !== 0)\r\n return cmp;\r\n }\r\n if (leftKeys.length === rightKeys.length)\r\n return 0;\r\n return leftKeys.length < rightKeys.length ? -1 : 1;\r\n };\r\n /**\r\n *\r\n * @param {Path} other\r\n * @return {boolean} true if paths are the same.\r\n */\r\n Path.prototype.equals = function (other) {\r\n if (this.getLength() !== other.getLength()) {\r\n return false;\r\n }\r\n for (var i = this.pieceNum_, j = other.pieceNum_; i <= this.pieces_.length; i++, j++) {\r\n if (this.pieces_[i] !== other.pieces_[j]) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n };\r\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 */\r\n Path.prototype.contains = function (other) {\r\n var i = this.pieceNum_;\r\n var j = other.pieceNum_;\r\n if (this.getLength() > other.getLength()) {\r\n return false;\r\n }\r\n while (i < this.pieces_.length) {\r\n if (this.pieces_[i] !== other.pieces_[j]) {\r\n return false;\r\n }\r\n ++i;\r\n ++j;\r\n }\r\n return true;\r\n };\r\n return Path;\r\n}()); // end Path\r\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 */\r\nvar ValidationPath = /** @class */ (function () {\r\n /**\r\n * @param {!Path} path Initial Path.\r\n * @param {string} errorPrefix_ Prefix for any error messages.\r\n */\r\n function ValidationPath(path, errorPrefix_) {\r\n this.errorPrefix_ = errorPrefix_;\r\n /** @type {!Array} */\r\n this.parts_ = path.slice();\r\n /** @type {number} Initialize to number of '/' chars needed in path. */\r\n this.byteLength_ = Math.max(1, this.parts_.length);\r\n for (var i = 0; i < this.parts_.length; i++) {\r\n this.byteLength_ += stringLength(this.parts_[i]);\r\n }\r\n this.checkValid_();\r\n }\r\n Object.defineProperty(ValidationPath, \"MAX_PATH_DEPTH\", {\r\n /** @const {number} Maximum key depth. */\r\n get: function () {\r\n return 32;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(ValidationPath, \"MAX_PATH_LENGTH_BYTES\", {\r\n /** @const {number} Maximum number of (UTF8) bytes in a Firebase path. */\r\n get: function () {\r\n return 768;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /** @param {string} child */\r\n ValidationPath.prototype.push = function (child) {\r\n // Count the needed '/'\r\n if (this.parts_.length > 0) {\r\n this.byteLength_ += 1;\r\n }\r\n this.parts_.push(child);\r\n this.byteLength_ += stringLength(child);\r\n this.checkValid_();\r\n };\r\n ValidationPath.prototype.pop = function () {\r\n var last = this.parts_.pop();\r\n this.byteLength_ -= stringLength(last);\r\n // Un-count the previous '/'\r\n if (this.parts_.length > 0) {\r\n this.byteLength_ -= 1;\r\n }\r\n };\r\n ValidationPath.prototype.checkValid_ = function () {\r\n if (this.byteLength_ > ValidationPath.MAX_PATH_LENGTH_BYTES) {\r\n throw new Error(this.errorPrefix_ +\r\n 'has a key path longer than ' +\r\n ValidationPath.MAX_PATH_LENGTH_BYTES +\r\n ' bytes (' +\r\n this.byteLength_ +\r\n ').');\r\n }\r\n if (this.parts_.length > ValidationPath.MAX_PATH_DEPTH) {\r\n throw new Error(this.errorPrefix_ +\r\n 'path specified exceeds the maximum depth that can be written (' +\r\n ValidationPath.MAX_PATH_DEPTH +\r\n ') or object contains a cycle ' +\r\n this.toErrorString());\r\n }\r\n };\r\n /**\r\n * String for use in error messages - uses '.' notation for path.\r\n *\r\n * @return {string}\r\n */\r\n ValidationPath.prototype.toErrorString = function () {\r\n if (this.parts_.length == 0) {\r\n return '';\r\n }\r\n return \"in property '\" + this.parts_.join('.') + \"'\";\r\n };\r\n return ValidationPath;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar PROTOCOL_VERSION = '5';\r\nvar VERSION_PARAM = 'v';\r\nvar TRANSPORT_SESSION_PARAM = 's';\r\nvar REFERER_PARAM = 'r';\r\nvar FORGE_REF = 'f';\r\nvar FORGE_DOMAIN = 'firebaseio.com';\r\nvar LAST_SESSION_PARAM = 'ls';\r\nvar WEBSOCKET = 'websocket';\r\nvar LONG_POLLING = 'long_polling';\n\n/**\r\n * @license\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 */\r\n/**\r\n * A class that holds metadata about a Repo object\r\n *\r\n * @constructor\r\n */\r\nvar RepoInfo = /** @class */ (function () {\r\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 */\r\n function RepoInfo(host, secure, namespace, webSocketOnly, persistenceKey) {\r\n if (persistenceKey === void 0) { persistenceKey = ''; }\r\n this.secure = secure;\r\n this.namespace = namespace;\r\n this.webSocketOnly = webSocketOnly;\r\n this.persistenceKey = persistenceKey;\r\n this.host = host.toLowerCase();\r\n this.domain = this.host.substr(this.host.indexOf('.') + 1);\r\n this.internalHost = PersistentStorage.get('host:' + host) || this.host;\r\n }\r\n RepoInfo.prototype.needsQueryParam = function () {\r\n return this.host !== this.internalHost || this.isCustomHost();\r\n };\r\n RepoInfo.prototype.isCacheableHost = function () {\r\n return this.internalHost.substr(0, 2) === 's-';\r\n };\r\n RepoInfo.prototype.isDemoHost = function () {\r\n return this.domain === 'firebaseio-demo.com';\r\n };\r\n RepoInfo.prototype.isCustomHost = function () {\r\n return (this.domain !== 'firebaseio.com' && this.domain !== 'firebaseio-demo.com');\r\n };\r\n RepoInfo.prototype.updateHost = function (newHost) {\r\n if (newHost !== this.internalHost) {\r\n this.internalHost = newHost;\r\n if (this.isCacheableHost()) {\r\n PersistentStorage.set('host:' + this.host, this.internalHost);\r\n }\r\n }\r\n };\r\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 */\r\n RepoInfo.prototype.connectionURL = function (type, params) {\r\n assert(typeof type === 'string', 'typeof type must == string');\r\n assert(typeof params === 'object', 'typeof params must == object');\r\n var connURL;\r\n if (type === WEBSOCKET) {\r\n connURL =\r\n (this.secure ? 'wss://' : 'ws://') + this.internalHost + '/.ws?';\r\n }\r\n else if (type === LONG_POLLING) {\r\n connURL =\r\n (this.secure ? 'https://' : 'http://') + this.internalHost + '/.lp?';\r\n }\r\n else {\r\n throw new Error('Unknown connection type: ' + type);\r\n }\r\n if (this.needsQueryParam()) {\r\n params['ns'] = this.namespace;\r\n }\r\n var pairs = [];\r\n forEach(params, function (key, value) {\r\n pairs.push(key + '=' + value);\r\n });\r\n return connURL + pairs.join('&');\r\n };\r\n /** @return {string} */\r\n RepoInfo.prototype.toString = function () {\r\n var str = this.toURLString();\r\n if (this.persistenceKey) {\r\n str += '<' + this.persistenceKey + '>';\r\n }\r\n return str;\r\n };\r\n /** @return {string} */\r\n RepoInfo.prototype.toURLString = function () {\r\n return (this.secure ? 'https://' : 'http://') + this.host;\r\n };\r\n return RepoInfo;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * @param {!string} pathString\r\n * @return {string}\r\n */\r\nfunction decodePath(pathString) {\r\n var pathStringDecoded = '';\r\n var pieces = pathString.split('/');\r\n for (var i = 0; i < pieces.length; i++) {\r\n if (pieces[i].length > 0) {\r\n var piece = pieces[i];\r\n try {\r\n piece = decodeURIComponent(piece.replace(/\\+/g, ' '));\r\n }\r\n catch (e) { }\r\n pathStringDecoded += '/' + piece;\r\n }\r\n }\r\n return pathStringDecoded;\r\n}\r\n/**\r\n * @param {!string} queryString\r\n * @return {!{[key:string]:string}} key value hash\r\n */\r\nfunction decodeQuery(queryString) {\r\n var results = {};\r\n if (queryString.charAt(0) === '?') {\r\n queryString = queryString.substring(1);\r\n }\r\n for (var _i = 0, _a = queryString.split('&'); _i < _a.length; _i++) {\r\n var segment = _a[_i];\r\n if (segment.length === 0) {\r\n continue;\r\n }\r\n var kv = segment.split('=');\r\n if (kv.length === 2) {\r\n results[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]);\r\n }\r\n else {\r\n warn(\"Invalid query segment '\" + segment + \"' in query '\" + queryString + \"'\");\r\n }\r\n }\r\n return results;\r\n}\r\n/**\r\n *\r\n * @param {!string} dataURL\r\n * @return {{repoInfo: !RepoInfo, path: !Path}}\r\n */\r\nvar parseRepoInfo = function (dataURL) {\r\n var parsedUrl = parseURL(dataURL), namespace = parsedUrl.subdomain;\r\n if (parsedUrl.domain === 'firebase') {\r\n fatal(parsedUrl.host +\r\n ' is no longer supported. ' +\r\n 'Please use .firebaseio.com instead');\r\n }\r\n // Catch common error of uninitialized namespace value.\r\n if ((!namespace || namespace == 'undefined') &&\r\n parsedUrl.domain !== 'localhost') {\r\n fatal('Cannot parse Firebase url. Please use https://.firebaseio.com');\r\n }\r\n if (!parsedUrl.secure) {\r\n warnIfPageIsSecure();\r\n }\r\n var webSocketOnly = parsedUrl.scheme === 'ws' || parsedUrl.scheme === 'wss';\r\n return {\r\n repoInfo: new RepoInfo(parsedUrl.host, parsedUrl.secure, namespace, webSocketOnly),\r\n path: new Path(parsedUrl.pathString)\r\n };\r\n};\r\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 */\r\nvar parseURL = function (dataURL) {\r\n // Default to empty strings in the event of a malformed string.\r\n var host = '', domain = '', subdomain = '', pathString = '';\r\n // Always default to SSL, unless otherwise specified.\r\n var secure = true, scheme = 'https', port = 443;\r\n // Don't do any validation here. The caller is responsible for validating the result of parsing.\r\n if (typeof dataURL === 'string') {\r\n // Parse scheme.\r\n var colonInd = dataURL.indexOf('//');\r\n if (colonInd >= 0) {\r\n scheme = dataURL.substring(0, colonInd - 1);\r\n dataURL = dataURL.substring(colonInd + 2);\r\n }\r\n // Parse host, path, and query string.\r\n var slashInd = dataURL.indexOf('/');\r\n if (slashInd === -1) {\r\n slashInd = dataURL.length;\r\n }\r\n var questionMarkInd = dataURL.indexOf('?');\r\n if (questionMarkInd === -1) {\r\n questionMarkInd = dataURL.length;\r\n }\r\n host = dataURL.substring(0, Math.min(slashInd, questionMarkInd));\r\n if (slashInd < questionMarkInd) {\r\n // For pathString, questionMarkInd will always come after slashInd\r\n pathString = decodePath(dataURL.substring(slashInd, questionMarkInd));\r\n }\r\n var queryParams = decodeQuery(dataURL.substring(Math.min(dataURL.length, questionMarkInd)));\r\n // If we have a port, use scheme for determining if it's secure.\r\n colonInd = host.indexOf(':');\r\n if (colonInd >= 0) {\r\n secure = scheme === 'https' || scheme === 'wss';\r\n port = parseInt(host.substring(colonInd + 1), 10);\r\n }\r\n else {\r\n colonInd = dataURL.length;\r\n }\r\n var parts = host.split('.');\r\n if (parts.length === 3) {\r\n // Normalize namespaces to lowercase to share storage / connection.\r\n domain = parts[1];\r\n subdomain = parts[0].toLowerCase();\r\n }\r\n else if (parts.length === 2) {\r\n domain = parts[0];\r\n }\r\n else if (parts[0].slice(0, colonInd).toLowerCase() === 'localhost') {\r\n domain = 'localhost';\r\n }\r\n // Support `ns` query param if subdomain not already set\r\n if (subdomain === '' && 'ns' in queryParams) {\r\n subdomain = queryParams['ns'];\r\n }\r\n }\r\n return {\r\n host: host,\r\n port: port,\r\n domain: domain,\r\n subdomain: subdomain,\r\n secure: secure,\r\n scheme: scheme,\r\n pathString: pathString\r\n };\r\n};\n\n/**\r\n * @license\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 */\r\n/**\r\n * True for invalid Firebase keys\r\n * @type {RegExp}\r\n * @private\r\n */\r\nvar INVALID_KEY_REGEX_ = /[\\[\\].#$\\/\\u0000-\\u001F\\u007F]/;\r\n/**\r\n * True for invalid Firebase paths.\r\n * Allows '/' in paths.\r\n * @type {RegExp}\r\n * @private\r\n */\r\nvar INVALID_PATH_REGEX_ = /[\\[\\].#$\\u0000-\\u001F\\u007F]/;\r\n/**\r\n * Maximum number of characters to allow in leaf value\r\n * @type {number}\r\n * @private\r\n */\r\nvar MAX_LEAF_SIZE_ = 10 * 1024 * 1024;\r\n/**\r\n * @param {*} key\r\n * @return {boolean}\r\n */\r\nvar isValidKey = function (key) {\r\n return (typeof key === 'string' && key.length !== 0 && !INVALID_KEY_REGEX_.test(key));\r\n};\r\n/**\r\n * @param {string} pathString\r\n * @return {boolean}\r\n */\r\nvar isValidPathString = function (pathString) {\r\n return (typeof pathString === 'string' &&\r\n pathString.length !== 0 &&\r\n !INVALID_PATH_REGEX_.test(pathString));\r\n};\r\n/**\r\n * @param {string} pathString\r\n * @return {boolean}\r\n */\r\nvar isValidRootPathString = function (pathString) {\r\n if (pathString) {\r\n // Allow '/.info/' at the beginning.\r\n pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\r\n }\r\n return isValidPathString(pathString);\r\n};\r\n/**\r\n * @param {*} priority\r\n * @return {boolean}\r\n */\r\nvar isValidPriority = function (priority) {\r\n return (priority === null ||\r\n typeof priority === 'string' ||\r\n (typeof priority === 'number' && !isInvalidJSONNumber(priority)) ||\r\n (priority && typeof priority === 'object' && contains(priority, '.sv')));\r\n};\r\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 */\r\nvar validateFirebaseDataArg = function (fnName, argumentNumber, data, path, optional) {\r\n if (optional && data === undefined)\r\n return;\r\n validateFirebaseData(errorPrefix(fnName, argumentNumber, optional), data, path);\r\n};\r\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 */\r\nvar validateFirebaseData = function (errorPrefix, data, path_) {\r\n var path = path_ instanceof Path ? new ValidationPath(path_, errorPrefix) : path_;\r\n if (data === undefined) {\r\n throw new Error(errorPrefix + 'contains undefined ' + path.toErrorString());\r\n }\r\n if (typeof data === 'function') {\r\n throw new Error(errorPrefix +\r\n 'contains a function ' +\r\n path.toErrorString() +\r\n ' with contents = ' +\r\n data.toString());\r\n }\r\n if (isInvalidJSONNumber(data)) {\r\n throw new Error(errorPrefix + 'contains ' + data.toString() + ' ' + path.toErrorString());\r\n }\r\n // Check max leaf size, but try to avoid the utf8 conversion if we can.\r\n if (typeof data === 'string' &&\r\n data.length > MAX_LEAF_SIZE_ / 3 &&\r\n stringLength(data) > MAX_LEAF_SIZE_) {\r\n throw new Error(errorPrefix +\r\n 'contains a string greater than ' +\r\n MAX_LEAF_SIZE_ +\r\n ' utf8 bytes ' +\r\n path.toErrorString() +\r\n \" ('\" +\r\n data.substring(0, 50) +\r\n \"...')\");\r\n }\r\n // TODO = Perf = Consider combining the recursive validation of keys into NodeFromJSON\r\n // to save extra walking of large objects.\r\n if (data && typeof data === 'object') {\r\n var hasDotValue_1 = false, hasActualChild_1 = false;\r\n forEach(data, function (key, value) {\r\n if (key === '.value') {\r\n hasDotValue_1 = true;\r\n }\r\n else if (key !== '.priority' && key !== '.sv') {\r\n hasActualChild_1 = true;\r\n if (!isValidKey(key)) {\r\n throw new Error(errorPrefix +\r\n ' contains an invalid key (' +\r\n key +\r\n ') ' +\r\n path.toErrorString() +\r\n '. Keys must be non-empty strings ' +\r\n 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"');\r\n }\r\n }\r\n path.push(key);\r\n validateFirebaseData(errorPrefix, value, path);\r\n path.pop();\r\n });\r\n if (hasDotValue_1 && hasActualChild_1) {\r\n throw new Error(errorPrefix +\r\n ' contains \".value\" child ' +\r\n path.toErrorString() +\r\n ' in addition to actual children.');\r\n }\r\n }\r\n};\r\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 */\r\nvar validateFirebaseMergePaths = function (errorPrefix, mergePaths) {\r\n var i, curPath;\r\n for (i = 0; i < mergePaths.length; i++) {\r\n curPath = mergePaths[i];\r\n var keys = curPath.slice();\r\n for (var j = 0; j < keys.length; j++) {\r\n if (keys[j] === '.priority' && j === keys.length - 1) ;\r\n else if (!isValidKey(keys[j])) {\r\n throw new Error(errorPrefix +\r\n 'contains an invalid key (' +\r\n keys[j] +\r\n ') in path ' +\r\n curPath.toString() +\r\n '. Keys must be non-empty strings ' +\r\n 'and can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\"');\r\n }\r\n }\r\n }\r\n // Check that update keys are not descendants of each other.\r\n // We rely on the property that sorting guarantees that ancestors come\r\n // right before descendants.\r\n mergePaths.sort(Path.comparePaths);\r\n var prevPath = null;\r\n for (i = 0; i < mergePaths.length; i++) {\r\n curPath = mergePaths[i];\r\n if (prevPath !== null && prevPath.contains(curPath)) {\r\n throw new Error(errorPrefix +\r\n 'contains a path ' +\r\n prevPath.toString() +\r\n ' that is ancestor of another path ' +\r\n curPath.toString());\r\n }\r\n prevPath = curPath;\r\n }\r\n};\r\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 */\r\nvar validateFirebaseMergeDataArg = function (fnName, argumentNumber, data, path, optional) {\r\n if (optional && data === undefined)\r\n return;\r\n var errorPrefix$1 = errorPrefix(fnName, argumentNumber, optional);\r\n if (!(data && typeof data === 'object') || Array.isArray(data)) {\r\n throw new Error(errorPrefix$1 + ' must be an object containing the children to replace.');\r\n }\r\n var mergePaths = [];\r\n forEach(data, function (key, value) {\r\n var curPath = new Path(key);\r\n validateFirebaseData(errorPrefix$1, value, path.child(curPath));\r\n if (curPath.getBack() === '.priority') {\r\n if (!isValidPriority(value)) {\r\n throw new Error(errorPrefix$1 +\r\n \"contains an invalid value for '\" +\r\n curPath.toString() +\r\n \"', which must be a valid \" +\r\n 'Firebase priority (a string, finite number, server value, or null).');\r\n }\r\n }\r\n mergePaths.push(curPath);\r\n });\r\n validateFirebaseMergePaths(errorPrefix$1, mergePaths);\r\n};\r\nvar validatePriority = function (fnName, argumentNumber, priority, optional) {\r\n if (optional && priority === undefined)\r\n return;\r\n if (isInvalidJSONNumber(priority))\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'is ' +\r\n priority.toString() +\r\n ', but must be a valid Firebase priority (a string, finite number, ' +\r\n 'server value, or null).');\r\n // Special case to allow importing data with a .sv.\r\n if (!isValidPriority(priority))\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'must be a valid Firebase priority ' +\r\n '(a string, finite number, server value, or null).');\r\n};\r\nvar validateEventType = function (fnName, argumentNumber, eventType, optional) {\r\n if (optional && eventType === undefined)\r\n return;\r\n switch (eventType) {\r\n case 'value':\r\n case 'child_added':\r\n case 'child_removed':\r\n case 'child_changed':\r\n case 'child_moved':\r\n break;\r\n default:\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'must be a valid event type = \"value\", \"child_added\", \"child_removed\", ' +\r\n '\"child_changed\", or \"child_moved\".');\r\n }\r\n};\r\nvar validateKey = function (fnName, argumentNumber, key, optional) {\r\n if (optional && key === undefined)\r\n return;\r\n if (!isValidKey(key))\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'was an invalid key = \"' +\r\n key +\r\n '\". Firebase keys must be non-empty strings and ' +\r\n 'can\\'t contain \".\", \"#\", \"$\", \"/\", \"[\", or \"]\").');\r\n};\r\nvar validatePathString = function (fnName, argumentNumber, pathString, optional) {\r\n if (optional && pathString === undefined)\r\n return;\r\n if (!isValidPathString(pathString))\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) +\r\n 'was an invalid path = \"' +\r\n pathString +\r\n '\". Paths must be non-empty strings and ' +\r\n 'can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\"');\r\n};\r\nvar validateRootPathString = function (fnName, argumentNumber, pathString, optional) {\r\n if (pathString) {\r\n // Allow '/.info/' at the beginning.\r\n pathString = pathString.replace(/^\\/*\\.info(\\/|$)/, '/');\r\n }\r\n validatePathString(fnName, argumentNumber, pathString, optional);\r\n};\r\nvar validateWritablePath = function (fnName, path) {\r\n if (path.getFront() === '.info') {\r\n throw new Error(fnName + \" failed = Can't modify data under /.info/\");\r\n }\r\n};\r\nvar validateUrl = function (fnName, argumentNumber, parsedUrl) {\r\n // TODO = Validate server better.\r\n var pathString = parsedUrl.path.toString();\r\n if (!(typeof parsedUrl.repoInfo.host === 'string') ||\r\n parsedUrl.repoInfo.host.length === 0 ||\r\n (!isValidKey(parsedUrl.repoInfo.namespace) &&\r\n parsedUrl.repoInfo.host.split(':')[0] !== 'localhost') ||\r\n (pathString.length !== 0 && !isValidRootPathString(pathString))) {\r\n throw new Error(errorPrefix(fnName, argumentNumber, false) +\r\n 'must be a valid firebase URL and ' +\r\n 'the path can\\'t contain \".\", \"#\", \"$\", \"[\", or \"]\".');\r\n }\r\n};\r\nvar validateBoolean = function (fnName, argumentNumber, bool, optional) {\r\n if (optional && bool === undefined)\r\n return;\r\n if (typeof bool !== 'boolean')\r\n throw new Error(errorPrefix(fnName, argumentNumber, optional) + 'must be a boolean.');\r\n};\n\n/**\r\n * @license\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 */\r\n/**\r\n * @constructor\r\n */\r\nvar OnDisconnect = /** @class */ (function () {\r\n /**\r\n * @param {!Repo} repo_\r\n * @param {!Path} path_\r\n */\r\n function OnDisconnect(repo_, path_) {\r\n this.repo_ = repo_;\r\n this.path_ = path_;\r\n }\r\n /**\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\r\n OnDisconnect.prototype.cancel = function (onComplete) {\r\n validateArgCount('OnDisconnect.cancel', 0, 1, arguments.length);\r\n validateCallback('OnDisconnect.cancel', 1, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo_.onDisconnectCancel(this.path_, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\r\n OnDisconnect.prototype.remove = function (onComplete) {\r\n validateArgCount('OnDisconnect.remove', 0, 1, arguments.length);\r\n validateWritablePath('OnDisconnect.remove', this.path_);\r\n validateCallback('OnDisconnect.remove', 1, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo_.onDisconnectSet(this.path_, null, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {*} value\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\r\n OnDisconnect.prototype.set = function (value, onComplete) {\r\n validateArgCount('OnDisconnect.set', 1, 2, arguments.length);\r\n validateWritablePath('OnDisconnect.set', this.path_);\r\n validateFirebaseDataArg('OnDisconnect.set', 1, value, this.path_, false);\r\n validateCallback('OnDisconnect.set', 2, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo_.onDisconnectSet(this.path_, value, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\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 */\r\n OnDisconnect.prototype.setWithPriority = function (value, priority, onComplete) {\r\n validateArgCount('OnDisconnect.setWithPriority', 2, 3, arguments.length);\r\n validateWritablePath('OnDisconnect.setWithPriority', this.path_);\r\n validateFirebaseDataArg('OnDisconnect.setWithPriority', 1, value, this.path_, false);\r\n validatePriority('OnDisconnect.setWithPriority', 2, priority, false);\r\n validateCallback('OnDisconnect.setWithPriority', 3, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo_.onDisconnectSetWithPriority(this.path_, value, priority, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {!Object} objectToMerge\r\n * @param {function(?Error)=} onComplete\r\n * @return {!firebase.Promise}\r\n */\r\n OnDisconnect.prototype.update = function (objectToMerge, onComplete) {\r\n validateArgCount('OnDisconnect.update', 1, 2, arguments.length);\r\n validateWritablePath('OnDisconnect.update', this.path_);\r\n if (Array.isArray(objectToMerge)) {\r\n var newObjectToMerge = {};\r\n for (var i = 0; i < objectToMerge.length; ++i) {\r\n newObjectToMerge['' + i] = objectToMerge[i];\r\n }\r\n objectToMerge = newObjectToMerge;\r\n warn('Passing an Array to firebase.database.onDisconnect().update() is deprecated. Use set() if you want to overwrite the ' +\r\n 'existing data, or an Object with integer keys if you really do want to only update some of the children.');\r\n }\r\n validateFirebaseMergeDataArg('OnDisconnect.update', 1, objectToMerge, this.path_, false);\r\n validateCallback('OnDisconnect.update', 2, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo_.onDisconnectUpdate(this.path_, objectToMerge, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n return OnDisconnect;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar TransactionResult = /** @class */ (function () {\r\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 */\r\n function TransactionResult(committed, snapshot) {\r\n this.committed = committed;\r\n this.snapshot = snapshot;\r\n }\r\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\r\n // for end-users\r\n TransactionResult.prototype.toJSON = function () {\r\n validateArgCount('TransactionResult.toJSON', 0, 1, arguments.length);\r\n return { committed: this.committed, snapshot: this.snapshot.toJSON() };\r\n };\r\n return TransactionResult;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar nextPushId = (function () {\r\n // Modeled after base64 web-safe chars, but ordered by ASCII.\r\n var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';\r\n // Timestamp of last push, used to prevent local collisions if you push twice\r\n // in one ms.\r\n var lastPushTime = 0;\r\n // We generate 72-bits of randomness which get turned into 12 characters and\r\n // appended to the timestamp to prevent collisions with other clients. We\r\n // store the last characters we generated because in the event of a collision,\r\n // we'll use those same characters except \"incremented\" by one.\r\n var lastRandChars = [];\r\n return function (now) {\r\n var duplicateTime = now === lastPushTime;\r\n lastPushTime = now;\r\n var i;\r\n var timeStampChars = new Array(8);\r\n for (i = 7; i >= 0; i--) {\r\n timeStampChars[i] = PUSH_CHARS.charAt(now % 64);\r\n // NOTE: Can't use << here because javascript will convert to int and lose\r\n // the upper bits.\r\n now = Math.floor(now / 64);\r\n }\r\n assert(now === 0, 'Cannot push at time == 0');\r\n var id = timeStampChars.join('');\r\n if (!duplicateTime) {\r\n for (i = 0; i < 12; i++) {\r\n lastRandChars[i] = Math.floor(Math.random() * 64);\r\n }\r\n }\r\n else {\r\n // If the timestamp hasn't changed since last push, use the same random\r\n // number, except incremented by 1.\r\n for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {\r\n lastRandChars[i] = 0;\r\n }\r\n lastRandChars[i]++;\r\n }\r\n for (i = 0; i < 12; i++) {\r\n id += PUSH_CHARS.charAt(lastRandChars[i]);\r\n }\r\n assert(id.length === 20, 'nextPushId: Length should be 20.');\r\n return id;\r\n };\r\n})();\n\n/**\r\n * @license\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 */\r\n/**\r\n *\r\n * @param {!string} name\r\n * @param {!Node} node\r\n * @constructor\r\n * @struct\r\n */\r\nvar NamedNode = /** @class */ (function () {\r\n function NamedNode(name, node) {\r\n this.name = name;\r\n this.node = node;\r\n }\r\n /**\r\n *\r\n * @param {!string} name\r\n * @param {!Node} node\r\n * @return {NamedNode}\r\n */\r\n NamedNode.Wrap = function (name, node) {\r\n return new NamedNode(name, node);\r\n };\r\n return NamedNode;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n *\r\n * @constructor\r\n */\r\nvar Index = /** @class */ (function () {\r\n function Index() {\r\n }\r\n /**\r\n * @return {function(!NamedNode, !NamedNode):number} A standalone comparison function for\r\n * this index\r\n */\r\n Index.prototype.getCompare = function () {\r\n return this.compare.bind(this);\r\n };\r\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 */\r\n Index.prototype.indexedValueChanged = function (oldNode, newNode) {\r\n var oldWrapped = new NamedNode(MIN_NAME, oldNode);\r\n var newWrapped = new NamedNode(MIN_NAME, newNode);\r\n return this.compare(oldWrapped, newWrapped) !== 0;\r\n };\r\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 */\r\n Index.prototype.minPost = function () {\r\n return NamedNode.MIN;\r\n };\r\n return Index;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar __EMPTY_NODE;\r\nvar KeyIndex = /** @class */ (function (_super) {\r\n __extends(KeyIndex, _super);\r\n function KeyIndex() {\r\n return _super !== null && _super.apply(this, arguments) || this;\r\n }\r\n Object.defineProperty(KeyIndex, \"__EMPTY_NODE\", {\r\n get: function () {\r\n return __EMPTY_NODE;\r\n },\r\n set: function (val) {\r\n __EMPTY_NODE = val;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @inheritDoc\r\n */\r\n KeyIndex.prototype.compare = function (a, b) {\r\n return nameCompare(a.name, b.name);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n KeyIndex.prototype.isDefinedOn = function (node) {\r\n // We could probably return true here (since every node has a key), but it's never called\r\n // so just leaving unimplemented for now.\r\n throw assertionError('KeyIndex.isDefinedOn not expected to be called.');\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n KeyIndex.prototype.indexedValueChanged = function (oldNode, newNode) {\r\n return false; // The key for a node never changes.\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n KeyIndex.prototype.minPost = function () {\r\n return NamedNode.MIN;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n KeyIndex.prototype.maxPost = function () {\r\n // TODO: This should really be created once and cached in a static property, but\r\n // NamedNode isn't defined yet, so I can't use it in a static. Bleh.\r\n return new NamedNode(MAX_NAME, __EMPTY_NODE);\r\n };\r\n /**\r\n * @param {*} indexValue\r\n * @param {string} name\r\n * @return {!NamedNode}\r\n */\r\n KeyIndex.prototype.makePost = function (indexValue, name) {\r\n assert(typeof indexValue === 'string', 'KeyIndex indexValue must always be a string.');\r\n // We just use empty node, but it'll never be compared, since our comparator only looks at name.\r\n return new NamedNode(indexValue, __EMPTY_NODE);\r\n };\r\n /**\r\n * @return {!string} String representation for inclusion in a query spec\r\n */\r\n KeyIndex.prototype.toString = function () {\r\n return '.key';\r\n };\r\n return KeyIndex;\r\n}(Index));\r\nvar KEY_INDEX = new KeyIndex();\n\n/**\r\n * @license\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 */\r\nvar MAX_NODE;\r\nfunction setMaxNode(val) {\r\n MAX_NODE = val;\r\n}\r\n/**\r\n * @param {(!string|!number)} priority\r\n * @return {!string}\r\n */\r\nvar priorityHashText = function (priority) {\r\n if (typeof priority === 'number')\r\n return 'number:' + doubleToIEEE754String(priority);\r\n else\r\n return 'string:' + priority;\r\n};\r\n/**\r\n * Validates that a priority snapshot Node is valid.\r\n *\r\n * @param {!Node} priorityNode\r\n */\r\nvar validatePriorityNode = function (priorityNode) {\r\n if (priorityNode.isLeafNode()) {\r\n var val = priorityNode.val();\r\n assert(typeof val === 'string' ||\r\n typeof val === 'number' ||\r\n (typeof val === 'object' && contains(val, '.sv')), 'Priority must be a string or number.');\r\n }\r\n else {\r\n assert(priorityNode === MAX_NODE || priorityNode.isEmpty(), 'priority of unexpected type.');\r\n }\r\n // Don't call getPriority() on MAX_NODE to avoid hitting assertion.\r\n assert(priorityNode === MAX_NODE || priorityNode.getPriority().isEmpty(), \"Priority nodes can't have a priority of their own.\");\r\n};\n\n/**\r\n * @license\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 */\r\nvar __childrenNodeConstructor;\r\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 */\r\nvar LeafNode = /** @class */ (function () {\r\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 */\r\n function LeafNode(value_, priorityNode_) {\r\n if (priorityNode_ === void 0) { priorityNode_ = LeafNode.__childrenNodeConstructor.EMPTY_NODE; }\r\n this.value_ = value_;\r\n this.priorityNode_ = priorityNode_;\r\n this.lazyHash_ = null;\r\n assert(this.value_ !== undefined && this.value_ !== null, \"LeafNode shouldn't be created with null/undefined value.\");\r\n validatePriorityNode(this.priorityNode_);\r\n }\r\n Object.defineProperty(LeafNode, \"__childrenNodeConstructor\", {\r\n get: function () {\r\n return __childrenNodeConstructor;\r\n },\r\n set: function (val) {\r\n __childrenNodeConstructor = val;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /** @inheritDoc */\r\n LeafNode.prototype.isLeafNode = function () {\r\n return true;\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.getPriority = function () {\r\n return this.priorityNode_;\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.updatePriority = function (newPriorityNode) {\r\n return new LeafNode(this.value_, newPriorityNode);\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.getImmediateChild = function (childName) {\r\n // Hack to treat priority as a regular child\r\n if (childName === '.priority') {\r\n return this.priorityNode_;\r\n }\r\n else {\r\n return LeafNode.__childrenNodeConstructor.EMPTY_NODE;\r\n }\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.getChild = function (path) {\r\n if (path.isEmpty()) {\r\n return this;\r\n }\r\n else if (path.getFront() === '.priority') {\r\n return this.priorityNode_;\r\n }\r\n else {\r\n return LeafNode.__childrenNodeConstructor.EMPTY_NODE;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LeafNode.prototype.hasChild = function () {\r\n return false;\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.getPredecessorChildName = function (childName, childNode) {\r\n return null;\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.updateImmediateChild = function (childName, newChildNode) {\r\n if (childName === '.priority') {\r\n return this.updatePriority(newChildNode);\r\n }\r\n else if (newChildNode.isEmpty() && childName !== '.priority') {\r\n return this;\r\n }\r\n else {\r\n return LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateImmediateChild(childName, newChildNode).updatePriority(this.priorityNode_);\r\n }\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.updateChild = function (path, newChildNode) {\r\n var front = path.getFront();\r\n if (front === null) {\r\n return newChildNode;\r\n }\r\n else if (newChildNode.isEmpty() && front !== '.priority') {\r\n return this;\r\n }\r\n else {\r\n assert(front !== '.priority' || path.getLength() === 1, '.priority must be the last token in a path');\r\n return this.updateImmediateChild(front, LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(path.popFront(), newChildNode));\r\n }\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.isEmpty = function () {\r\n return false;\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.numChildren = function () {\r\n return 0;\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.forEachChild = function (index, action) {\r\n return false;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LeafNode.prototype.val = function (exportFormat) {\r\n if (exportFormat && !this.getPriority().isEmpty())\r\n return {\r\n '.value': this.getValue(),\r\n '.priority': this.getPriority().val()\r\n };\r\n else\r\n return this.getValue();\r\n };\r\n /** @inheritDoc */\r\n LeafNode.prototype.hash = function () {\r\n if (this.lazyHash_ === null) {\r\n var toHash = '';\r\n if (!this.priorityNode_.isEmpty())\r\n toHash +=\r\n 'priority:' +\r\n priorityHashText(this.priorityNode_.val()) +\r\n ':';\r\n var type = typeof this.value_;\r\n toHash += type + ':';\r\n if (type === 'number') {\r\n toHash += doubleToIEEE754String(this.value_);\r\n }\r\n else {\r\n toHash += this.value_;\r\n }\r\n this.lazyHash_ = sha1(toHash);\r\n }\r\n return this.lazyHash_;\r\n };\r\n /**\r\n * Returns the value of the leaf node.\r\n * @return {Object|string|number|boolean} The value of the node.\r\n */\r\n LeafNode.prototype.getValue = function () {\r\n return this.value_;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LeafNode.prototype.compareTo = function (other) {\r\n if (other === LeafNode.__childrenNodeConstructor.EMPTY_NODE) {\r\n return 1;\r\n }\r\n else if (other instanceof LeafNode.__childrenNodeConstructor) {\r\n return -1;\r\n }\r\n else {\r\n assert(other.isLeafNode(), 'Unknown node type');\r\n return this.compareToLeafNode_(other);\r\n }\r\n };\r\n /**\r\n * Comparison specifically for two leaf nodes\r\n * @param {!LeafNode} otherLeaf\r\n * @return {!number}\r\n * @private\r\n */\r\n LeafNode.prototype.compareToLeafNode_ = function (otherLeaf) {\r\n var otherLeafType = typeof otherLeaf.value_;\r\n var thisLeafType = typeof this.value_;\r\n var otherIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(otherLeafType);\r\n var thisIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(thisLeafType);\r\n assert(otherIndex >= 0, 'Unknown leaf type: ' + otherLeafType);\r\n assert(thisIndex >= 0, 'Unknown leaf type: ' + thisLeafType);\r\n if (otherIndex === thisIndex) {\r\n // Same type, compare values\r\n if (thisLeafType === 'object') {\r\n // Deferred value nodes are all equal, but we should also never get to this point...\r\n return 0;\r\n }\r\n else {\r\n // Note that this works because true > false, all others are number or string comparisons\r\n if (this.value_ < otherLeaf.value_) {\r\n return -1;\r\n }\r\n else if (this.value_ === otherLeaf.value_) {\r\n return 0;\r\n }\r\n else {\r\n return 1;\r\n }\r\n }\r\n }\r\n else {\r\n return thisIndex - otherIndex;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LeafNode.prototype.withIndex = function () {\r\n return this;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LeafNode.prototype.isIndexed = function () {\r\n return true;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LeafNode.prototype.equals = function (other) {\r\n /**\r\n * @inheritDoc\r\n */\r\n if (other === this) {\r\n return true;\r\n }\r\n else if (other.isLeafNode()) {\r\n var otherLeaf = other;\r\n return (this.value_ === otherLeaf.value_ &&\r\n this.priorityNode_.equals(otherLeaf.priorityNode_));\r\n }\r\n else {\r\n return false;\r\n }\r\n };\r\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 */\r\n LeafNode.VALUE_TYPE_ORDER = ['object', 'boolean', 'number', 'string'];\r\n return LeafNode;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar nodeFromJSON;\r\nvar MAX_NODE$1;\r\nfunction setNodeFromJSON(val) {\r\n nodeFromJSON = val;\r\n}\r\nfunction setMaxNode$1(val) {\r\n MAX_NODE$1 = val;\r\n}\r\n/**\r\n * @constructor\r\n * @extends {Index}\r\n * @private\r\n */\r\nvar PriorityIndex = /** @class */ (function (_super) {\r\n __extends(PriorityIndex, _super);\r\n function PriorityIndex() {\r\n return _super !== null && _super.apply(this, arguments) || this;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n PriorityIndex.prototype.compare = function (a, b) {\r\n var aPriority = a.node.getPriority();\r\n var bPriority = b.node.getPriority();\r\n var indexCmp = aPriority.compareTo(bPriority);\r\n if (indexCmp === 0) {\r\n return nameCompare(a.name, b.name);\r\n }\r\n else {\r\n return indexCmp;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PriorityIndex.prototype.isDefinedOn = function (node) {\r\n return !node.getPriority().isEmpty();\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PriorityIndex.prototype.indexedValueChanged = function (oldNode, newNode) {\r\n return !oldNode.getPriority().equals(newNode.getPriority());\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PriorityIndex.prototype.minPost = function () {\r\n return NamedNode.MIN;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PriorityIndex.prototype.maxPost = function () {\r\n return new NamedNode(MAX_NAME, new LeafNode('[PRIORITY-POST]', MAX_NODE$1));\r\n };\r\n /**\r\n * @param {*} indexValue\r\n * @param {string} name\r\n * @return {!NamedNode}\r\n */\r\n PriorityIndex.prototype.makePost = function (indexValue, name) {\r\n var priorityNode = nodeFromJSON(indexValue);\r\n return new NamedNode(name, new LeafNode('[PRIORITY-POST]', priorityNode));\r\n };\r\n /**\r\n * @return {!string} String representation for inclusion in a query spec\r\n */\r\n PriorityIndex.prototype.toString = function () {\r\n return '.priority';\r\n };\r\n return PriorityIndex;\r\n}(Index));\r\nvar PRIORITY_INDEX = new PriorityIndex();\n\n/**\r\n * @license\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 */\r\n/**\r\n * An iterator over an LLRBNode.\r\n */\r\nvar SortedMapIterator = /** @class */ (function () {\r\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 */\r\n function SortedMapIterator(node, startKey, comparator, isReverse_, resultGenerator_) {\r\n if (resultGenerator_ === void 0) { resultGenerator_ = null; }\r\n this.isReverse_ = isReverse_;\r\n this.resultGenerator_ = resultGenerator_;\r\n /** @private\r\n * @type {Array.}\r\n */\r\n this.nodeStack_ = [];\r\n var cmp = 1;\r\n while (!node.isEmpty()) {\r\n node = node;\r\n cmp = startKey ? comparator(node.key, startKey) : 1;\r\n // flip the comparison if we're going in reverse\r\n if (isReverse_)\r\n cmp *= -1;\r\n if (cmp < 0) {\r\n // This node is less than our start key. ignore it\r\n if (this.isReverse_) {\r\n node = node.left;\r\n }\r\n else {\r\n node = node.right;\r\n }\r\n }\r\n else if (cmp === 0) {\r\n // This node is exactly equal to our start key. Push it on the stack, but stop iterating;\r\n this.nodeStack_.push(node);\r\n break;\r\n }\r\n else {\r\n // This node is greater than our start key, add it to the stack and move to the next one\r\n this.nodeStack_.push(node);\r\n if (this.isReverse_) {\r\n node = node.right;\r\n }\r\n else {\r\n node = node.left;\r\n }\r\n }\r\n }\r\n }\r\n SortedMapIterator.prototype.getNext = function () {\r\n if (this.nodeStack_.length === 0)\r\n return null;\r\n var node = this.nodeStack_.pop();\r\n var result;\r\n if (this.resultGenerator_)\r\n result = this.resultGenerator_(node.key, node.value);\r\n else\r\n result = { key: node.key, value: node.value };\r\n if (this.isReverse_) {\r\n node = node.left;\r\n while (!node.isEmpty()) {\r\n this.nodeStack_.push(node);\r\n node = node.right;\r\n }\r\n }\r\n else {\r\n node = node.right;\r\n while (!node.isEmpty()) {\r\n this.nodeStack_.push(node);\r\n node = node.left;\r\n }\r\n }\r\n return result;\r\n };\r\n SortedMapIterator.prototype.hasNext = function () {\r\n return this.nodeStack_.length > 0;\r\n };\r\n SortedMapIterator.prototype.peek = function () {\r\n if (this.nodeStack_.length === 0)\r\n return null;\r\n var node = this.nodeStack_[this.nodeStack_.length - 1];\r\n if (this.resultGenerator_) {\r\n return this.resultGenerator_(node.key, node.value);\r\n }\r\n else {\r\n return { key: node.key, value: node.value };\r\n }\r\n };\r\n return SortedMapIterator;\r\n}());\r\n/**\r\n * Represents a node in a Left-leaning Red-Black tree.\r\n */\r\nvar LLRBNode = /** @class */ (function () {\r\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 */\r\n function LLRBNode(key, value, color, left, right) {\r\n this.key = key;\r\n this.value = value;\r\n this.color = color != null ? color : LLRBNode.RED;\r\n this.left =\r\n left != null ? left : SortedMap.EMPTY_NODE;\r\n this.right =\r\n right != null ? right : SortedMap.EMPTY_NODE;\r\n }\r\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 */\r\n LLRBNode.prototype.copy = function (key, value, color, left, right) {\r\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);\r\n };\r\n /**\r\n * @return {number} The total number of nodes in the tree.\r\n */\r\n LLRBNode.prototype.count = function () {\r\n return this.left.count() + 1 + this.right.count();\r\n };\r\n /**\r\n * @return {boolean} True if the tree is empty.\r\n */\r\n LLRBNode.prototype.isEmpty = function () {\r\n return false;\r\n };\r\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 */\r\n LLRBNode.prototype.inorderTraversal = function (action) {\r\n return (this.left.inorderTraversal(action) ||\r\n action(this.key, this.value) ||\r\n this.right.inorderTraversal(action));\r\n };\r\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 */\r\n LLRBNode.prototype.reverseTraversal = function (action) {\r\n return (this.right.reverseTraversal(action) ||\r\n action(this.key, this.value) ||\r\n this.left.reverseTraversal(action));\r\n };\r\n /**\r\n * @return {!Object} The minimum node in the tree.\r\n * @private\r\n */\r\n LLRBNode.prototype.min_ = function () {\r\n if (this.left.isEmpty()) {\r\n return this;\r\n }\r\n else {\r\n return this.left.min_();\r\n }\r\n };\r\n /**\r\n * @return {!K} The maximum key in the tree.\r\n */\r\n LLRBNode.prototype.minKey = function () {\r\n return this.min_().key;\r\n };\r\n /**\r\n * @return {!K} The maximum key in the tree.\r\n */\r\n LLRBNode.prototype.maxKey = function () {\r\n if (this.right.isEmpty()) {\r\n return this.key;\r\n }\r\n else {\r\n return this.right.maxKey();\r\n }\r\n };\r\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 */\r\n LLRBNode.prototype.insert = function (key, value, comparator) {\r\n var cmp, n;\r\n n = this;\r\n cmp = comparator(key, n.key);\r\n if (cmp < 0) {\r\n n = n.copy(null, null, null, n.left.insert(key, value, comparator), null);\r\n }\r\n else if (cmp === 0) {\r\n n = n.copy(null, value, null, null, null);\r\n }\r\n else {\r\n n = n.copy(null, null, null, null, n.right.insert(key, value, comparator));\r\n }\r\n return n.fixUp_();\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode|LLRBEmptyNode} New tree, with the minimum key removed.\r\n */\r\n LLRBNode.prototype.removeMin_ = function () {\r\n if (this.left.isEmpty()) {\r\n return SortedMap.EMPTY_NODE;\r\n }\r\n var n = this;\r\n if (!n.left.isRed_() && !n.left.left.isRed_())\r\n n = n.moveRedLeft_();\r\n n = n.copy(null, null, null, n.left.removeMin_(), null);\r\n return n.fixUp_();\r\n };\r\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 */\r\n LLRBNode.prototype.remove = function (key, comparator) {\r\n var n, smallest;\r\n n = this;\r\n if (comparator(key, n.key) < 0) {\r\n if (!n.left.isEmpty() && !n.left.isRed_() && !n.left.left.isRed_()) {\r\n n = n.moveRedLeft_();\r\n }\r\n n = n.copy(null, null, null, n.left.remove(key, comparator), null);\r\n }\r\n else {\r\n if (n.left.isRed_())\r\n n = n.rotateRight_();\r\n if (!n.right.isEmpty() && !n.right.isRed_() && !n.right.left.isRed_()) {\r\n n = n.moveRedRight_();\r\n }\r\n if (comparator(key, n.key) === 0) {\r\n if (n.right.isEmpty()) {\r\n return SortedMap.EMPTY_NODE;\r\n }\r\n else {\r\n smallest = n.right.min_();\r\n n = n.copy(smallest.key, smallest.value, null, null, n.right.removeMin_());\r\n }\r\n }\r\n n = n.copy(null, null, null, null, n.right.remove(key, comparator));\r\n }\r\n return n.fixUp_();\r\n };\r\n /**\r\n * @private\r\n * @return {boolean} Whether this is a RED node.\r\n */\r\n LLRBNode.prototype.isRed_ = function () {\r\n return this.color;\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree after performing any needed rotations.\r\n */\r\n LLRBNode.prototype.fixUp_ = function () {\r\n var n = this;\r\n if (n.right.isRed_() && !n.left.isRed_())\r\n n = n.rotateLeft_();\r\n if (n.left.isRed_() && n.left.left.isRed_())\r\n n = n.rotateRight_();\r\n if (n.left.isRed_() && n.right.isRed_())\r\n n = n.colorFlip_();\r\n return n;\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after moveRedLeft.\r\n */\r\n LLRBNode.prototype.moveRedLeft_ = function () {\r\n var n = this.colorFlip_();\r\n if (n.right.left.isRed_()) {\r\n n = n.copy(null, null, null, null, n.right.rotateRight_());\r\n n = n.rotateLeft_();\r\n n = n.colorFlip_();\r\n }\r\n return n;\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after moveRedRight.\r\n */\r\n LLRBNode.prototype.moveRedRight_ = function () {\r\n var n = this.colorFlip_();\r\n if (n.left.left.isRed_()) {\r\n n = n.rotateRight_();\r\n n = n.colorFlip_();\r\n }\r\n return n;\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after rotateLeft.\r\n */\r\n LLRBNode.prototype.rotateLeft_ = function () {\r\n var nl = this.copy(null, null, LLRBNode.RED, null, this.right.left);\r\n return this.right.copy(null, null, this.color, nl, null);\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after rotateRight.\r\n */\r\n LLRBNode.prototype.rotateRight_ = function () {\r\n var nr = this.copy(null, null, LLRBNode.RED, this.left.right, null);\r\n return this.left.copy(null, null, this.color, null, nr);\r\n };\r\n /**\r\n * @private\r\n * @return {!LLRBNode} New tree, after colorFlip.\r\n */\r\n LLRBNode.prototype.colorFlip_ = function () {\r\n var left = this.left.copy(null, null, !this.left.color, null, null);\r\n var right = this.right.copy(null, null, !this.right.color, null, null);\r\n return this.copy(null, null, !this.color, left, right);\r\n };\r\n /**\r\n * For testing.\r\n *\r\n * @private\r\n * @return {boolean} True if all is well.\r\n */\r\n LLRBNode.prototype.checkMaxDepth_ = function () {\r\n var blackDepth = this.check_();\r\n return Math.pow(2.0, blackDepth) <= this.count() + 1;\r\n };\r\n /**\r\n * @private\r\n * @return {number} Not sure what this returns exactly. :-).\r\n */\r\n LLRBNode.prototype.check_ = function () {\r\n var blackDepth;\r\n if (this.isRed_() && this.left.isRed_()) {\r\n throw new Error('Red node has red child(' + this.key + ',' + this.value + ')');\r\n }\r\n if (this.right.isRed_()) {\r\n throw new Error('Right child of (' + this.key + ',' + this.value + ') is red');\r\n }\r\n blackDepth = this.left.check_();\r\n if (blackDepth !== this.right.check_()) {\r\n throw new Error('Black depths differ');\r\n }\r\n else {\r\n return blackDepth + (this.isRed_() ? 0 : 1);\r\n }\r\n };\r\n LLRBNode.RED = true;\r\n LLRBNode.BLACK = false;\r\n return LLRBNode;\r\n}());\r\n/**\r\n * Represents an empty node (a leaf node in the Red-Black Tree).\r\n */\r\nvar LLRBEmptyNode = /** @class */ (function () {\r\n function LLRBEmptyNode() {\r\n }\r\n /**\r\n * Returns a copy of the current node.\r\n *\r\n * @return {!LLRBEmptyNode} The node copy.\r\n */\r\n LLRBEmptyNode.prototype.copy = function (key, value, color, left, right) {\r\n return this;\r\n };\r\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 */\r\n LLRBEmptyNode.prototype.insert = function (key, value, comparator) {\r\n return new LLRBNode(key, value, null);\r\n };\r\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 */\r\n LLRBEmptyNode.prototype.remove = function (key, comparator) {\r\n return this;\r\n };\r\n /**\r\n * @return {number} The total number of nodes in the tree.\r\n */\r\n LLRBEmptyNode.prototype.count = function () {\r\n return 0;\r\n };\r\n /**\r\n * @return {boolean} True if the tree is empty.\r\n */\r\n LLRBEmptyNode.prototype.isEmpty = function () {\r\n return true;\r\n };\r\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 */\r\n LLRBEmptyNode.prototype.inorderTraversal = function (action) {\r\n return false;\r\n };\r\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 */\r\n LLRBEmptyNode.prototype.reverseTraversal = function (action) {\r\n return false;\r\n };\r\n /**\r\n * @return {null}\r\n */\r\n LLRBEmptyNode.prototype.minKey = function () {\r\n return null;\r\n };\r\n /**\r\n * @return {null}\r\n */\r\n LLRBEmptyNode.prototype.maxKey = function () {\r\n return null;\r\n };\r\n /**\r\n * @private\r\n * @return {number} Not sure what this returns exactly. :-).\r\n */\r\n LLRBEmptyNode.prototype.check_ = function () {\r\n return 0;\r\n };\r\n /**\r\n * @private\r\n * @return {boolean} Whether this node is red.\r\n */\r\n LLRBEmptyNode.prototype.isRed_ = function () {\r\n return false;\r\n };\r\n return LLRBEmptyNode;\r\n}());\r\n/**\r\n * An immutable sorted map implementation, based on a Left-leaning Red-Black\r\n * tree.\r\n */\r\nvar SortedMap = /** @class */ (function () {\r\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 */\r\n function SortedMap(comparator_, root_) {\r\n if (root_ === void 0) { root_ = SortedMap.EMPTY_NODE; }\r\n this.comparator_ = comparator_;\r\n this.root_ = root_;\r\n }\r\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 */\r\n SortedMap.prototype.insert = function (key, value) {\r\n return new SortedMap(this.comparator_, this.root_\r\n .insert(key, value, this.comparator_)\r\n .copy(null, null, LLRBNode.BLACK, null, null));\r\n };\r\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 */\r\n SortedMap.prototype.remove = function (key) {\r\n return new SortedMap(this.comparator_, this.root_\r\n .remove(key, this.comparator_)\r\n .copy(null, null, LLRBNode.BLACK, null, null));\r\n };\r\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 */\r\n SortedMap.prototype.get = function (key) {\r\n var cmp;\r\n var node = this.root_;\r\n while (!node.isEmpty()) {\r\n cmp = this.comparator_(key, node.key);\r\n if (cmp === 0) {\r\n return node.value;\r\n }\r\n else if (cmp < 0) {\r\n node = node.left;\r\n }\r\n else if (cmp > 0) {\r\n node = node.right;\r\n }\r\n }\r\n return null;\r\n };\r\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 */\r\n SortedMap.prototype.getPredecessorKey = function (key) {\r\n var cmp, node = this.root_, rightParent = null;\r\n while (!node.isEmpty()) {\r\n cmp = this.comparator_(key, node.key);\r\n if (cmp === 0) {\r\n if (!node.left.isEmpty()) {\r\n node = node.left;\r\n while (!node.right.isEmpty())\r\n node = node.right;\r\n return node.key;\r\n }\r\n else if (rightParent) {\r\n return rightParent.key;\r\n }\r\n else {\r\n return null; // first item.\r\n }\r\n }\r\n else if (cmp < 0) {\r\n node = node.left;\r\n }\r\n else if (cmp > 0) {\r\n rightParent = node;\r\n node = node.right;\r\n }\r\n }\r\n throw new Error('Attempted to find predecessor key for a nonexistent key. What gives?');\r\n };\r\n /**\r\n * @return {boolean} True if the map is empty.\r\n */\r\n SortedMap.prototype.isEmpty = function () {\r\n return this.root_.isEmpty();\r\n };\r\n /**\r\n * @return {number} The total number of nodes in the map.\r\n */\r\n SortedMap.prototype.count = function () {\r\n return this.root_.count();\r\n };\r\n /**\r\n * @return {?K} The minimum key in the map.\r\n */\r\n SortedMap.prototype.minKey = function () {\r\n return this.root_.minKey();\r\n };\r\n /**\r\n * @return {?K} The maximum key in the map.\r\n */\r\n SortedMap.prototype.maxKey = function () {\r\n return this.root_.maxKey();\r\n };\r\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 */\r\n SortedMap.prototype.inorderTraversal = function (action) {\r\n return this.root_.inorderTraversal(action);\r\n };\r\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 */\r\n SortedMap.prototype.reverseTraversal = function (action) {\r\n return this.root_.reverseTraversal(action);\r\n };\r\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 */\r\n SortedMap.prototype.getIterator = function (resultGenerator) {\r\n return new SortedMapIterator(this.root_, null, this.comparator_, false, resultGenerator);\r\n };\r\n SortedMap.prototype.getIteratorFrom = function (key, resultGenerator) {\r\n return new SortedMapIterator(this.root_, key, this.comparator_, false, resultGenerator);\r\n };\r\n SortedMap.prototype.getReverseIteratorFrom = function (key, resultGenerator) {\r\n return new SortedMapIterator(this.root_, key, this.comparator_, true, resultGenerator);\r\n };\r\n SortedMap.prototype.getReverseIterator = function (resultGenerator) {\r\n return new SortedMapIterator(this.root_, null, this.comparator_, true, resultGenerator);\r\n };\r\n /**\r\n * Always use the same empty node, to reduce memory.\r\n * @const\r\n */\r\n SortedMap.EMPTY_NODE = new LLRBEmptyNode();\r\n return SortedMap;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar LOG_2 = Math.log(2);\r\n/**\r\n * @constructor\r\n */\r\nvar Base12Num = /** @class */ (function () {\r\n /**\r\n * @param {number} length\r\n */\r\n function Base12Num(length) {\r\n var logBase2 = function (num) {\r\n return parseInt((Math.log(num) / LOG_2), 10);\r\n };\r\n var bitMask = function (bits) { return parseInt(Array(bits + 1).join('1'), 2); };\r\n this.count = logBase2(length + 1);\r\n this.current_ = this.count - 1;\r\n var mask = bitMask(this.count);\r\n this.bits_ = (length + 1) & mask;\r\n }\r\n /**\r\n * @return {boolean}\r\n */\r\n Base12Num.prototype.nextBitIsOne = function () {\r\n //noinspection JSBitwiseOperatorUsage\r\n var result = !(this.bits_ & (0x1 << this.current_));\r\n this.current_--;\r\n return result;\r\n };\r\n return Base12Num;\r\n}());\r\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 */\r\nvar buildChildSet = function (childList, cmp, keyFn, mapSortFn) {\r\n childList.sort(cmp);\r\n var buildBalancedTree = function (low, high) {\r\n var length = high - low;\r\n var namedNode;\r\n var key;\r\n if (length == 0) {\r\n return null;\r\n }\r\n else if (length == 1) {\r\n namedNode = childList[low];\r\n key = keyFn ? keyFn(namedNode) : namedNode;\r\n return new LLRBNode(key, namedNode.node, LLRBNode.BLACK, null, null);\r\n }\r\n else {\r\n var middle = parseInt((length / 2), 10) + low;\r\n var left = buildBalancedTree(low, middle);\r\n var right = buildBalancedTree(middle + 1, high);\r\n namedNode = childList[middle];\r\n key = keyFn ? keyFn(namedNode) : namedNode;\r\n return new LLRBNode(key, namedNode.node, LLRBNode.BLACK, left, right);\r\n }\r\n };\r\n var buildFrom12Array = function (base12) {\r\n var node = null;\r\n var root = null;\r\n var index = childList.length;\r\n var buildPennant = function (chunkSize, color) {\r\n var low = index - chunkSize;\r\n var high = index;\r\n index -= chunkSize;\r\n var childTree = buildBalancedTree(low + 1, high);\r\n var namedNode = childList[low];\r\n var key = keyFn ? keyFn(namedNode) : namedNode;\r\n attachPennant(new LLRBNode(key, namedNode.node, color, null, childTree));\r\n };\r\n var attachPennant = function (pennant) {\r\n if (node) {\r\n node.left = pennant;\r\n node = pennant;\r\n }\r\n else {\r\n root = pennant;\r\n node = pennant;\r\n }\r\n };\r\n for (var i = 0; i < base12.count; ++i) {\r\n var isOne = base12.nextBitIsOne();\r\n // The number of nodes taken in each slice is 2^(arr.length - (i + 1))\r\n var chunkSize = Math.pow(2, base12.count - (i + 1));\r\n if (isOne) {\r\n buildPennant(chunkSize, LLRBNode.BLACK);\r\n }\r\n else {\r\n // current == 2\r\n buildPennant(chunkSize, LLRBNode.BLACK);\r\n buildPennant(chunkSize, LLRBNode.RED);\r\n }\r\n }\r\n return root;\r\n };\r\n var base12 = new Base12Num(childList.length);\r\n var root = buildFrom12Array(base12);\r\n return new SortedMap(mapSortFn || cmp, root);\r\n};\n\n/**\r\n * @license\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 */\r\nvar _defaultIndexMap;\r\nvar fallbackObject = {};\r\n/**\r\n *\r\n * @param {Object.>} indexes\r\n * @param {Object.} indexSet\r\n * @constructor\r\n */\r\nvar IndexMap = /** @class */ (function () {\r\n function IndexMap(indexes_, indexSet_) {\r\n this.indexes_ = indexes_;\r\n this.indexSet_ = indexSet_;\r\n }\r\n Object.defineProperty(IndexMap, \"Default\", {\r\n /**\r\n * The default IndexMap for nodes without a priority\r\n * @type {!IndexMap}\r\n * @const\r\n */\r\n get: function () {\r\n assert(fallbackObject && PRIORITY_INDEX, 'ChildrenNode.ts has not been loaded');\r\n _defaultIndexMap =\r\n _defaultIndexMap ||\r\n new IndexMap({ '.priority': fallbackObject }, { '.priority': PRIORITY_INDEX });\r\n return _defaultIndexMap;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n *\r\n * @param {!string} indexKey\r\n * @return {?SortedMap.}\r\n */\r\n IndexMap.prototype.get = function (indexKey) {\r\n var sortedMap = safeGet(this.indexes_, indexKey);\r\n if (!sortedMap)\r\n throw new Error('No index defined for ' + indexKey);\r\n if (sortedMap === fallbackObject) {\r\n // The index exists, but it falls back to just name comparison. Return null so that the calling code uses the\r\n // regular child map\r\n return null;\r\n }\r\n else {\r\n return sortedMap;\r\n }\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {boolean}\r\n */\r\n IndexMap.prototype.hasIndex = function (indexDefinition) {\r\n return contains(this.indexSet_, indexDefinition.toString());\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @param {!SortedMap.} existingChildren\r\n * @return {!IndexMap}\r\n */\r\n IndexMap.prototype.addIndex = function (indexDefinition, existingChildren) {\r\n assert(indexDefinition !== KEY_INDEX, \"KeyIndex always exists and isn't meant to be added to the IndexMap.\");\r\n var childList = [];\r\n var sawIndexedValue = false;\r\n var iter = existingChildren.getIterator(NamedNode.Wrap);\r\n var next = iter.getNext();\r\n while (next) {\r\n sawIndexedValue =\r\n sawIndexedValue || indexDefinition.isDefinedOn(next.node);\r\n childList.push(next);\r\n next = iter.getNext();\r\n }\r\n var newIndex;\r\n if (sawIndexedValue) {\r\n newIndex = buildChildSet(childList, indexDefinition.getCompare());\r\n }\r\n else {\r\n newIndex = fallbackObject;\r\n }\r\n var indexName = indexDefinition.toString();\r\n var newIndexSet = clone(this.indexSet_);\r\n newIndexSet[indexName] = indexDefinition;\r\n var newIndexes = clone(this.indexes_);\r\n newIndexes[indexName] = newIndex;\r\n return new IndexMap(newIndexes, newIndexSet);\r\n };\r\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 */\r\n IndexMap.prototype.addToIndexes = function (namedNode, existingChildren) {\r\n var _this = this;\r\n var newIndexes = map(this.indexes_, function (indexedChildren, indexName) {\r\n var index = safeGet(_this.indexSet_, indexName);\r\n assert(index, 'Missing index implementation for ' + indexName);\r\n if (indexedChildren === fallbackObject) {\r\n // Check to see if we need to index everything\r\n if (index.isDefinedOn(namedNode.node)) {\r\n // We need to build this index\r\n var childList = [];\r\n var iter = existingChildren.getIterator(NamedNode.Wrap);\r\n var next = iter.getNext();\r\n while (next) {\r\n if (next.name != namedNode.name) {\r\n childList.push(next);\r\n }\r\n next = iter.getNext();\r\n }\r\n childList.push(namedNode);\r\n return buildChildSet(childList, index.getCompare());\r\n }\r\n else {\r\n // No change, this remains a fallback\r\n return fallbackObject;\r\n }\r\n }\r\n else {\r\n var existingSnap = existingChildren.get(namedNode.name);\r\n var newChildren = indexedChildren;\r\n if (existingSnap) {\r\n newChildren = newChildren.remove(new NamedNode(namedNode.name, existingSnap));\r\n }\r\n return newChildren.insert(namedNode, namedNode.node);\r\n }\r\n });\r\n return new IndexMap(newIndexes, this.indexSet_);\r\n };\r\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 */\r\n IndexMap.prototype.removeFromIndexes = function (namedNode, existingChildren) {\r\n var newIndexes = map(this.indexes_, function (indexedChildren) {\r\n if (indexedChildren === fallbackObject) {\r\n // This is the fallback. Just return it, nothing to do in this case\r\n return indexedChildren;\r\n }\r\n else {\r\n var existingSnap = existingChildren.get(namedNode.name);\r\n if (existingSnap) {\r\n return indexedChildren.remove(new NamedNode(namedNode.name, existingSnap));\r\n }\r\n else {\r\n // No record of this child\r\n return indexedChildren;\r\n }\r\n }\r\n });\r\n return new IndexMap(newIndexes, this.indexSet_);\r\n };\r\n return IndexMap;\r\n}());\n\n/**\r\n * @license\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 */\r\nfunction NAME_ONLY_COMPARATOR(left, right) {\r\n return nameCompare(left.name, right.name);\r\n}\r\nfunction NAME_COMPARATOR(left, right) {\r\n return nameCompare(left, right);\r\n}\n\n/**\r\n * @license\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 */\r\n// TODO: For memory savings, don't store priorityNode_ if it's empty.\r\nvar EMPTY_NODE;\r\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 */\r\nvar ChildrenNode = /** @class */ (function () {\r\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 */\r\n function ChildrenNode(children_, priorityNode_, indexMap_) {\r\n this.children_ = children_;\r\n this.priorityNode_ = priorityNode_;\r\n this.indexMap_ = indexMap_;\r\n this.lazyHash_ = null;\r\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 */\r\n if (this.priorityNode_) {\r\n validatePriorityNode(this.priorityNode_);\r\n }\r\n if (this.children_.isEmpty()) {\r\n assert(!this.priorityNode_ || this.priorityNode_.isEmpty(), 'An empty node cannot have a priority');\r\n }\r\n }\r\n Object.defineProperty(ChildrenNode, \"EMPTY_NODE\", {\r\n get: function () {\r\n return (EMPTY_NODE ||\r\n (EMPTY_NODE = new ChildrenNode(new SortedMap(NAME_COMPARATOR), null, IndexMap.Default)));\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.isLeafNode = function () {\r\n return false;\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.getPriority = function () {\r\n return this.priorityNode_ || EMPTY_NODE;\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.updatePriority = function (newPriorityNode) {\r\n if (this.children_.isEmpty()) {\r\n // Don't allow priorities on empty nodes\r\n return this;\r\n }\r\n else {\r\n return new ChildrenNode(this.children_, newPriorityNode, this.indexMap_);\r\n }\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.getImmediateChild = function (childName) {\r\n // Hack to treat priority as a regular child\r\n if (childName === '.priority') {\r\n return this.getPriority();\r\n }\r\n else {\r\n var child = this.children_.get(childName);\r\n return child === null ? EMPTY_NODE : child;\r\n }\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.getChild = function (path) {\r\n var front = path.getFront();\r\n if (front === null)\r\n return this;\r\n return this.getImmediateChild(front).getChild(path.popFront());\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.hasChild = function (childName) {\r\n return this.children_.get(childName) !== null;\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.updateImmediateChild = function (childName, newChildNode) {\r\n assert(newChildNode, 'We should always be passing snapshot nodes');\r\n if (childName === '.priority') {\r\n return this.updatePriority(newChildNode);\r\n }\r\n else {\r\n var namedNode = new NamedNode(childName, newChildNode);\r\n var newChildren = void 0, newIndexMap = void 0, newPriority = void 0;\r\n if (newChildNode.isEmpty()) {\r\n newChildren = this.children_.remove(childName);\r\n newIndexMap = this.indexMap_.removeFromIndexes(namedNode, this.children_);\r\n }\r\n else {\r\n newChildren = this.children_.insert(childName, newChildNode);\r\n newIndexMap = this.indexMap_.addToIndexes(namedNode, this.children_);\r\n }\r\n newPriority = newChildren.isEmpty() ? EMPTY_NODE : this.priorityNode_;\r\n return new ChildrenNode(newChildren, newPriority, newIndexMap);\r\n }\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.updateChild = function (path, newChildNode) {\r\n var front = path.getFront();\r\n if (front === null) {\r\n return newChildNode;\r\n }\r\n else {\r\n assert(path.getFront() !== '.priority' || path.getLength() === 1, '.priority must be the last token in a path');\r\n var newImmediateChild = this.getImmediateChild(front).updateChild(path.popFront(), newChildNode);\r\n return this.updateImmediateChild(front, newImmediateChild);\r\n }\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.isEmpty = function () {\r\n return this.children_.isEmpty();\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.numChildren = function () {\r\n return this.children_.count();\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.val = function (exportFormat) {\r\n if (this.isEmpty())\r\n return null;\r\n var obj = {};\r\n var numKeys = 0, maxKey = 0, allIntegerKeys = true;\r\n this.forEachChild(PRIORITY_INDEX, function (key, childNode) {\r\n obj[key] = childNode.val(exportFormat);\r\n numKeys++;\r\n if (allIntegerKeys && ChildrenNode.INTEGER_REGEXP_.test(key)) {\r\n maxKey = Math.max(maxKey, Number(key));\r\n }\r\n else {\r\n allIntegerKeys = false;\r\n }\r\n });\r\n if (!exportFormat && allIntegerKeys && maxKey < 2 * numKeys) {\r\n // convert to array.\r\n var array = [];\r\n for (var key in obj)\r\n array[key] = obj[key];\r\n return array;\r\n }\r\n else {\r\n if (exportFormat && !this.getPriority().isEmpty()) {\r\n obj['.priority'] = this.getPriority().val();\r\n }\r\n return obj;\r\n }\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.hash = function () {\r\n if (this.lazyHash_ === null) {\r\n var toHash_1 = '';\r\n if (!this.getPriority().isEmpty())\r\n toHash_1 +=\r\n 'priority:' +\r\n priorityHashText(this.getPriority().val()) +\r\n ':';\r\n this.forEachChild(PRIORITY_INDEX, function (key, childNode) {\r\n var childHash = childNode.hash();\r\n if (childHash !== '')\r\n toHash_1 += ':' + key + ':' + childHash;\r\n });\r\n this.lazyHash_ = toHash_1 === '' ? '' : sha1(toHash_1);\r\n }\r\n return this.lazyHash_;\r\n };\r\n /** @inheritDoc */\r\n ChildrenNode.prototype.getPredecessorChildName = function (childName, childNode, index) {\r\n var idx = this.resolveIndex_(index);\r\n if (idx) {\r\n var predecessor = idx.getPredecessorKey(new NamedNode(childName, childNode));\r\n return predecessor ? predecessor.name : null;\r\n }\r\n else {\r\n return this.children_.getPredecessorKey(childName);\r\n }\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {?string}\r\n */\r\n ChildrenNode.prototype.getFirstChildName = function (indexDefinition) {\r\n var idx = this.resolveIndex_(indexDefinition);\r\n if (idx) {\r\n var minKey = idx.minKey();\r\n return minKey && minKey.name;\r\n }\r\n else {\r\n return this.children_.minKey();\r\n }\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {?NamedNode}\r\n */\r\n ChildrenNode.prototype.getFirstChild = function (indexDefinition) {\r\n var minKey = this.getFirstChildName(indexDefinition);\r\n if (minKey) {\r\n return new NamedNode(minKey, this.children_.get(minKey));\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\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 */\r\n ChildrenNode.prototype.getLastChildName = function (indexDefinition) {\r\n var idx = this.resolveIndex_(indexDefinition);\r\n if (idx) {\r\n var maxKey = idx.maxKey();\r\n return maxKey && maxKey.name;\r\n }\r\n else {\r\n return this.children_.maxKey();\r\n }\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {?NamedNode}\r\n */\r\n ChildrenNode.prototype.getLastChild = function (indexDefinition) {\r\n var maxKey = this.getLastChildName(indexDefinition);\r\n if (maxKey) {\r\n return new NamedNode(maxKey, this.children_.get(maxKey));\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildrenNode.prototype.forEachChild = function (index, action) {\r\n var idx = this.resolveIndex_(index);\r\n if (idx) {\r\n return idx.inorderTraversal(function (wrappedNode) {\r\n return action(wrappedNode.name, wrappedNode.node);\r\n });\r\n }\r\n else {\r\n return this.children_.inorderTraversal(action);\r\n }\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {SortedMapIterator}\r\n */\r\n ChildrenNode.prototype.getIterator = function (indexDefinition) {\r\n return this.getIteratorFrom(indexDefinition.minPost(), indexDefinition);\r\n };\r\n /**\r\n *\r\n * @param {!NamedNode} startPost\r\n * @param {!Index} indexDefinition\r\n * @return {!SortedMapIterator}\r\n */\r\n ChildrenNode.prototype.getIteratorFrom = function (startPost, indexDefinition) {\r\n var idx = this.resolveIndex_(indexDefinition);\r\n if (idx) {\r\n return idx.getIteratorFrom(startPost, function (key) { return key; });\r\n }\r\n else {\r\n var iterator = this.children_.getIteratorFrom(startPost.name, NamedNode.Wrap);\r\n var next = iterator.peek();\r\n while (next != null && indexDefinition.compare(next, startPost) < 0) {\r\n iterator.getNext();\r\n next = iterator.peek();\r\n }\r\n return iterator;\r\n }\r\n };\r\n /**\r\n * @param {!Index} indexDefinition\r\n * @return {!SortedMapIterator}\r\n */\r\n ChildrenNode.prototype.getReverseIterator = function (indexDefinition) {\r\n return this.getReverseIteratorFrom(indexDefinition.maxPost(), indexDefinition);\r\n };\r\n /**\r\n * @param {!NamedNode} endPost\r\n * @param {!Index} indexDefinition\r\n * @return {!SortedMapIterator}\r\n */\r\n ChildrenNode.prototype.getReverseIteratorFrom = function (endPost, indexDefinition) {\r\n var idx = this.resolveIndex_(indexDefinition);\r\n if (idx) {\r\n return idx.getReverseIteratorFrom(endPost, function (key) {\r\n return key;\r\n });\r\n }\r\n else {\r\n var iterator = this.children_.getReverseIteratorFrom(endPost.name, NamedNode.Wrap);\r\n var next = iterator.peek();\r\n while (next != null && indexDefinition.compare(next, endPost) > 0) {\r\n iterator.getNext();\r\n next = iterator.peek();\r\n }\r\n return iterator;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildrenNode.prototype.compareTo = function (other) {\r\n if (this.isEmpty()) {\r\n if (other.isEmpty()) {\r\n return 0;\r\n }\r\n else {\r\n return -1;\r\n }\r\n }\r\n else if (other.isLeafNode() || other.isEmpty()) {\r\n return 1;\r\n }\r\n else if (other === MAX_NODE$2) {\r\n return -1;\r\n }\r\n else {\r\n // Must be another node with children.\r\n return 0;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildrenNode.prototype.withIndex = function (indexDefinition) {\r\n if (indexDefinition === KEY_INDEX ||\r\n this.indexMap_.hasIndex(indexDefinition)) {\r\n return this;\r\n }\r\n else {\r\n var newIndexMap = this.indexMap_.addIndex(indexDefinition, this.children_);\r\n return new ChildrenNode(this.children_, this.priorityNode_, newIndexMap);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildrenNode.prototype.isIndexed = function (index) {\r\n return index === KEY_INDEX || this.indexMap_.hasIndex(index);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildrenNode.prototype.equals = function (other) {\r\n if (other === this) {\r\n return true;\r\n }\r\n else if (other.isLeafNode()) {\r\n return false;\r\n }\r\n else {\r\n var otherChildrenNode = other;\r\n if (!this.getPriority().equals(otherChildrenNode.getPriority())) {\r\n return false;\r\n }\r\n else if (this.children_.count() === otherChildrenNode.children_.count()) {\r\n var thisIter = this.getIterator(PRIORITY_INDEX);\r\n var otherIter = otherChildrenNode.getIterator(PRIORITY_INDEX);\r\n var thisCurrent = thisIter.getNext();\r\n var otherCurrent = otherIter.getNext();\r\n while (thisCurrent && otherCurrent) {\r\n if (thisCurrent.name !== otherCurrent.name ||\r\n !thisCurrent.node.equals(otherCurrent.node)) {\r\n return false;\r\n }\r\n thisCurrent = thisIter.getNext();\r\n otherCurrent = otherIter.getNext();\r\n }\r\n return thisCurrent === null && otherCurrent === null;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n };\r\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 */\r\n ChildrenNode.prototype.resolveIndex_ = function (indexDefinition) {\r\n if (indexDefinition === KEY_INDEX) {\r\n return null;\r\n }\r\n else {\r\n return this.indexMap_.get(indexDefinition.toString());\r\n }\r\n };\r\n /**\r\n * @private\r\n * @type {RegExp}\r\n */\r\n ChildrenNode.INTEGER_REGEXP_ = /^(0|[1-9]\\d*)$/;\r\n return ChildrenNode;\r\n}());\r\n/**\r\n * @constructor\r\n * @extends {ChildrenNode}\r\n * @private\r\n */\r\nvar MaxNode = /** @class */ (function (_super) {\r\n __extends(MaxNode, _super);\r\n function MaxNode() {\r\n return _super.call(this, new SortedMap(NAME_COMPARATOR), ChildrenNode.EMPTY_NODE, IndexMap.Default) || this;\r\n }\r\n MaxNode.prototype.compareTo = function (other) {\r\n if (other === this) {\r\n return 0;\r\n }\r\n else {\r\n return 1;\r\n }\r\n };\r\n MaxNode.prototype.equals = function (other) {\r\n // Not that we every compare it, but MAX_NODE is only ever equal to itself\r\n return other === this;\r\n };\r\n MaxNode.prototype.getPriority = function () {\r\n return this;\r\n };\r\n MaxNode.prototype.getImmediateChild = function (childName) {\r\n return ChildrenNode.EMPTY_NODE;\r\n };\r\n MaxNode.prototype.isEmpty = function () {\r\n return false;\r\n };\r\n return MaxNode;\r\n}(ChildrenNode));\r\n/**\r\n * Marker that will sort higher than any other snapshot.\r\n * @type {!MAX_NODE}\r\n * @const\r\n */\r\nvar MAX_NODE$2 = new MaxNode();\r\nObject.defineProperties(NamedNode, {\r\n MIN: {\r\n value: new NamedNode(MIN_NAME, ChildrenNode.EMPTY_NODE)\r\n },\r\n MAX: {\r\n value: new NamedNode(MAX_NAME, MAX_NODE$2)\r\n }\r\n});\r\n/**\r\n * Reference Extensions\r\n */\r\nKeyIndex.__EMPTY_NODE = ChildrenNode.EMPTY_NODE;\r\nLeafNode.__childrenNodeConstructor = ChildrenNode;\r\nsetMaxNode(MAX_NODE$2);\r\nsetMaxNode$1(MAX_NODE$2);\n\n/**\r\n * @license\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 */\r\nvar USE_HINZE = true;\r\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 */\r\nfunction nodeFromJSON$1(json, priority) {\r\n if (priority === void 0) { priority = null; }\r\n if (json === null) {\r\n return ChildrenNode.EMPTY_NODE;\r\n }\r\n if (typeof json === 'object' && '.priority' in json) {\r\n priority = json['.priority'];\r\n }\r\n assert(priority === null ||\r\n typeof priority === 'string' ||\r\n typeof priority === 'number' ||\r\n (typeof priority === 'object' && '.sv' in priority), 'Invalid priority type found: ' + typeof priority);\r\n if (typeof json === 'object' && '.value' in json && json['.value'] !== null) {\r\n json = json['.value'];\r\n }\r\n // Valid leaf nodes include non-objects or server-value wrapper objects\r\n if (typeof json !== 'object' || '.sv' in json) {\r\n var jsonLeaf = json;\r\n return new LeafNode(jsonLeaf, nodeFromJSON$1(priority));\r\n }\r\n if (!(json instanceof Array) && USE_HINZE) {\r\n var children_1 = [];\r\n var childrenHavePriority_1 = false;\r\n var hinzeJsonObj_1 = json;\r\n forEach(hinzeJsonObj_1, function (key, child) {\r\n if (typeof key !== 'string' || key.substring(0, 1) !== '.') {\r\n // Ignore metadata nodes\r\n var childNode = nodeFromJSON$1(hinzeJsonObj_1[key]);\r\n if (!childNode.isEmpty()) {\r\n childrenHavePriority_1 =\r\n childrenHavePriority_1 || !childNode.getPriority().isEmpty();\r\n children_1.push(new NamedNode(key, childNode));\r\n }\r\n }\r\n });\r\n if (children_1.length == 0) {\r\n return ChildrenNode.EMPTY_NODE;\r\n }\r\n var childSet = buildChildSet(children_1, NAME_ONLY_COMPARATOR, function (namedNode) { return namedNode.name; }, NAME_COMPARATOR);\r\n if (childrenHavePriority_1) {\r\n var sortedChildSet = buildChildSet(children_1, PRIORITY_INDEX.getCompare());\r\n return new ChildrenNode(childSet, nodeFromJSON$1(priority), new IndexMap({ '.priority': sortedChildSet }, { '.priority': PRIORITY_INDEX }));\r\n }\r\n else {\r\n return new ChildrenNode(childSet, nodeFromJSON$1(priority), IndexMap.Default);\r\n }\r\n }\r\n else {\r\n var node_1 = ChildrenNode.EMPTY_NODE;\r\n var jsonObj_1 = json;\r\n forEach(jsonObj_1, function (key, childData) {\r\n if (contains(jsonObj_1, key)) {\r\n if (key.substring(0, 1) !== '.') {\r\n // ignore metadata nodes.\r\n var childNode = nodeFromJSON$1(childData);\r\n if (childNode.isLeafNode() || !childNode.isEmpty())\r\n node_1 = node_1.updateImmediateChild(key, childNode);\r\n }\r\n }\r\n });\r\n return node_1.updatePriority(nodeFromJSON$1(priority));\r\n }\r\n}\r\nsetNodeFromJSON(nodeFromJSON$1);\n\n/**\r\n * @license\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 */\r\n/**\r\n * @constructor\r\n * @extends {Index}\r\n * @private\r\n */\r\nvar ValueIndex = /** @class */ (function (_super) {\r\n __extends(ValueIndex, _super);\r\n function ValueIndex() {\r\n return _super !== null && _super.apply(this, arguments) || this;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueIndex.prototype.compare = function (a, b) {\r\n var indexCmp = a.node.compareTo(b.node);\r\n if (indexCmp === 0) {\r\n return nameCompare(a.name, b.name);\r\n }\r\n else {\r\n return indexCmp;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueIndex.prototype.isDefinedOn = function (node) {\r\n return true;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueIndex.prototype.indexedValueChanged = function (oldNode, newNode) {\r\n return !oldNode.equals(newNode);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueIndex.prototype.minPost = function () {\r\n return NamedNode.MIN;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueIndex.prototype.maxPost = function () {\r\n return NamedNode.MAX;\r\n };\r\n /**\r\n * @param {*} indexValue\r\n * @param {string} name\r\n * @return {!NamedNode}\r\n */\r\n ValueIndex.prototype.makePost = function (indexValue, name) {\r\n var valueNode = nodeFromJSON$1(indexValue);\r\n return new NamedNode(name, valueNode);\r\n };\r\n /**\r\n * @return {!string} String representation for inclusion in a query spec\r\n */\r\n ValueIndex.prototype.toString = function () {\r\n return '.value';\r\n };\r\n return ValueIndex;\r\n}(Index));\r\nvar VALUE_INDEX = new ValueIndex();\n\n/**\r\n * @license\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 */\r\n/**\r\n * @param {!Path} indexPath\r\n * @constructor\r\n * @extends {Index}\r\n */\r\nvar PathIndex = /** @class */ (function (_super) {\r\n __extends(PathIndex, _super);\r\n function PathIndex(indexPath_) {\r\n var _this = _super.call(this) || this;\r\n _this.indexPath_ = indexPath_;\r\n assert(!indexPath_.isEmpty() && indexPath_.getFront() !== '.priority', \"Can't create PathIndex with empty path or .priority key\");\r\n return _this;\r\n }\r\n /**\r\n * @param {!Node} snap\r\n * @return {!Node}\r\n * @protected\r\n */\r\n PathIndex.prototype.extractChild = function (snap) {\r\n return snap.getChild(this.indexPath_);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PathIndex.prototype.isDefinedOn = function (node) {\r\n return !node.getChild(this.indexPath_).isEmpty();\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PathIndex.prototype.compare = function (a, b) {\r\n var aChild = this.extractChild(a.node);\r\n var bChild = this.extractChild(b.node);\r\n var indexCmp = aChild.compareTo(bChild);\r\n if (indexCmp === 0) {\r\n return nameCompare(a.name, b.name);\r\n }\r\n else {\r\n return indexCmp;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PathIndex.prototype.makePost = function (indexValue, name) {\r\n var valueNode = nodeFromJSON$1(indexValue);\r\n var node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, valueNode);\r\n return new NamedNode(name, node);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PathIndex.prototype.maxPost = function () {\r\n var node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, MAX_NODE$2);\r\n return new NamedNode(MAX_NAME, node);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PathIndex.prototype.toString = function () {\r\n return this.indexPath_.slice().join('/');\r\n };\r\n return PathIndex;\r\n}(Index));\n\n/**\r\n * @license\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 */\r\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 */\r\nvar DataSnapshot = /** @class */ (function () {\r\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 */\r\n function DataSnapshot(node_, ref_, index_) {\r\n this.node_ = node_;\r\n this.ref_ = ref_;\r\n this.index_ = index_;\r\n }\r\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 */\r\n DataSnapshot.prototype.val = function () {\r\n validateArgCount('DataSnapshot.val', 0, 0, arguments.length);\r\n return this.node_.val();\r\n };\r\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 */\r\n DataSnapshot.prototype.exportVal = function () {\r\n validateArgCount('DataSnapshot.exportVal', 0, 0, arguments.length);\r\n return this.node_.val(true);\r\n };\r\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\r\n // for end-users\r\n DataSnapshot.prototype.toJSON = function () {\r\n // Optional spacer argument is unnecessary because we're depending on recursion rather than stringifying the content\r\n validateArgCount('DataSnapshot.toJSON', 0, 1, arguments.length);\r\n return this.exportVal();\r\n };\r\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 */\r\n DataSnapshot.prototype.exists = function () {\r\n validateArgCount('DataSnapshot.exists', 0, 0, arguments.length);\r\n return !this.node_.isEmpty();\r\n };\r\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 */\r\n DataSnapshot.prototype.child = function (childPathString) {\r\n validateArgCount('DataSnapshot.child', 0, 1, arguments.length);\r\n // Ensure the childPath is a string (can be a number)\r\n childPathString = String(childPathString);\r\n validatePathString('DataSnapshot.child', 1, childPathString, false);\r\n var childPath = new Path(childPathString);\r\n var childRef = this.ref_.child(childPath);\r\n return new DataSnapshot(this.node_.getChild(childPath), childRef, PRIORITY_INDEX);\r\n };\r\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 */\r\n DataSnapshot.prototype.hasChild = function (childPathString) {\r\n validateArgCount('DataSnapshot.hasChild', 1, 1, arguments.length);\r\n validatePathString('DataSnapshot.hasChild', 1, childPathString, false);\r\n var childPath = new Path(childPathString);\r\n return !this.node_.getChild(childPath).isEmpty();\r\n };\r\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 */\r\n DataSnapshot.prototype.getPriority = function () {\r\n validateArgCount('DataSnapshot.getPriority', 0, 0, arguments.length);\r\n // typecast here because we never return deferred values or internal priorities (MAX_PRIORITY)\r\n return this.node_.getPriority().val();\r\n };\r\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 */\r\n DataSnapshot.prototype.forEach = function (action) {\r\n var _this = this;\r\n validateArgCount('DataSnapshot.forEach', 1, 1, arguments.length);\r\n validateCallback('DataSnapshot.forEach', 1, action, false);\r\n if (this.node_.isLeafNode())\r\n return false;\r\n var childrenNode = this.node_;\r\n // Sanitize the return value to a boolean. ChildrenNode.forEachChild has a weird return type...\r\n return !!childrenNode.forEachChild(this.index_, function (key, node) {\r\n return action(new DataSnapshot(node, _this.ref_.child(key), PRIORITY_INDEX));\r\n });\r\n };\r\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 */\r\n DataSnapshot.prototype.hasChildren = function () {\r\n validateArgCount('DataSnapshot.hasChildren', 0, 0, arguments.length);\r\n if (this.node_.isLeafNode())\r\n return false;\r\n else\r\n return !this.node_.isEmpty();\r\n };\r\n Object.defineProperty(DataSnapshot.prototype, \"key\", {\r\n get: function () {\r\n return this.ref_.getKey();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\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 */\r\n DataSnapshot.prototype.numChildren = function () {\r\n validateArgCount('DataSnapshot.numChildren', 0, 0, arguments.length);\r\n return this.node_.numChildren();\r\n };\r\n /**\r\n * @return {Reference} The Firebase reference for the location this snapshot's data came from.\r\n */\r\n DataSnapshot.prototype.getRef = function () {\r\n validateArgCount('DataSnapshot.ref', 0, 0, arguments.length);\r\n return this.ref_;\r\n };\r\n Object.defineProperty(DataSnapshot.prototype, \"ref\", {\r\n get: function () {\r\n return this.getRef();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n return DataSnapshot;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Encapsulates the data needed to raise an event\r\n * @implements {Event}\r\n */\r\nvar DataEvent = /** @class */ (function () {\r\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 */\r\n function DataEvent(eventType, eventRegistration, snapshot, prevName) {\r\n this.eventType = eventType;\r\n this.eventRegistration = eventRegistration;\r\n this.snapshot = snapshot;\r\n this.prevName = prevName;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n DataEvent.prototype.getPath = function () {\r\n var ref = this.snapshot.getRef();\r\n if (this.eventType === 'value') {\r\n return ref.path;\r\n }\r\n else {\r\n return ref.getParent().path;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n DataEvent.prototype.getEventType = function () {\r\n return this.eventType;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n DataEvent.prototype.getEventRunner = function () {\r\n return this.eventRegistration.getEventRunner(this);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n DataEvent.prototype.toString = function () {\r\n return (this.getPath().toString() +\r\n ':' +\r\n this.eventType +\r\n ':' +\r\n stringify(this.snapshot.exportVal()));\r\n };\r\n return DataEvent;\r\n}());\r\nvar CancelEvent = /** @class */ (function () {\r\n /**\r\n * @param {EventRegistration} eventRegistration\r\n * @param {Error} error\r\n * @param {!Path} path\r\n */\r\n function CancelEvent(eventRegistration, error, path) {\r\n this.eventRegistration = eventRegistration;\r\n this.error = error;\r\n this.path = path;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n CancelEvent.prototype.getPath = function () {\r\n return this.path;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n CancelEvent.prototype.getEventType = function () {\r\n return 'cancel';\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n CancelEvent.prototype.getEventRunner = function () {\r\n return this.eventRegistration.getEventRunner(this);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n CancelEvent.prototype.toString = function () {\r\n return this.path.toString() + ':cancel';\r\n };\r\n return CancelEvent;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Represents registration for 'value' events.\r\n */\r\nvar ValueEventRegistration = /** @class */ (function () {\r\n /**\r\n * @param {?function(!DataSnapshot)} callback_\r\n * @param {?function(Error)} cancelCallback_\r\n * @param {?Object} context_\r\n */\r\n function ValueEventRegistration(callback_, cancelCallback_, context_) {\r\n this.callback_ = callback_;\r\n this.cancelCallback_ = cancelCallback_;\r\n this.context_ = context_;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueEventRegistration.prototype.respondsTo = function (eventType) {\r\n return eventType === 'value';\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueEventRegistration.prototype.createEvent = function (change, query) {\r\n var index = query.getQueryParams().getIndex();\r\n return new DataEvent('value', this, new DataSnapshot(change.snapshotNode, query.getRef(), index));\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueEventRegistration.prototype.getEventRunner = function (eventData) {\r\n var ctx = this.context_;\r\n if (eventData.getEventType() === 'cancel') {\r\n assert(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback');\r\n var cancelCB_1 = this.cancelCallback_;\r\n return function () {\r\n // We know that error exists, we checked above that this is a cancel event\r\n cancelCB_1.call(ctx, eventData.error);\r\n };\r\n }\r\n else {\r\n var cb_1 = this.callback_;\r\n return function () {\r\n cb_1.call(ctx, eventData.snapshot);\r\n };\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueEventRegistration.prototype.createCancelEvent = function (error, path) {\r\n if (this.cancelCallback_) {\r\n return new CancelEvent(this, error, path);\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueEventRegistration.prototype.matches = function (other) {\r\n if (!(other instanceof ValueEventRegistration)) {\r\n return false;\r\n }\r\n else if (!other.callback_ || !this.callback_) {\r\n // If no callback specified, we consider it to match any callback.\r\n return true;\r\n }\r\n else {\r\n return (other.callback_ === this.callback_ && other.context_ === this.context_);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ValueEventRegistration.prototype.hasAnyCallback = function () {\r\n return this.callback_ !== null;\r\n };\r\n return ValueEventRegistration;\r\n}());\r\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 */\r\nvar ChildEventRegistration = /** @class */ (function () {\r\n /**\r\n * @param {?Object.} callbacks_\r\n * @param {?function(Error)} cancelCallback_\r\n * @param {Object=} context_\r\n */\r\n function ChildEventRegistration(callbacks_, cancelCallback_, context_) {\r\n this.callbacks_ = callbacks_;\r\n this.cancelCallback_ = cancelCallback_;\r\n this.context_ = context_;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildEventRegistration.prototype.respondsTo = function (eventType) {\r\n var eventToCheck = eventType === 'children_added' ? 'child_added' : eventType;\r\n eventToCheck =\r\n eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;\r\n return contains(this.callbacks_, eventToCheck);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildEventRegistration.prototype.createCancelEvent = function (error, path) {\r\n if (this.cancelCallback_) {\r\n return new CancelEvent(this, error, path);\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildEventRegistration.prototype.createEvent = function (change, query) {\r\n assert(change.childName != null, 'Child events should have a childName.');\r\n var ref = query.getRef().child(/** @type {!string} */ (change.childName));\r\n var index = query.getQueryParams().getIndex();\r\n return new DataEvent(change.type, this, new DataSnapshot(change.snapshotNode, ref, index), change.prevName);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildEventRegistration.prototype.getEventRunner = function (eventData) {\r\n var ctx = this.context_;\r\n if (eventData.getEventType() === 'cancel') {\r\n assert(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback');\r\n var cancelCB_2 = this.cancelCallback_;\r\n return function () {\r\n // We know that error exists, we checked above that this is a cancel event\r\n cancelCB_2.call(ctx, eventData.error);\r\n };\r\n }\r\n else {\r\n var cb_2 = this.callbacks_[eventData.eventType];\r\n return function () {\r\n cb_2.call(ctx, eventData.snapshot, eventData.prevName);\r\n };\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildEventRegistration.prototype.matches = function (other) {\r\n if (other instanceof ChildEventRegistration) {\r\n if (!this.callbacks_ || !other.callbacks_) {\r\n return true;\r\n }\r\n else if (this.context_ === other.context_) {\r\n var otherCount = getCount(other.callbacks_);\r\n var thisCount = getCount(this.callbacks_);\r\n if (otherCount === thisCount) {\r\n // If count is 1, do an exact match on eventType, if either is defined but null, it's a match.\r\n // If event types don't match, not a match\r\n // If count is not 1, exact match across all\r\n if (otherCount === 1) {\r\n var otherKey /** @type {!string} */ = getAnyKey(other.callbacks_);\r\n var thisKey /** @type {!string} */ = getAnyKey(this.callbacks_);\r\n return (thisKey === otherKey &&\r\n (!other.callbacks_[otherKey] ||\r\n !this.callbacks_[thisKey] ||\r\n other.callbacks_[otherKey] === this.callbacks_[thisKey]));\r\n }\r\n else {\r\n // Exact match on each key.\r\n return every(this.callbacks_, function (eventType, cb) { return other.callbacks_[eventType] === cb; });\r\n }\r\n }\r\n }\r\n }\r\n return false;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n ChildEventRegistration.prototype.hasAnyCallback = function () {\r\n return this.callbacks_ !== null;\r\n };\r\n return ChildEventRegistration;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar __referenceConstructor;\r\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 */\r\nvar Query = /** @class */ (function () {\r\n function Query(repo, path, queryParams_, orderByCalled_) {\r\n this.repo = repo;\r\n this.path = path;\r\n this.queryParams_ = queryParams_;\r\n this.orderByCalled_ = orderByCalled_;\r\n }\r\n Object.defineProperty(Query, \"__referenceConstructor\", {\r\n get: function () {\r\n assert(__referenceConstructor, 'Reference.ts has not been loaded');\r\n return __referenceConstructor;\r\n },\r\n set: function (val) {\r\n __referenceConstructor = val;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * Validates start/end values for queries.\r\n * @param {!QueryParams} params\r\n * @private\r\n */\r\n Query.validateQueryEndpoints_ = function (params) {\r\n var startNode = null;\r\n var endNode = null;\r\n if (params.hasStart()) {\r\n startNode = params.getIndexStartValue();\r\n }\r\n if (params.hasEnd()) {\r\n endNode = params.getIndexEndValue();\r\n }\r\n if (params.getIndex() === KEY_INDEX) {\r\n var tooManyArgsError = 'Query: When ordering by key, you may only pass one argument to ' +\r\n 'startAt(), endAt(), or equalTo().';\r\n var wrongArgTypeError = 'Query: When ordering by key, the argument passed to startAt(), endAt(),' +\r\n 'or equalTo() must be a string.';\r\n if (params.hasStart()) {\r\n var startName = params.getIndexStartName();\r\n if (startName != MIN_NAME) {\r\n throw new Error(tooManyArgsError);\r\n }\r\n else if (typeof startNode !== 'string') {\r\n throw new Error(wrongArgTypeError);\r\n }\r\n }\r\n if (params.hasEnd()) {\r\n var endName = params.getIndexEndName();\r\n if (endName != MAX_NAME) {\r\n throw new Error(tooManyArgsError);\r\n }\r\n else if (typeof endNode !== 'string') {\r\n throw new Error(wrongArgTypeError);\r\n }\r\n }\r\n }\r\n else if (params.getIndex() === PRIORITY_INDEX) {\r\n if ((startNode != null && !isValidPriority(startNode)) ||\r\n (endNode != null && !isValidPriority(endNode))) {\r\n throw new Error('Query: When ordering by priority, the first argument passed to startAt(), ' +\r\n 'endAt(), or equalTo() must be a valid priority value (null, a number, or a string).');\r\n }\r\n }\r\n else {\r\n assert(params.getIndex() instanceof PathIndex ||\r\n params.getIndex() === VALUE_INDEX, 'unknown index type.');\r\n if ((startNode != null && typeof startNode === 'object') ||\r\n (endNode != null && typeof endNode === 'object')) {\r\n throw new Error('Query: First argument passed to startAt(), endAt(), or equalTo() cannot be ' +\r\n 'an object.');\r\n }\r\n }\r\n };\r\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 */\r\n Query.validateLimit_ = function (params) {\r\n if (params.hasStart() &&\r\n params.hasEnd() &&\r\n params.hasLimit() &&\r\n !params.hasAnchoredLimit()) {\r\n throw new Error(\"Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.\");\r\n }\r\n };\r\n /**\r\n * Validates that no other order by call has been made\r\n * @param {!string} fnName\r\n * @private\r\n */\r\n Query.prototype.validateNoPreviousOrderByCall_ = function (fnName) {\r\n if (this.orderByCalled_ === true) {\r\n throw new Error(fnName + \": You can't combine multiple orderBy calls.\");\r\n }\r\n };\r\n /**\r\n * @return {!QueryParams}\r\n */\r\n Query.prototype.getQueryParams = function () {\r\n return this.queryParams_;\r\n };\r\n /**\r\n * @return {!Reference}\r\n */\r\n Query.prototype.getRef = function () {\r\n validateArgCount('Query.ref', 0, 0, arguments.length);\r\n // This is a slight hack. We cannot goog.require('fb.api.Firebase'), since Firebase requires fb.api.Query.\r\n // However, we will always export 'Firebase' to the global namespace, so it's guaranteed to exist by the time this\r\n // method gets called.\r\n return new Query.__referenceConstructor(this.repo, this.path);\r\n };\r\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 */\r\n Query.prototype.on = function (eventType, callback, cancelCallbackOrContext, context) {\r\n validateArgCount('Query.on', 2, 4, arguments.length);\r\n validateEventType('Query.on', 1, eventType, false);\r\n validateCallback('Query.on', 2, callback, false);\r\n var ret = Query.getCancelAndContextArgs_('Query.on', cancelCallbackOrContext, context);\r\n if (eventType === 'value') {\r\n this.onValueEvent(callback, ret.cancel, ret.context);\r\n }\r\n else {\r\n var callbacks = {};\r\n callbacks[eventType] = callback;\r\n this.onChildEvent(callbacks, ret.cancel, ret.context);\r\n }\r\n return callback;\r\n };\r\n /**\r\n * @param {!function(!DataSnapshot)} callback\r\n * @param {?function(Error)} cancelCallback\r\n * @param {?Object} context\r\n * @protected\r\n */\r\n Query.prototype.onValueEvent = function (callback, cancelCallback, context) {\r\n var container = new ValueEventRegistration(callback, cancelCallback || null, context || null);\r\n this.repo.addEventCallbackForQuery(this, container);\r\n };\r\n /**\r\n * @param {!Object.} callbacks\r\n * @param {?function(Error)} cancelCallback\r\n * @param {?Object} context\r\n * @protected\r\n */\r\n Query.prototype.onChildEvent = function (callbacks, cancelCallback, context) {\r\n var container = new ChildEventRegistration(callbacks, cancelCallback, context);\r\n this.repo.addEventCallbackForQuery(this, container);\r\n };\r\n /**\r\n * @param {string=} eventType\r\n * @param {(function(!DataSnapshot, ?string=))=} callback\r\n * @param {Object=} context\r\n */\r\n Query.prototype.off = function (eventType, callback, context) {\r\n validateArgCount('Query.off', 0, 3, arguments.length);\r\n validateEventType('Query.off', 1, eventType, true);\r\n validateCallback('Query.off', 2, callback, true);\r\n validateContextObject('Query.off', 3, context, true);\r\n var container = null;\r\n var callbacks = null;\r\n if (eventType === 'value') {\r\n var valueCallback = callback || null;\r\n container = new ValueEventRegistration(valueCallback, null, context || null);\r\n }\r\n else if (eventType) {\r\n if (callback) {\r\n callbacks = {};\r\n callbacks[eventType] = callback;\r\n }\r\n container = new ChildEventRegistration(callbacks, null, context || null);\r\n }\r\n this.repo.removeEventCallbackForQuery(this, container);\r\n };\r\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 */\r\n Query.prototype.once = function (eventType, userCallback, cancelOrContext, context) {\r\n var _this = this;\r\n validateArgCount('Query.once', 1, 4, arguments.length);\r\n validateEventType('Query.once', 1, eventType, false);\r\n validateCallback('Query.once', 2, userCallback, true);\r\n var ret = Query.getCancelAndContextArgs_('Query.once', cancelOrContext, context);\r\n // TODO: Implement this more efficiently (in particular, use 'get' wire protocol for 'value' event)\r\n // TODO: consider actually wiring the callbacks into the promise. We cannot do this without a breaking change\r\n // because the API currently expects callbacks will be called synchronously if the data is cached, but this is\r\n // against the Promise specification.\r\n var firstCall = true;\r\n var deferred = new Deferred();\r\n // A dummy error handler in case a user wasn't expecting promises\r\n deferred.promise.catch(function () { });\r\n var onceCallback = function (snapshot) {\r\n // NOTE: Even though we unsubscribe, we may get called multiple times if a single action (e.g. set() with JSON)\r\n // triggers multiple events (e.g. child_added or child_changed).\r\n if (firstCall) {\r\n firstCall = false;\r\n _this.off(eventType, onceCallback);\r\n if (userCallback) {\r\n userCallback.bind(ret.context)(snapshot);\r\n }\r\n deferred.resolve(snapshot);\r\n }\r\n };\r\n this.on(eventType, onceCallback, \r\n /*cancel=*/ function (err) {\r\n _this.off(eventType, onceCallback);\r\n if (ret.cancel)\r\n ret.cancel.bind(ret.context)(err);\r\n deferred.reject(err);\r\n });\r\n return deferred.promise;\r\n };\r\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 */\r\n Query.prototype.limitToFirst = function (limit) {\r\n validateArgCount('Query.limitToFirst', 1, 1, arguments.length);\r\n if (typeof limit !== 'number' ||\r\n Math.floor(limit) !== limit ||\r\n limit <= 0) {\r\n throw new Error('Query.limitToFirst: First argument must be a positive integer.');\r\n }\r\n if (this.queryParams_.hasLimit()) {\r\n throw new Error('Query.limitToFirst: Limit was already set (by another call to limit, ' +\r\n 'limitToFirst, or limitToLast).');\r\n }\r\n return new Query(this.repo, this.path, this.queryParams_.limitToFirst(limit), this.orderByCalled_);\r\n };\r\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 */\r\n Query.prototype.limitToLast = function (limit) {\r\n validateArgCount('Query.limitToLast', 1, 1, arguments.length);\r\n if (typeof limit !== 'number' ||\r\n Math.floor(limit) !== limit ||\r\n limit <= 0) {\r\n throw new Error('Query.limitToLast: First argument must be a positive integer.');\r\n }\r\n if (this.queryParams_.hasLimit()) {\r\n throw new Error('Query.limitToLast: Limit was already set (by another call to limit, ' +\r\n 'limitToFirst, or limitToLast).');\r\n }\r\n return new Query(this.repo, this.path, this.queryParams_.limitToLast(limit), this.orderByCalled_);\r\n };\r\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 */\r\n Query.prototype.orderByChild = function (path) {\r\n validateArgCount('Query.orderByChild', 1, 1, arguments.length);\r\n if (path === '$key') {\r\n throw new Error('Query.orderByChild: \"$key\" is invalid. Use Query.orderByKey() instead.');\r\n }\r\n else if (path === '$priority') {\r\n throw new Error('Query.orderByChild: \"$priority\" is invalid. Use Query.orderByPriority() instead.');\r\n }\r\n else if (path === '$value') {\r\n throw new Error('Query.orderByChild: \"$value\" is invalid. Use Query.orderByValue() instead.');\r\n }\r\n validatePathString('Query.orderByChild', 1, path, false);\r\n this.validateNoPreviousOrderByCall_('Query.orderByChild');\r\n var parsedPath = new Path(path);\r\n if (parsedPath.isEmpty()) {\r\n throw new Error('Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.');\r\n }\r\n var index = new PathIndex(parsedPath);\r\n var newParams = this.queryParams_.orderBy(index);\r\n Query.validateQueryEndpoints_(newParams);\r\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\r\n };\r\n /**\r\n * Return a new query ordered by the KeyIndex\r\n * @return {!Query}\r\n */\r\n Query.prototype.orderByKey = function () {\r\n validateArgCount('Query.orderByKey', 0, 0, arguments.length);\r\n this.validateNoPreviousOrderByCall_('Query.orderByKey');\r\n var newParams = this.queryParams_.orderBy(KEY_INDEX);\r\n Query.validateQueryEndpoints_(newParams);\r\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\r\n };\r\n /**\r\n * Return a new query ordered by the PriorityIndex\r\n * @return {!Query}\r\n */\r\n Query.prototype.orderByPriority = function () {\r\n validateArgCount('Query.orderByPriority', 0, 0, arguments.length);\r\n this.validateNoPreviousOrderByCall_('Query.orderByPriority');\r\n var newParams = this.queryParams_.orderBy(PRIORITY_INDEX);\r\n Query.validateQueryEndpoints_(newParams);\r\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\r\n };\r\n /**\r\n * Return a new query ordered by the ValueIndex\r\n * @return {!Query}\r\n */\r\n Query.prototype.orderByValue = function () {\r\n validateArgCount('Query.orderByValue', 0, 0, arguments.length);\r\n this.validateNoPreviousOrderByCall_('Query.orderByValue');\r\n var newParams = this.queryParams_.orderBy(VALUE_INDEX);\r\n Query.validateQueryEndpoints_(newParams);\r\n return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true);\r\n };\r\n /**\r\n * @param {number|string|boolean|null} value\r\n * @param {?string=} name\r\n * @return {!Query}\r\n */\r\n Query.prototype.startAt = function (value, name) {\r\n if (value === void 0) { value = null; }\r\n validateArgCount('Query.startAt', 0, 2, arguments.length);\r\n validateFirebaseDataArg('Query.startAt', 1, value, this.path, true);\r\n validateKey('Query.startAt', 2, name, true);\r\n var newParams = this.queryParams_.startAt(value, name);\r\n Query.validateLimit_(newParams);\r\n Query.validateQueryEndpoints_(newParams);\r\n if (this.queryParams_.hasStart()) {\r\n throw new Error('Query.startAt: Starting point was already set (by another call to startAt ' +\r\n 'or equalTo).');\r\n }\r\n // Calling with no params tells us to start at the beginning.\r\n if (value === undefined) {\r\n value = null;\r\n name = null;\r\n }\r\n return new Query(this.repo, this.path, newParams, this.orderByCalled_);\r\n };\r\n /**\r\n * @param {number|string|boolean|null} value\r\n * @param {?string=} name\r\n * @return {!Query}\r\n */\r\n Query.prototype.endAt = function (value, name) {\r\n if (value === void 0) { value = null; }\r\n validateArgCount('Query.endAt', 0, 2, arguments.length);\r\n validateFirebaseDataArg('Query.endAt', 1, value, this.path, true);\r\n validateKey('Query.endAt', 2, name, true);\r\n var newParams = this.queryParams_.endAt(value, name);\r\n Query.validateLimit_(newParams);\r\n Query.validateQueryEndpoints_(newParams);\r\n if (this.queryParams_.hasEnd()) {\r\n throw new Error('Query.endAt: Ending point was already set (by another call to endAt or ' +\r\n 'equalTo).');\r\n }\r\n return new Query(this.repo, this.path, newParams, this.orderByCalled_);\r\n };\r\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 */\r\n Query.prototype.equalTo = function (value, name) {\r\n validateArgCount('Query.equalTo', 1, 2, arguments.length);\r\n validateFirebaseDataArg('Query.equalTo', 1, value, this.path, false);\r\n validateKey('Query.equalTo', 2, name, true);\r\n if (this.queryParams_.hasStart()) {\r\n throw new Error('Query.equalTo: Starting point was already set (by another call to startAt or ' +\r\n 'equalTo).');\r\n }\r\n if (this.queryParams_.hasEnd()) {\r\n throw new Error('Query.equalTo: Ending point was already set (by another call to endAt or ' +\r\n 'equalTo).');\r\n }\r\n return this.startAt(value, name).endAt(value, name);\r\n };\r\n /**\r\n * @return {!string} URL for this location.\r\n */\r\n Query.prototype.toString = function () {\r\n validateArgCount('Query.toString', 0, 0, arguments.length);\r\n return this.repo.toString() + this.path.toUrlEncodedString();\r\n };\r\n // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary\r\n // for end-users.\r\n Query.prototype.toJSON = function () {\r\n // An optional spacer argument is unnecessary for a string.\r\n validateArgCount('Query.toJSON', 0, 1, arguments.length);\r\n return this.toString();\r\n };\r\n /**\r\n * An object representation of the query parameters used by this Query.\r\n * @return {!Object}\r\n */\r\n Query.prototype.queryObject = function () {\r\n return this.queryParams_.getQueryObject();\r\n };\r\n /**\r\n * @return {!string}\r\n */\r\n Query.prototype.queryIdentifier = function () {\r\n var obj = this.queryObject();\r\n var id = ObjectToUniqueKey(obj);\r\n return id === '{}' ? 'default' : id;\r\n };\r\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 */\r\n Query.prototype.isEqual = function (other) {\r\n validateArgCount('Query.isEqual', 1, 1, arguments.length);\r\n if (!(other instanceof Query)) {\r\n var error = 'Query.isEqual failed: First argument must be an instance of firebase.database.Query.';\r\n throw new Error(error);\r\n }\r\n var sameRepo = this.repo === other.repo;\r\n var samePath = this.path.equals(other.path);\r\n var sameQueryIdentifier = this.queryIdentifier() === other.queryIdentifier();\r\n return sameRepo && samePath && sameQueryIdentifier;\r\n };\r\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 */\r\n Query.getCancelAndContextArgs_ = function (fnName, cancelOrContext, context) {\r\n var ret = { cancel: null, context: null };\r\n if (cancelOrContext && context) {\r\n ret.cancel = cancelOrContext;\r\n validateCallback(fnName, 3, ret.cancel, true);\r\n ret.context = context;\r\n validateContextObject(fnName, 4, ret.context, true);\r\n }\r\n else if (cancelOrContext) {\r\n // we have either a cancel callback or a context.\r\n if (typeof cancelOrContext === 'object' && cancelOrContext !== null) {\r\n // it's a context!\r\n ret.context = cancelOrContext;\r\n }\r\n else if (typeof cancelOrContext === 'function') {\r\n ret.cancel = cancelOrContext;\r\n }\r\n else {\r\n throw new Error(errorPrefix(fnName, 3, true) +\r\n ' must either be a cancel callback or a context object.');\r\n }\r\n }\r\n return ret;\r\n };\r\n Object.defineProperty(Query.prototype, \"ref\", {\r\n get: function () {\r\n return this.getRef();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n return Query;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Implements a set with a count of elements.\r\n *\r\n * @template K, V\r\n */\r\nvar CountedSet = /** @class */ (function () {\r\n function CountedSet() {\r\n this.set = {};\r\n }\r\n /**\r\n * @param {!K} item\r\n * @param {V} val\r\n */\r\n CountedSet.prototype.add = function (item, val) {\r\n this.set[item] = val !== null ? val : true;\r\n };\r\n /**\r\n * @param {!K} key\r\n * @return {boolean}\r\n */\r\n CountedSet.prototype.contains = function (key) {\r\n return contains(this.set, key);\r\n };\r\n /**\r\n * @param {!K} item\r\n * @return {V}\r\n */\r\n CountedSet.prototype.get = function (item) {\r\n return this.contains(item) ? this.set[item] : undefined;\r\n };\r\n /**\r\n * @param {!K} item\r\n */\r\n CountedSet.prototype.remove = function (item) {\r\n delete this.set[item];\r\n };\r\n /**\r\n * Deletes everything in the set\r\n */\r\n CountedSet.prototype.clear = function () {\r\n this.set = {};\r\n };\r\n /**\r\n * True if there's nothing in the set\r\n * @return {boolean}\r\n */\r\n CountedSet.prototype.isEmpty = function () {\r\n return isEmpty(this.set);\r\n };\r\n /**\r\n * @return {number} The number of items in the set\r\n */\r\n CountedSet.prototype.count = function () {\r\n return getCount(this.set);\r\n };\r\n /**\r\n * Run a function on each k,v pair in the set\r\n * @param {function(K, V)} fn\r\n */\r\n CountedSet.prototype.each = function (fn) {\r\n forEach(this.set, function (k, v) { return fn(k, v); });\r\n };\r\n /**\r\n * Mostly for debugging\r\n * @return {Array.} The keys present in this CountedSet\r\n */\r\n CountedSet.prototype.keys = function () {\r\n var keys = [];\r\n forEach(this.set, function (k) {\r\n keys.push(k);\r\n });\r\n return keys;\r\n };\r\n return CountedSet;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Helper class to store a sparse set of snapshots.\r\n *\r\n * @constructor\r\n */\r\nvar SparseSnapshotTree = /** @class */ (function () {\r\n function SparseSnapshotTree() {\r\n /**\r\n * @private\r\n * @type {Node}\r\n */\r\n this.value_ = null;\r\n /**\r\n * @private\r\n * @type {CountedSet}\r\n */\r\n this.children_ = null;\r\n }\r\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 */\r\n SparseSnapshotTree.prototype.find = function (path) {\r\n if (this.value_ != null) {\r\n return this.value_.getChild(path);\r\n }\r\n else if (!path.isEmpty() && this.children_ != null) {\r\n var childKey = path.getFront();\r\n path = path.popFront();\r\n if (this.children_.contains(childKey)) {\r\n var childTree = this.children_.get(childKey);\r\n return childTree.find(path);\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\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 */\r\n SparseSnapshotTree.prototype.remember = function (path, data) {\r\n if (path.isEmpty()) {\r\n this.value_ = data;\r\n this.children_ = null;\r\n }\r\n else if (this.value_ !== null) {\r\n this.value_ = this.value_.updateChild(path, data);\r\n }\r\n else {\r\n if (this.children_ == null) {\r\n this.children_ = new CountedSet();\r\n }\r\n var childKey = path.getFront();\r\n if (!this.children_.contains(childKey)) {\r\n this.children_.add(childKey, new SparseSnapshotTree());\r\n }\r\n var child = this.children_.get(childKey);\r\n path = path.popFront();\r\n child.remember(path, data);\r\n }\r\n };\r\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 */\r\n SparseSnapshotTree.prototype.forget = function (path) {\r\n if (path.isEmpty()) {\r\n this.value_ = null;\r\n this.children_ = null;\r\n return true;\r\n }\r\n else {\r\n if (this.value_ !== null) {\r\n if (this.value_.isLeafNode()) {\r\n // We're trying to forget a node that doesn't exist\r\n return false;\r\n }\r\n else {\r\n var value = this.value_;\r\n this.value_ = null;\r\n var self_1 = this;\r\n value.forEachChild(PRIORITY_INDEX, function (key, tree) {\r\n self_1.remember(new Path(key), tree);\r\n });\r\n return this.forget(path);\r\n }\r\n }\r\n else if (this.children_ !== null) {\r\n var childKey = path.getFront();\r\n path = path.popFront();\r\n if (this.children_.contains(childKey)) {\r\n var safeToRemove = this.children_.get(childKey).forget(path);\r\n if (safeToRemove) {\r\n this.children_.remove(childKey);\r\n }\r\n }\r\n if (this.children_.isEmpty()) {\r\n this.children_ = null;\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n else {\r\n return true;\r\n }\r\n }\r\n };\r\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 */\r\n SparseSnapshotTree.prototype.forEachTree = function (prefixPath, func) {\r\n if (this.value_ !== null) {\r\n func(prefixPath, this.value_);\r\n }\r\n else {\r\n this.forEachChild(function (key, tree) {\r\n var path = new Path(prefixPath.toString() + '/' + key);\r\n tree.forEachTree(path, func);\r\n });\r\n }\r\n };\r\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 */\r\n SparseSnapshotTree.prototype.forEachChild = function (func) {\r\n if (this.children_ !== null) {\r\n this.children_.each(function (key, tree) {\r\n func(key, tree);\r\n });\r\n }\r\n };\r\n return SparseSnapshotTree;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Generate placeholders for deferred values.\r\n * @param {?Object} values\r\n * @return {!Object}\r\n */\r\nvar generateWithValues = function (values) {\r\n values = values || {};\r\n values['timestamp'] = values['timestamp'] || new Date().getTime();\r\n return values;\r\n};\r\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 */\r\nvar resolveDeferredValue = function (value, serverValues) {\r\n if (!value || typeof value !== 'object') {\r\n return value;\r\n }\r\n else {\r\n assert('.sv' in value, 'Unexpected leaf node or priority contents');\r\n return serverValues[value['.sv']];\r\n }\r\n};\r\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 */\r\nvar resolveDeferredValueTree = function (tree, serverValues) {\r\n var resolvedTree = new SparseSnapshotTree();\r\n tree.forEachTree(new Path(''), function (path, node) {\r\n resolvedTree.remember(path, resolveDeferredValueSnapshot(node, serverValues));\r\n });\r\n return resolvedTree;\r\n};\r\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 */\r\nvar resolveDeferredValueSnapshot = function (node, serverValues) {\r\n var rawPri = node.getPriority().val();\r\n var priority = resolveDeferredValue(rawPri, serverValues);\r\n var newNode;\r\n if (node.isLeafNode()) {\r\n var leafNode = node;\r\n var value = resolveDeferredValue(leafNode.getValue(), serverValues);\r\n if (value !== leafNode.getValue() ||\r\n priority !== leafNode.getPriority().val()) {\r\n return new LeafNode(value, nodeFromJSON$1(priority));\r\n }\r\n else {\r\n return node;\r\n }\r\n }\r\n else {\r\n var childrenNode = node;\r\n newNode = childrenNode;\r\n if (priority !== childrenNode.getPriority().val()) {\r\n newNode = newNode.updatePriority(new LeafNode(priority));\r\n }\r\n childrenNode.forEachChild(PRIORITY_INDEX, function (childName, childNode) {\r\n var newChildNode = resolveDeferredValueSnapshot(childNode, serverValues);\r\n if (newChildNode !== childNode) {\r\n newNode = newNode.updateImmediateChild(childName, newChildNode);\r\n }\r\n });\r\n return newNode;\r\n }\r\n};\n\n/**\r\n * @license\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 */\r\n/**\r\n *\r\n * @enum\r\n */\r\nvar OperationType;\r\n(function (OperationType) {\r\n OperationType[OperationType[\"OVERWRITE\"] = 0] = \"OVERWRITE\";\r\n OperationType[OperationType[\"MERGE\"] = 1] = \"MERGE\";\r\n OperationType[OperationType[\"ACK_USER_WRITE\"] = 2] = \"ACK_USER_WRITE\";\r\n OperationType[OperationType[\"LISTEN_COMPLETE\"] = 3] = \"LISTEN_COMPLETE\";\r\n})(OperationType || (OperationType = {}));\r\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 */\r\nvar OperationSource = /** @class */ (function () {\r\n function OperationSource(fromUser, fromServer, queryId, tagged) {\r\n this.fromUser = fromUser;\r\n this.fromServer = fromServer;\r\n this.queryId = queryId;\r\n this.tagged = tagged;\r\n assert(!tagged || fromServer, 'Tagged queries must be from server.');\r\n }\r\n /**\r\n * @const\r\n * @type {!OperationSource}\r\n */\r\n OperationSource.User = new OperationSource(\r\n /*fromUser=*/ true, false, null, \r\n /*tagged=*/ false);\r\n /**\r\n * @const\r\n * @type {!OperationSource}\r\n */\r\n OperationSource.Server = new OperationSource(false, \r\n /*fromServer=*/ true, null, \r\n /*tagged=*/ false);\r\n /**\r\n * @param {string} queryId\r\n * @return {!OperationSource}\r\n */\r\n OperationSource.forServerTaggedQuery = function (queryId) {\r\n return new OperationSource(false, \r\n /*fromServer=*/ true, queryId, \r\n /*tagged=*/ true);\r\n };\r\n return OperationSource;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar AckUserWrite = /** @class */ (function () {\r\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 */\r\n function AckUserWrite(\r\n /**@inheritDoc */ path, \r\n /**@inheritDoc */ affectedTree, \r\n /**@inheritDoc */ revert) {\r\n this.path = path;\r\n this.affectedTree = affectedTree;\r\n this.revert = revert;\r\n /** @inheritDoc */\r\n this.type = OperationType.ACK_USER_WRITE;\r\n /** @inheritDoc */\r\n this.source = OperationSource.User;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n AckUserWrite.prototype.operationForChild = function (childName) {\r\n if (!this.path.isEmpty()) {\r\n assert(this.path.getFront() === childName, 'operationForChild called for unrelated child.');\r\n return new AckUserWrite(this.path.popFront(), this.affectedTree, this.revert);\r\n }\r\n else if (this.affectedTree.value != null) {\r\n assert(this.affectedTree.children.isEmpty(), 'affectedTree should not have overlapping affected paths.');\r\n // All child locations are affected as well; just return same operation.\r\n return this;\r\n }\r\n else {\r\n var childTree = this.affectedTree.subtree(new Path(childName));\r\n return new AckUserWrite(Path.Empty, childTree, this.revert);\r\n }\r\n };\r\n return AckUserWrite;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar emptyChildrenSingleton;\r\n/**\r\n * Singleton empty children collection.\r\n *\r\n * @const\r\n * @type {!SortedMap.>}\r\n */\r\nvar EmptyChildren = function () {\r\n if (!emptyChildrenSingleton) {\r\n emptyChildrenSingleton = new SortedMap(stringCompare);\r\n }\r\n return emptyChildrenSingleton;\r\n};\r\n/**\r\n * A tree with immutable elements.\r\n */\r\nvar ImmutableTree = /** @class */ (function () {\r\n /**\r\n * @template T\r\n * @param {?T} value\r\n * @param {SortedMap.>=} children\r\n */\r\n function ImmutableTree(value, children) {\r\n if (children === void 0) { children = EmptyChildren(); }\r\n this.value = value;\r\n this.children = children;\r\n }\r\n /**\r\n * @template T\r\n * @param {!Object.} obj\r\n * @return {!ImmutableTree.}\r\n */\r\n ImmutableTree.fromObject = function (obj) {\r\n var tree = ImmutableTree.Empty;\r\n forEach(obj, function (childPath, childSnap) {\r\n tree = tree.set(new Path(childPath), childSnap);\r\n });\r\n return tree;\r\n };\r\n /**\r\n * True if the value is empty and there are no children\r\n * @return {boolean}\r\n */\r\n ImmutableTree.prototype.isEmpty = function () {\r\n return this.value === null && this.children.isEmpty();\r\n };\r\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 */\r\n ImmutableTree.prototype.findRootMostMatchingPathAndValue = function (relativePath, predicate) {\r\n if (this.value != null && predicate(this.value)) {\r\n return { path: Path.Empty, value: this.value };\r\n }\r\n else {\r\n if (relativePath.isEmpty()) {\r\n return null;\r\n }\r\n else {\r\n var front = relativePath.getFront();\r\n var child = this.children.get(front);\r\n if (child !== null) {\r\n var childExistingPathAndValue = child.findRootMostMatchingPathAndValue(relativePath.popFront(), predicate);\r\n if (childExistingPathAndValue != null) {\r\n var fullPath = new Path(front).child(childExistingPathAndValue.path);\r\n return { path: fullPath, value: childExistingPathAndValue.value };\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.findRootMostValueAndPath = function (relativePath) {\r\n return this.findRootMostMatchingPathAndValue(relativePath, function () { return true; });\r\n };\r\n /**\r\n * @param {!Path} relativePath\r\n * @return {!ImmutableTree.} The subtree at the given path\r\n */\r\n ImmutableTree.prototype.subtree = function (relativePath) {\r\n if (relativePath.isEmpty()) {\r\n return this;\r\n }\r\n else {\r\n var front = relativePath.getFront();\r\n var childTree = this.children.get(front);\r\n if (childTree !== null) {\r\n return childTree.subtree(relativePath.popFront());\r\n }\r\n else {\r\n return ImmutableTree.Empty;\r\n }\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.set = function (relativePath, toSet) {\r\n if (relativePath.isEmpty()) {\r\n return new ImmutableTree(toSet, this.children);\r\n }\r\n else {\r\n var front = relativePath.getFront();\r\n var child = this.children.get(front) || ImmutableTree.Empty;\r\n var newChild = child.set(relativePath.popFront(), toSet);\r\n var newChildren = this.children.insert(front, newChild);\r\n return new ImmutableTree(this.value, newChildren);\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.remove = function (relativePath) {\r\n if (relativePath.isEmpty()) {\r\n if (this.children.isEmpty()) {\r\n return ImmutableTree.Empty;\r\n }\r\n else {\r\n return new ImmutableTree(null, this.children);\r\n }\r\n }\r\n else {\r\n var front = relativePath.getFront();\r\n var child = this.children.get(front);\r\n if (child) {\r\n var newChild = child.remove(relativePath.popFront());\r\n var newChildren = void 0;\r\n if (newChild.isEmpty()) {\r\n newChildren = this.children.remove(front);\r\n }\r\n else {\r\n newChildren = this.children.insert(front, newChild);\r\n }\r\n if (this.value === null && newChildren.isEmpty()) {\r\n return ImmutableTree.Empty;\r\n }\r\n else {\r\n return new ImmutableTree(this.value, newChildren);\r\n }\r\n }\r\n else {\r\n return this;\r\n }\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.get = function (relativePath) {\r\n if (relativePath.isEmpty()) {\r\n return this.value;\r\n }\r\n else {\r\n var front = relativePath.getFront();\r\n var child = this.children.get(front);\r\n if (child) {\r\n return child.get(relativePath.popFront());\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.setTree = function (relativePath, newTree) {\r\n if (relativePath.isEmpty()) {\r\n return newTree;\r\n }\r\n else {\r\n var front = relativePath.getFront();\r\n var child = this.children.get(front) || ImmutableTree.Empty;\r\n var newChild = child.setTree(relativePath.popFront(), newTree);\r\n var newChildren = void 0;\r\n if (newChild.isEmpty()) {\r\n newChildren = this.children.remove(front);\r\n }\r\n else {\r\n newChildren = this.children.insert(front, newChild);\r\n }\r\n return new ImmutableTree(this.value, newChildren);\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.fold = function (fn) {\r\n return this.fold_(Path.Empty, fn);\r\n };\r\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 */\r\n ImmutableTree.prototype.fold_ = function (pathSoFar, fn) {\r\n var accum = {};\r\n this.children.inorderTraversal(function (childKey, childTree) {\r\n accum[childKey] = childTree.fold_(pathSoFar.child(childKey), fn);\r\n });\r\n return fn(pathSoFar, this.value, accum);\r\n };\r\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 */\r\n ImmutableTree.prototype.findOnPath = function (path, f) {\r\n return this.findOnPath_(path, Path.Empty, f);\r\n };\r\n ImmutableTree.prototype.findOnPath_ = function (pathToFollow, pathSoFar, f) {\r\n var result = this.value ? f(pathSoFar, this.value) : false;\r\n if (result) {\r\n return result;\r\n }\r\n else {\r\n if (pathToFollow.isEmpty()) {\r\n return null;\r\n }\r\n else {\r\n var front = pathToFollow.getFront();\r\n var nextChild = this.children.get(front);\r\n if (nextChild) {\r\n return nextChild.findOnPath_(pathToFollow.popFront(), pathSoFar.child(front), f);\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n }\r\n };\r\n /**\r\n *\r\n * @param {!Path} path\r\n * @param {!function(!Path, !T)} f\r\n * @returns {!ImmutableTree.}\r\n */\r\n ImmutableTree.prototype.foreachOnPath = function (path, f) {\r\n return this.foreachOnPath_(path, Path.Empty, f);\r\n };\r\n ImmutableTree.prototype.foreachOnPath_ = function (pathToFollow, currentRelativePath, f) {\r\n if (pathToFollow.isEmpty()) {\r\n return this;\r\n }\r\n else {\r\n if (this.value) {\r\n f(currentRelativePath, this.value);\r\n }\r\n var front = pathToFollow.getFront();\r\n var nextChild = this.children.get(front);\r\n if (nextChild) {\r\n return nextChild.foreachOnPath_(pathToFollow.popFront(), currentRelativePath.child(front), f);\r\n }\r\n else {\r\n return ImmutableTree.Empty;\r\n }\r\n }\r\n };\r\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 */\r\n ImmutableTree.prototype.foreach = function (f) {\r\n this.foreach_(Path.Empty, f);\r\n };\r\n ImmutableTree.prototype.foreach_ = function (currentRelativePath, f) {\r\n this.children.inorderTraversal(function (childName, childTree) {\r\n childTree.foreach_(currentRelativePath.child(childName), f);\r\n });\r\n if (this.value) {\r\n f(currentRelativePath, this.value);\r\n }\r\n };\r\n /**\r\n *\r\n * @param {function(string, !T)} f\r\n */\r\n ImmutableTree.prototype.foreachChild = function (f) {\r\n this.children.inorderTraversal(function (childName, childTree) {\r\n if (childTree.value) {\r\n f(childName, childTree.value);\r\n }\r\n });\r\n };\r\n ImmutableTree.Empty = new ImmutableTree(null);\r\n return ImmutableTree;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * @param {!OperationSource} source\r\n * @param {!Path} path\r\n * @constructor\r\n * @implements {Operation}\r\n */\r\nvar ListenComplete = /** @class */ (function () {\r\n function ListenComplete(source, path) {\r\n this.source = source;\r\n this.path = path;\r\n /** @inheritDoc */\r\n this.type = OperationType.LISTEN_COMPLETE;\r\n }\r\n ListenComplete.prototype.operationForChild = function (childName) {\r\n if (this.path.isEmpty()) {\r\n return new ListenComplete(this.source, Path.Empty);\r\n }\r\n else {\r\n return new ListenComplete(this.source, this.path.popFront());\r\n }\r\n };\r\n return ListenComplete;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar Overwrite = /** @class */ (function () {\r\n function Overwrite(source, path, snap) {\r\n this.source = source;\r\n this.path = path;\r\n this.snap = snap;\r\n /** @inheritDoc */\r\n this.type = OperationType.OVERWRITE;\r\n }\r\n Overwrite.prototype.operationForChild = function (childName) {\r\n if (this.path.isEmpty()) {\r\n return new Overwrite(this.source, Path.Empty, this.snap.getImmediateChild(childName));\r\n }\r\n else {\r\n return new Overwrite(this.source, this.path.popFront(), this.snap);\r\n }\r\n };\r\n return Overwrite;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar Merge = /** @class */ (function () {\r\n function Merge(\r\n /**@inheritDoc */ source, \r\n /**@inheritDoc */ path, \r\n /**@inheritDoc */ children) {\r\n this.source = source;\r\n this.path = path;\r\n this.children = children;\r\n /** @inheritDoc */\r\n this.type = OperationType.MERGE;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n Merge.prototype.operationForChild = function (childName) {\r\n if (this.path.isEmpty()) {\r\n var childTree = this.children.subtree(new Path(childName));\r\n if (childTree.isEmpty()) {\r\n // This child is unaffected\r\n return null;\r\n }\r\n else if (childTree.value) {\r\n // We have a snapshot for the child in question. This becomes an overwrite of the child.\r\n return new Overwrite(this.source, Path.Empty, childTree.value);\r\n }\r\n else {\r\n // This is a merge at a deeper level\r\n return new Merge(this.source, Path.Empty, childTree);\r\n }\r\n }\r\n else {\r\n assert(this.path.getFront() === childName, \"Can't get a merge for a child not on the path of the operation\");\r\n return new Merge(this.source, this.path.popFront(), this.children);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n Merge.prototype.toString = function () {\r\n return ('Operation(' +\r\n this.path +\r\n ': ' +\r\n this.source.toString() +\r\n ' merge: ' +\r\n this.children.toString() +\r\n ')');\r\n };\r\n return Merge;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar CacheNode = /** @class */ (function () {\r\n /**\r\n * @param {!Node} node_\r\n * @param {boolean} fullyInitialized_\r\n * @param {boolean} filtered_\r\n */\r\n function CacheNode(node_, fullyInitialized_, filtered_) {\r\n this.node_ = node_;\r\n this.fullyInitialized_ = fullyInitialized_;\r\n this.filtered_ = filtered_;\r\n }\r\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 */\r\n CacheNode.prototype.isFullyInitialized = function () {\r\n return this.fullyInitialized_;\r\n };\r\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 */\r\n CacheNode.prototype.isFiltered = function () {\r\n return this.filtered_;\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @return {boolean}\r\n */\r\n CacheNode.prototype.isCompleteForPath = function (path) {\r\n if (path.isEmpty()) {\r\n return this.isFullyInitialized() && !this.filtered_;\r\n }\r\n var childKey = path.getFront();\r\n return this.isCompleteForChild(childKey);\r\n };\r\n /**\r\n * @param {!string} key\r\n * @return {boolean}\r\n */\r\n CacheNode.prototype.isCompleteForChild = function (key) {\r\n return ((this.isFullyInitialized() && !this.filtered_) || this.node_.hasChild(key));\r\n };\r\n /**\r\n * @return {!Node}\r\n */\r\n CacheNode.prototype.getNode = function () {\r\n return this.node_;\r\n };\r\n return CacheNode;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar ViewCache = /** @class */ (function () {\r\n /**\r\n *\r\n * @param {!CacheNode} eventCache_\r\n * @param {!CacheNode} serverCache_\r\n */\r\n function ViewCache(eventCache_, serverCache_) {\r\n this.eventCache_ = eventCache_;\r\n this.serverCache_ = serverCache_;\r\n }\r\n /**\r\n * @param {!Node} eventSnap\r\n * @param {boolean} complete\r\n * @param {boolean} filtered\r\n * @return {!ViewCache}\r\n */\r\n ViewCache.prototype.updateEventSnap = function (eventSnap, complete, filtered) {\r\n return new ViewCache(new CacheNode(eventSnap, complete, filtered), this.serverCache_);\r\n };\r\n /**\r\n * @param {!Node} serverSnap\r\n * @param {boolean} complete\r\n * @param {boolean} filtered\r\n * @return {!ViewCache}\r\n */\r\n ViewCache.prototype.updateServerSnap = function (serverSnap, complete, filtered) {\r\n return new ViewCache(this.eventCache_, new CacheNode(serverSnap, complete, filtered));\r\n };\r\n /**\r\n * @return {!CacheNode}\r\n */\r\n ViewCache.prototype.getEventCache = function () {\r\n return this.eventCache_;\r\n };\r\n /**\r\n * @return {?Node}\r\n */\r\n ViewCache.prototype.getCompleteEventSnap = function () {\r\n return this.eventCache_.isFullyInitialized()\r\n ? this.eventCache_.getNode()\r\n : null;\r\n };\r\n /**\r\n * @return {!CacheNode}\r\n */\r\n ViewCache.prototype.getServerCache = function () {\r\n return this.serverCache_;\r\n };\r\n /**\r\n * @return {?Node}\r\n */\r\n ViewCache.prototype.getCompleteServerSnap = function () {\r\n return this.serverCache_.isFullyInitialized()\r\n ? this.serverCache_.getNode()\r\n : null;\r\n };\r\n /**\r\n * @const\r\n * @type {ViewCache}\r\n */\r\n ViewCache.Empty = new ViewCache(new CacheNode(ChildrenNode.EMPTY_NODE, \r\n /*fullyInitialized=*/ false, \r\n /*filtered=*/ false), new CacheNode(ChildrenNode.EMPTY_NODE, \r\n /*fullyInitialized=*/ false, \r\n /*filtered=*/ false));\r\n return ViewCache;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar Change = /** @class */ (function () {\r\n function Change(type, snapshotNode, childName, oldSnap, prevName) {\r\n this.type = type;\r\n this.snapshotNode = snapshotNode;\r\n this.childName = childName;\r\n this.oldSnap = oldSnap;\r\n this.prevName = prevName;\r\n }\r\n /**\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\r\n Change.valueChange = function (snapshot) {\r\n return new Change(Change.VALUE, snapshot);\r\n };\r\n /**\r\n * @param {string} childKey\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\r\n Change.childAddedChange = function (childKey, snapshot) {\r\n return new Change(Change.CHILD_ADDED, snapshot, childKey);\r\n };\r\n /**\r\n * @param {string} childKey\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\r\n Change.childRemovedChange = function (childKey, snapshot) {\r\n return new Change(Change.CHILD_REMOVED, snapshot, childKey);\r\n };\r\n /**\r\n * @param {string} childKey\r\n * @param {!Node} newSnapshot\r\n * @param {!Node} oldSnapshot\r\n * @return {!Change}\r\n */\r\n Change.childChangedChange = function (childKey, newSnapshot, oldSnapshot) {\r\n return new Change(Change.CHILD_CHANGED, newSnapshot, childKey, oldSnapshot);\r\n };\r\n /**\r\n * @param {string} childKey\r\n * @param {!Node} snapshot\r\n * @return {!Change}\r\n */\r\n Change.childMovedChange = function (childKey, snapshot) {\r\n return new Change(Change.CHILD_MOVED, snapshot, childKey);\r\n };\r\n //event types\r\n /** Event type for a child added */\r\n Change.CHILD_ADDED = 'child_added';\r\n /** Event type for a child removed */\r\n Change.CHILD_REMOVED = 'child_removed';\r\n /** Event type for a child changed */\r\n Change.CHILD_CHANGED = 'child_changed';\r\n /** Event type for a child moved */\r\n Change.CHILD_MOVED = 'child_moved';\r\n /** Event type for a value change */\r\n Change.VALUE = 'value';\r\n return Change;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar IndexedFilter = /** @class */ (function () {\r\n function IndexedFilter(index_) {\r\n this.index_ = index_;\r\n }\r\n IndexedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {\r\n assert(snap.isIndexed(this.index_), 'A node must be indexed if only a child is updated');\r\n var oldChild = snap.getImmediateChild(key);\r\n // Check if anything actually changed.\r\n if (oldChild.getChild(affectedPath).equals(newChild.getChild(affectedPath))) {\r\n // There's an edge case where a child can enter or leave the view because affectedPath was set to null.\r\n // In this case, affectedPath will appear null in both the old and new snapshots. So we need\r\n // to avoid treating these cases as \"nothing changed.\"\r\n if (oldChild.isEmpty() == newChild.isEmpty()) {\r\n // Nothing changed.\r\n // This assert should be valid, but it's expensive (can dominate perf testing) so don't actually do it.\r\n //assert(oldChild.equals(newChild), 'Old and new snapshots should be equal.');\r\n return snap;\r\n }\r\n }\r\n if (optChangeAccumulator != null) {\r\n if (newChild.isEmpty()) {\r\n if (snap.hasChild(key)) {\r\n optChangeAccumulator.trackChildChange(Change.childRemovedChange(key, oldChild));\r\n }\r\n else {\r\n assert(snap.isLeafNode(), 'A child remove without an old child only makes sense on a leaf node');\r\n }\r\n }\r\n else if (oldChild.isEmpty()) {\r\n optChangeAccumulator.trackChildChange(Change.childAddedChange(key, newChild));\r\n }\r\n else {\r\n optChangeAccumulator.trackChildChange(Change.childChangedChange(key, newChild, oldChild));\r\n }\r\n }\r\n if (snap.isLeafNode() && newChild.isEmpty()) {\r\n return snap;\r\n }\r\n else {\r\n // Make sure the node is indexed\r\n return snap.updateImmediateChild(key, newChild).withIndex(this.index_);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n IndexedFilter.prototype.updateFullNode = function (oldSnap, newSnap, optChangeAccumulator) {\r\n if (optChangeAccumulator != null) {\r\n if (!oldSnap.isLeafNode()) {\r\n oldSnap.forEachChild(PRIORITY_INDEX, function (key, childNode) {\r\n if (!newSnap.hasChild(key)) {\r\n optChangeAccumulator.trackChildChange(Change.childRemovedChange(key, childNode));\r\n }\r\n });\r\n }\r\n if (!newSnap.isLeafNode()) {\r\n newSnap.forEachChild(PRIORITY_INDEX, function (key, childNode) {\r\n if (oldSnap.hasChild(key)) {\r\n var oldChild = oldSnap.getImmediateChild(key);\r\n if (!oldChild.equals(childNode)) {\r\n optChangeAccumulator.trackChildChange(Change.childChangedChange(key, childNode, oldChild));\r\n }\r\n }\r\n else {\r\n optChangeAccumulator.trackChildChange(Change.childAddedChange(key, childNode));\r\n }\r\n });\r\n }\r\n }\r\n return newSnap.withIndex(this.index_);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n IndexedFilter.prototype.updatePriority = function (oldSnap, newPriority) {\r\n if (oldSnap.isEmpty()) {\r\n return ChildrenNode.EMPTY_NODE;\r\n }\r\n else {\r\n return oldSnap.updatePriority(newPriority);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n IndexedFilter.prototype.filtersNodes = function () {\r\n return false;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n IndexedFilter.prototype.getIndexedFilter = function () {\r\n return this;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n IndexedFilter.prototype.getIndex = function () {\r\n return this.index_;\r\n };\r\n return IndexedFilter;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * @constructor\r\n */\r\nvar ChildChangeAccumulator = /** @class */ (function () {\r\n function ChildChangeAccumulator() {\r\n this.changeMap_ = {};\r\n }\r\n /**\r\n * @param {!Change} change\r\n */\r\n ChildChangeAccumulator.prototype.trackChildChange = function (change) {\r\n var type = change.type;\r\n var childKey /** @type {!string} */ = change.childName;\r\n assert(type == Change.CHILD_ADDED ||\r\n type == Change.CHILD_CHANGED ||\r\n type == Change.CHILD_REMOVED, 'Only child changes supported for tracking');\r\n assert(childKey !== '.priority', 'Only non-priority child changes can be tracked.');\r\n var oldChange = safeGet(this.changeMap_, childKey);\r\n if (oldChange) {\r\n var oldType = oldChange.type;\r\n if (type == Change.CHILD_ADDED && oldType == Change.CHILD_REMOVED) {\r\n this.changeMap_[childKey] = Change.childChangedChange(childKey, change.snapshotNode, oldChange.snapshotNode);\r\n }\r\n else if (type == Change.CHILD_REMOVED &&\r\n oldType == Change.CHILD_ADDED) {\r\n delete this.changeMap_[childKey];\r\n }\r\n else if (type == Change.CHILD_REMOVED &&\r\n oldType == Change.CHILD_CHANGED) {\r\n this.changeMap_[childKey] = Change.childRemovedChange(childKey, oldChange.oldSnap);\r\n }\r\n else if (type == Change.CHILD_CHANGED &&\r\n oldType == Change.CHILD_ADDED) {\r\n this.changeMap_[childKey] = Change.childAddedChange(childKey, change.snapshotNode);\r\n }\r\n else if (type == Change.CHILD_CHANGED &&\r\n oldType == Change.CHILD_CHANGED) {\r\n this.changeMap_[childKey] = Change.childChangedChange(childKey, change.snapshotNode, oldChange.oldSnap);\r\n }\r\n else {\r\n throw assertionError('Illegal combination of changes: ' +\r\n change +\r\n ' occurred after ' +\r\n oldChange);\r\n }\r\n }\r\n else {\r\n this.changeMap_[childKey] = change;\r\n }\r\n };\r\n /**\r\n * @return {!Array.}\r\n */\r\n ChildChangeAccumulator.prototype.getChanges = function () {\r\n return getValues(this.changeMap_);\r\n };\r\n return ChildChangeAccumulator;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar NoCompleteChildSource_ = /** @class */ (function () {\r\n function NoCompleteChildSource_() {\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n NoCompleteChildSource_.prototype.getCompleteChild = function (childKey) {\r\n return null;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n NoCompleteChildSource_.prototype.getChildAfterChild = function (index, child, reverse) {\r\n return null;\r\n };\r\n return NoCompleteChildSource_;\r\n}());\r\n/**\r\n * Singleton instance.\r\n * @const\r\n * @type {!CompleteChildSource}\r\n */\r\nvar NO_COMPLETE_CHILD_SOURCE = new NoCompleteChildSource_();\r\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 */\r\nvar WriteTreeCompleteChildSource = /** @class */ (function () {\r\n /**\r\n * @param {!WriteTreeRef} writes_\r\n * @param {!ViewCache} viewCache_\r\n * @param {?Node} optCompleteServerCache_\r\n */\r\n function WriteTreeCompleteChildSource(writes_, viewCache_, optCompleteServerCache_) {\r\n if (optCompleteServerCache_ === void 0) { optCompleteServerCache_ = null; }\r\n this.writes_ = writes_;\r\n this.viewCache_ = viewCache_;\r\n this.optCompleteServerCache_ = optCompleteServerCache_;\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n WriteTreeCompleteChildSource.prototype.getCompleteChild = function (childKey) {\r\n var node = this.viewCache_.getEventCache();\r\n if (node.isCompleteForChild(childKey)) {\r\n return node.getNode().getImmediateChild(childKey);\r\n }\r\n else {\r\n var serverNode = this.optCompleteServerCache_ != null\r\n ? new CacheNode(this.optCompleteServerCache_, true, false)\r\n : this.viewCache_.getServerCache();\r\n return this.writes_.calcCompleteChild(childKey, serverNode);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n WriteTreeCompleteChildSource.prototype.getChildAfterChild = function (index, child, reverse) {\r\n var completeServerData = this.optCompleteServerCache_ != null\r\n ? this.optCompleteServerCache_\r\n : this.viewCache_.getCompleteServerSnap();\r\n var nodes = this.writes_.calcIndexedSlice(completeServerData, child, 1, reverse, index);\r\n if (nodes.length === 0) {\r\n return null;\r\n }\r\n else {\r\n return nodes[0];\r\n }\r\n };\r\n return WriteTreeCompleteChildSource;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * @constructor\r\n * @struct\r\n */\r\nvar ProcessorResult = /** @class */ (function () {\r\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {!Array.} changes\r\n */\r\n function ProcessorResult(viewCache, changes) {\r\n this.viewCache = viewCache;\r\n this.changes = changes;\r\n }\r\n return ProcessorResult;\r\n}());\r\n/**\r\n * @constructor\r\n */\r\nvar ViewProcessor = /** @class */ (function () {\r\n /**\r\n * @param {!NodeFilter} filter_\r\n */\r\n function ViewProcessor(filter_) {\r\n this.filter_ = filter_;\r\n }\r\n /**\r\n * @param {!ViewCache} viewCache\r\n */\r\n ViewProcessor.prototype.assertIndexed = function (viewCache) {\r\n assert(viewCache\r\n .getEventCache()\r\n .getNode()\r\n .isIndexed(this.filter_.getIndex()), 'Event snap not indexed');\r\n assert(viewCache\r\n .getServerCache()\r\n .getNode()\r\n .isIndexed(this.filter_.getIndex()), 'Server snap not indexed');\r\n };\r\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 */\r\n ViewProcessor.prototype.applyOperation = function (oldViewCache, operation, writesCache, completeCache) {\r\n var accumulator = new ChildChangeAccumulator();\r\n var newViewCache, filterServerNode;\r\n if (operation.type === OperationType.OVERWRITE) {\r\n var overwrite = operation;\r\n if (overwrite.source.fromUser) {\r\n newViewCache = this.applyUserOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, completeCache, accumulator);\r\n }\r\n else {\r\n assert(overwrite.source.fromServer, 'Unknown source.');\r\n // We filter the node if it's a tagged update or the node has been previously filtered and the\r\n // update is not at the root in which case it is ok (and necessary) to mark the node unfiltered\r\n // again\r\n filterServerNode =\r\n overwrite.source.tagged ||\r\n (oldViewCache.getServerCache().isFiltered() &&\r\n !overwrite.path.isEmpty());\r\n newViewCache = this.applyServerOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, completeCache, filterServerNode, accumulator);\r\n }\r\n }\r\n else if (operation.type === OperationType.MERGE) {\r\n var merge = operation;\r\n if (merge.source.fromUser) {\r\n newViewCache = this.applyUserMerge_(oldViewCache, merge.path, merge.children, writesCache, completeCache, accumulator);\r\n }\r\n else {\r\n assert(merge.source.fromServer, 'Unknown source.');\r\n // We filter the node if it's a tagged update or the node has been previously filtered\r\n filterServerNode =\r\n merge.source.tagged || oldViewCache.getServerCache().isFiltered();\r\n newViewCache = this.applyServerMerge_(oldViewCache, merge.path, merge.children, writesCache, completeCache, filterServerNode, accumulator);\r\n }\r\n }\r\n else if (operation.type === OperationType.ACK_USER_WRITE) {\r\n var ackUserWrite = operation;\r\n if (!ackUserWrite.revert) {\r\n newViewCache = this.ackUserWrite_(oldViewCache, ackUserWrite.path, ackUserWrite.affectedTree, writesCache, completeCache, accumulator);\r\n }\r\n else {\r\n newViewCache = this.revertUserWrite_(oldViewCache, ackUserWrite.path, writesCache, completeCache, accumulator);\r\n }\r\n }\r\n else if (operation.type === OperationType.LISTEN_COMPLETE) {\r\n newViewCache = this.listenComplete_(oldViewCache, operation.path, writesCache, accumulator);\r\n }\r\n else {\r\n throw assertionError('Unknown operation type: ' + operation.type);\r\n }\r\n var changes = accumulator.getChanges();\r\n ViewProcessor.maybeAddValueEvent_(oldViewCache, newViewCache, changes);\r\n return new ProcessorResult(newViewCache, changes);\r\n };\r\n /**\r\n * @param {!ViewCache} oldViewCache\r\n * @param {!ViewCache} newViewCache\r\n * @param {!Array.} accumulator\r\n * @private\r\n */\r\n ViewProcessor.maybeAddValueEvent_ = function (oldViewCache, newViewCache, accumulator) {\r\n var eventSnap = newViewCache.getEventCache();\r\n if (eventSnap.isFullyInitialized()) {\r\n var isLeafOrEmpty = eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty();\r\n var oldCompleteSnap = oldViewCache.getCompleteEventSnap();\r\n if (accumulator.length > 0 ||\r\n !oldViewCache.getEventCache().isFullyInitialized() ||\r\n (isLeafOrEmpty &&\r\n !eventSnap\r\n .getNode()\r\n .equals(/** @type {!Node} */ (oldCompleteSnap))) ||\r\n !eventSnap\r\n .getNode()\r\n .getPriority()\r\n .equals(oldCompleteSnap.getPriority())) {\r\n accumulator.push(Change.valueChange(\r\n /** @type {!Node} */ newViewCache.getCompleteEventSnap()));\r\n }\r\n }\r\n };\r\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 */\r\n ViewProcessor.prototype.generateEventCacheAfterServerEvent_ = function (viewCache, changePath, writesCache, source, accumulator) {\r\n var oldEventSnap = viewCache.getEventCache();\r\n if (writesCache.shadowingWrite(changePath) != null) {\r\n // we have a shadowing write, ignore changes\r\n return viewCache;\r\n }\r\n else {\r\n var newEventCache = void 0, serverNode = void 0;\r\n if (changePath.isEmpty()) {\r\n // TODO: figure out how this plays with \"sliding ack windows\"\r\n assert(viewCache.getServerCache().isFullyInitialized(), 'If change path is empty, we must have complete server data');\r\n if (viewCache.getServerCache().isFiltered()) {\r\n // We need to special case this, because we need to only apply writes to complete children, or\r\n // we might end up raising events for incomplete children. If the server data is filtered deep\r\n // writes cannot be guaranteed to be complete\r\n var serverCache = viewCache.getCompleteServerSnap();\r\n var completeChildren = serverCache instanceof ChildrenNode\r\n ? serverCache\r\n : ChildrenNode.EMPTY_NODE;\r\n var completeEventChildren = writesCache.calcCompleteEventChildren(completeChildren);\r\n newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeEventChildren, accumulator);\r\n }\r\n else {\r\n var completeNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\r\n newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeNode, accumulator);\r\n }\r\n }\r\n else {\r\n var childKey = changePath.getFront();\r\n if (childKey == '.priority') {\r\n assert(changePath.getLength() == 1, \"Can't have a priority with additional path components\");\r\n var oldEventNode = oldEventSnap.getNode();\r\n serverNode = viewCache.getServerCache().getNode();\r\n // we might have overwrites for this priority\r\n var updatedPriority = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventNode, serverNode);\r\n if (updatedPriority != null) {\r\n newEventCache = this.filter_.updatePriority(oldEventNode, updatedPriority);\r\n }\r\n else {\r\n // priority didn't change, keep old node\r\n newEventCache = oldEventSnap.getNode();\r\n }\r\n }\r\n else {\r\n var childChangePath = changePath.popFront();\r\n // update child\r\n var newEventChild = void 0;\r\n if (oldEventSnap.isCompleteForChild(childKey)) {\r\n serverNode = viewCache.getServerCache().getNode();\r\n var eventChildUpdate = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventSnap.getNode(), serverNode);\r\n if (eventChildUpdate != null) {\r\n newEventChild = oldEventSnap\r\n .getNode()\r\n .getImmediateChild(childKey)\r\n .updateChild(childChangePath, eventChildUpdate);\r\n }\r\n else {\r\n // Nothing changed, just keep the old child\r\n newEventChild = oldEventSnap\r\n .getNode()\r\n .getImmediateChild(childKey);\r\n }\r\n }\r\n else {\r\n newEventChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());\r\n }\r\n if (newEventChild != null) {\r\n newEventCache = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newEventChild, childChangePath, source, accumulator);\r\n }\r\n else {\r\n // no complete child available or no change\r\n newEventCache = oldEventSnap.getNode();\r\n }\r\n }\r\n }\r\n return viewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized() || changePath.isEmpty(), this.filter_.filtersNodes());\r\n }\r\n };\r\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 */\r\n ViewProcessor.prototype.applyServerOverwrite_ = function (oldViewCache, changePath, changedSnap, writesCache, completeCache, filterServerNode, accumulator) {\r\n var oldServerSnap = oldViewCache.getServerCache();\r\n var newServerCache;\r\n var serverFilter = filterServerNode\r\n ? this.filter_\r\n : this.filter_.getIndexedFilter();\r\n if (changePath.isEmpty()) {\r\n newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), changedSnap, null);\r\n }\r\n else if (serverFilter.filtersNodes() && !oldServerSnap.isFiltered()) {\r\n // we want to filter the server node, but we didn't filter the server node yet, so simulate a full update\r\n var newServerNode = oldServerSnap\r\n .getNode()\r\n .updateChild(changePath, changedSnap);\r\n newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), newServerNode, null);\r\n }\r\n else {\r\n var childKey = changePath.getFront();\r\n if (!oldServerSnap.isCompleteForPath(changePath) &&\r\n changePath.getLength() > 1) {\r\n // We don't update incomplete nodes with updates intended for other listeners\r\n return oldViewCache;\r\n }\r\n var childChangePath = changePath.popFront();\r\n var childNode = oldServerSnap.getNode().getImmediateChild(childKey);\r\n var newChildNode = childNode.updateChild(childChangePath, changedSnap);\r\n if (childKey == '.priority') {\r\n newServerCache = serverFilter.updatePriority(oldServerSnap.getNode(), newChildNode);\r\n }\r\n else {\r\n newServerCache = serverFilter.updateChild(oldServerSnap.getNode(), childKey, newChildNode, childChangePath, NO_COMPLETE_CHILD_SOURCE, null);\r\n }\r\n }\r\n var newViewCache = oldViewCache.updateServerSnap(newServerCache, oldServerSnap.isFullyInitialized() || changePath.isEmpty(), serverFilter.filtersNodes());\r\n var source = new WriteTreeCompleteChildSource(writesCache, newViewCache, completeCache);\r\n return this.generateEventCacheAfterServerEvent_(newViewCache, changePath, writesCache, source, accumulator);\r\n };\r\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 */\r\n ViewProcessor.prototype.applyUserOverwrite_ = function (oldViewCache, changePath, changedSnap, writesCache, completeCache, accumulator) {\r\n var oldEventSnap = oldViewCache.getEventCache();\r\n var newViewCache, newEventCache;\r\n var source = new WriteTreeCompleteChildSource(writesCache, oldViewCache, completeCache);\r\n if (changePath.isEmpty()) {\r\n newEventCache = this.filter_.updateFullNode(oldViewCache.getEventCache().getNode(), changedSnap, accumulator);\r\n newViewCache = oldViewCache.updateEventSnap(newEventCache, true, this.filter_.filtersNodes());\r\n }\r\n else {\r\n var childKey = changePath.getFront();\r\n if (childKey === '.priority') {\r\n newEventCache = this.filter_.updatePriority(oldViewCache.getEventCache().getNode(), changedSnap);\r\n newViewCache = oldViewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized(), oldEventSnap.isFiltered());\r\n }\r\n else {\r\n var childChangePath = changePath.popFront();\r\n var oldChild = oldEventSnap.getNode().getImmediateChild(childKey);\r\n var newChild = void 0;\r\n if (childChangePath.isEmpty()) {\r\n // Child overwrite, we can replace the child\r\n newChild = changedSnap;\r\n }\r\n else {\r\n var childNode = source.getCompleteChild(childKey);\r\n if (childNode != null) {\r\n if (childChangePath.getBack() === '.priority' &&\r\n childNode.getChild(childChangePath.parent()).isEmpty()) {\r\n // This is a priority update on an empty node. If this node exists on the server, the\r\n // server will send down the priority in the update, so ignore for now\r\n newChild = childNode;\r\n }\r\n else {\r\n newChild = childNode.updateChild(childChangePath, changedSnap);\r\n }\r\n }\r\n else {\r\n // There is no complete child node available\r\n newChild = ChildrenNode.EMPTY_NODE;\r\n }\r\n }\r\n if (!oldChild.equals(newChild)) {\r\n var newEventSnap = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newChild, childChangePath, source, accumulator);\r\n newViewCache = oldViewCache.updateEventSnap(newEventSnap, oldEventSnap.isFullyInitialized(), this.filter_.filtersNodes());\r\n }\r\n else {\r\n newViewCache = oldViewCache;\r\n }\r\n }\r\n }\r\n return newViewCache;\r\n };\r\n /**\r\n * @param {!ViewCache} viewCache\r\n * @param {string} childKey\r\n * @return {boolean}\r\n * @private\r\n */\r\n ViewProcessor.cacheHasChild_ = function (viewCache, childKey) {\r\n return viewCache.getEventCache().isCompleteForChild(childKey);\r\n };\r\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 */\r\n ViewProcessor.prototype.applyUserMerge_ = function (viewCache, path, changedChildren, writesCache, serverCache, accumulator) {\r\n var _this = this;\r\n // HACK: In the case of a limit query, there may be some changes that bump things out of the\r\n // window leaving room for new items. It's important we process these changes first, so we\r\n // iterate the changes twice, first processing any that affect items currently in view.\r\n // TODO: I consider an item \"in view\" if cacheHasChild is true, which checks both the server\r\n // and event snap. I'm not sure if this will result in edge cases when a child is in one but\r\n // not the other.\r\n var curViewCache = viewCache;\r\n changedChildren.foreach(function (relativePath, childNode) {\r\n var writePath = path.child(relativePath);\r\n if (ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\r\n curViewCache = _this.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache, serverCache, accumulator);\r\n }\r\n });\r\n changedChildren.foreach(function (relativePath, childNode) {\r\n var writePath = path.child(relativePath);\r\n if (!ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {\r\n curViewCache = _this.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache, serverCache, accumulator);\r\n }\r\n });\r\n return curViewCache;\r\n };\r\n /**\r\n * @param {!Node} node\r\n * @param {ImmutableTree.} merge\r\n * @return {!Node}\r\n * @private\r\n */\r\n ViewProcessor.prototype.applyMerge_ = function (node, merge) {\r\n merge.foreach(function (relativePath, childNode) {\r\n node = node.updateChild(relativePath, childNode);\r\n });\r\n return node;\r\n };\r\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 */\r\n ViewProcessor.prototype.applyServerMerge_ = function (viewCache, path, changedChildren, writesCache, serverCache, filterServerNode, accumulator) {\r\n var _this = this;\r\n // If we don't have a cache yet, this merge was intended for a previously listen in the same location. Ignore it and\r\n // wait for the complete data update coming soon.\r\n if (viewCache\r\n .getServerCache()\r\n .getNode()\r\n .isEmpty() &&\r\n !viewCache.getServerCache().isFullyInitialized()) {\r\n return viewCache;\r\n }\r\n // HACK: In the case of a limit query, there may be some changes that bump things out of the\r\n // window leaving room for new items. It's important we process these changes first, so we\r\n // iterate the changes twice, first processing any that affect items currently in view.\r\n // TODO: I consider an item \"in view\" if cacheHasChild is true, which checks both the server\r\n // and event snap. I'm not sure if this will result in edge cases when a child is in one but\r\n // not the other.\r\n var curViewCache = viewCache;\r\n var viewMergeTree;\r\n if (path.isEmpty()) {\r\n viewMergeTree = changedChildren;\r\n }\r\n else {\r\n viewMergeTree = ImmutableTree.Empty.setTree(path, changedChildren);\r\n }\r\n var serverNode = viewCache.getServerCache().getNode();\r\n viewMergeTree.children.inorderTraversal(function (childKey, childTree) {\r\n if (serverNode.hasChild(childKey)) {\r\n var serverChild = viewCache\r\n .getServerCache()\r\n .getNode()\r\n .getImmediateChild(childKey);\r\n var newChild = _this.applyMerge_(serverChild, childTree);\r\n curViewCache = _this.applyServerOverwrite_(curViewCache, new Path(childKey), newChild, writesCache, serverCache, filterServerNode, accumulator);\r\n }\r\n });\r\n viewMergeTree.children.inorderTraversal(function (childKey, childMergeTree) {\r\n var isUnknownDeepMerge = !viewCache.getServerCache().isCompleteForChild(childKey) &&\r\n childMergeTree.value == null;\r\n if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {\r\n var serverChild = viewCache\r\n .getServerCache()\r\n .getNode()\r\n .getImmediateChild(childKey);\r\n var newChild = _this.applyMerge_(serverChild, childMergeTree);\r\n curViewCache = _this.applyServerOverwrite_(curViewCache, new Path(childKey), newChild, writesCache, serverCache, filterServerNode, accumulator);\r\n }\r\n });\r\n return curViewCache;\r\n };\r\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 */\r\n ViewProcessor.prototype.ackUserWrite_ = function (viewCache, ackPath, affectedTree, writesCache, completeCache, accumulator) {\r\n if (writesCache.shadowingWrite(ackPath) != null) {\r\n return viewCache;\r\n }\r\n // Only filter server node if it is currently filtered\r\n var filterServerNode = viewCache.getServerCache().isFiltered();\r\n // Essentially we'll just get our existing server cache for the affected paths and re-apply it as a server update\r\n // now that it won't be shadowed.\r\n var serverCache = viewCache.getServerCache();\r\n if (affectedTree.value != null) {\r\n // This is an overwrite.\r\n if ((ackPath.isEmpty() && serverCache.isFullyInitialized()) ||\r\n serverCache.isCompleteForPath(ackPath)) {\r\n return this.applyServerOverwrite_(viewCache, ackPath, serverCache.getNode().getChild(ackPath), writesCache, completeCache, filterServerNode, accumulator);\r\n }\r\n else if (ackPath.isEmpty()) {\r\n // This is a goofy edge case where we are acking data at this location but don't have full data. We\r\n // should just re-apply whatever we have in our cache as a merge.\r\n var changedChildren_1 = ImmutableTree.Empty;\r\n serverCache.getNode().forEachChild(KEY_INDEX, function (name, node) {\r\n changedChildren_1 = changedChildren_1.set(new Path(name), node);\r\n });\r\n return this.applyServerMerge_(viewCache, ackPath, changedChildren_1, writesCache, completeCache, filterServerNode, accumulator);\r\n }\r\n else {\r\n return viewCache;\r\n }\r\n }\r\n else {\r\n // This is a merge.\r\n var changedChildren_2 = ImmutableTree.Empty;\r\n affectedTree.foreach(function (mergePath, value) {\r\n var serverCachePath = ackPath.child(mergePath);\r\n if (serverCache.isCompleteForPath(serverCachePath)) {\r\n changedChildren_2 = changedChildren_2.set(mergePath, serverCache.getNode().getChild(serverCachePath));\r\n }\r\n });\r\n return this.applyServerMerge_(viewCache, ackPath, changedChildren_2, writesCache, completeCache, filterServerNode, accumulator);\r\n }\r\n };\r\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 */\r\n ViewProcessor.prototype.listenComplete_ = function (viewCache, path, writesCache, accumulator) {\r\n var oldServerNode = viewCache.getServerCache();\r\n var newViewCache = viewCache.updateServerSnap(oldServerNode.getNode(), oldServerNode.isFullyInitialized() || path.isEmpty(), oldServerNode.isFiltered());\r\n return this.generateEventCacheAfterServerEvent_(newViewCache, path, writesCache, NO_COMPLETE_CHILD_SOURCE, accumulator);\r\n };\r\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 */\r\n ViewProcessor.prototype.revertUserWrite_ = function (viewCache, path, writesCache, completeServerCache, accumulator) {\r\n var complete;\r\n if (writesCache.shadowingWrite(path) != null) {\r\n return viewCache;\r\n }\r\n else {\r\n var source = new WriteTreeCompleteChildSource(writesCache, viewCache, completeServerCache);\r\n var oldEventCache = viewCache.getEventCache().getNode();\r\n var newEventCache = void 0;\r\n if (path.isEmpty() || path.getFront() === '.priority') {\r\n var newNode = void 0;\r\n if (viewCache.getServerCache().isFullyInitialized()) {\r\n newNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\r\n }\r\n else {\r\n var serverChildren = viewCache.getServerCache().getNode();\r\n assert(serverChildren instanceof ChildrenNode, 'serverChildren would be complete if leaf node');\r\n newNode = writesCache.calcCompleteEventChildren(serverChildren);\r\n }\r\n newNode = newNode;\r\n newEventCache = this.filter_.updateFullNode(oldEventCache, newNode, accumulator);\r\n }\r\n else {\r\n var childKey = path.getFront();\r\n var newChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());\r\n if (newChild == null &&\r\n viewCache.getServerCache().isCompleteForChild(childKey)) {\r\n newChild = oldEventCache.getImmediateChild(childKey);\r\n }\r\n if (newChild != null) {\r\n newEventCache = this.filter_.updateChild(oldEventCache, childKey, newChild, path.popFront(), source, accumulator);\r\n }\r\n else if (viewCache\r\n .getEventCache()\r\n .getNode()\r\n .hasChild(childKey)) {\r\n // No complete child available, delete the existing one, if any\r\n newEventCache = this.filter_.updateChild(oldEventCache, childKey, ChildrenNode.EMPTY_NODE, path.popFront(), source, accumulator);\r\n }\r\n else {\r\n newEventCache = oldEventCache;\r\n }\r\n if (newEventCache.isEmpty() &&\r\n viewCache.getServerCache().isFullyInitialized()) {\r\n // We might have reverted all child writes. Maybe the old event was a leaf node\r\n complete = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());\r\n if (complete.isLeafNode()) {\r\n newEventCache = this.filter_.updateFullNode(newEventCache, complete, accumulator);\r\n }\r\n }\r\n }\r\n complete =\r\n viewCache.getServerCache().isFullyInitialized() ||\r\n writesCache.shadowingWrite(Path.Empty) != null;\r\n return viewCache.updateEventSnap(newEventCache, complete, this.filter_.filtersNodes());\r\n }\r\n };\r\n return ViewProcessor;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar EventGenerator = /** @class */ (function () {\r\n /**\r\n *\r\n * @param {!Query} query_\r\n */\r\n function EventGenerator(query_) {\r\n this.query_ = query_;\r\n /**\r\n * @private\r\n * @type {!Index}\r\n */\r\n this.index_ = this.query_.getQueryParams().getIndex();\r\n }\r\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 */\r\n EventGenerator.prototype.generateEventsForChanges = function (changes, eventCache, eventRegistrations) {\r\n var _this = this;\r\n var events = [];\r\n var moves = [];\r\n changes.forEach(function (change) {\r\n if (change.type === Change.CHILD_CHANGED &&\r\n _this.index_.indexedValueChanged(change.oldSnap, change.snapshotNode)) {\r\n moves.push(Change.childMovedChange(change.childName, change.snapshotNode));\r\n }\r\n });\r\n this.generateEventsForType_(events, Change.CHILD_REMOVED, changes, eventRegistrations, eventCache);\r\n this.generateEventsForType_(events, Change.CHILD_ADDED, changes, eventRegistrations, eventCache);\r\n this.generateEventsForType_(events, Change.CHILD_MOVED, moves, eventRegistrations, eventCache);\r\n this.generateEventsForType_(events, Change.CHILD_CHANGED, changes, eventRegistrations, eventCache);\r\n this.generateEventsForType_(events, Change.VALUE, changes, eventRegistrations, eventCache);\r\n return events;\r\n };\r\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 */\r\n EventGenerator.prototype.generateEventsForType_ = function (events, eventType, changes, registrations, eventCache) {\r\n var _this = this;\r\n var filteredChanges = changes.filter(function (change) { return change.type === eventType; });\r\n filteredChanges.sort(this.compareChanges_.bind(this));\r\n filteredChanges.forEach(function (change) {\r\n var materializedChange = _this.materializeSingleChange_(change, eventCache);\r\n registrations.forEach(function (registration) {\r\n if (registration.respondsTo(change.type)) {\r\n events.push(registration.createEvent(materializedChange, _this.query_));\r\n }\r\n });\r\n });\r\n };\r\n /**\r\n * @param {!Change} change\r\n * @param {!Node} eventCache\r\n * @return {!Change}\r\n * @private\r\n */\r\n EventGenerator.prototype.materializeSingleChange_ = function (change, eventCache) {\r\n if (change.type === 'value' || change.type === 'child_removed') {\r\n return change;\r\n }\r\n else {\r\n change.prevName = eventCache.getPredecessorChildName(\r\n /** @type {!string} */\r\n change.childName, change.snapshotNode, this.index_);\r\n return change;\r\n }\r\n };\r\n /**\r\n * @param {!Change} a\r\n * @param {!Change} b\r\n * @return {number}\r\n * @private\r\n */\r\n EventGenerator.prototype.compareChanges_ = function (a, b) {\r\n if (a.childName == null || b.childName == null) {\r\n throw assertionError('Should only compare child_ events.');\r\n }\r\n var aWrapped = new NamedNode(a.childName, a.snapshotNode);\r\n var bWrapped = new NamedNode(b.childName, b.snapshotNode);\r\n return this.index_.compare(aWrapped, bWrapped);\r\n };\r\n return EventGenerator;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar View = /** @class */ (function () {\r\n /**\r\n *\r\n * @param {!Query} query_\r\n * @param {!ViewCache} initialViewCache\r\n */\r\n function View(query_, initialViewCache) {\r\n this.query_ = query_;\r\n this.eventRegistrations_ = [];\r\n var params = this.query_.getQueryParams();\r\n var indexFilter = new IndexedFilter(params.getIndex());\r\n var filter = params.getNodeFilter();\r\n /**\r\n * @type {ViewProcessor}\r\n * @private\r\n */\r\n this.processor_ = new ViewProcessor(filter);\r\n var initialServerCache = initialViewCache.getServerCache();\r\n var initialEventCache = initialViewCache.getEventCache();\r\n // Don't filter server node with other filter than index, wait for tagged listen\r\n var serverSnap = indexFilter.updateFullNode(ChildrenNode.EMPTY_NODE, initialServerCache.getNode(), null);\r\n var eventSnap = filter.updateFullNode(ChildrenNode.EMPTY_NODE, initialEventCache.getNode(), null);\r\n var newServerCache = new CacheNode(serverSnap, initialServerCache.isFullyInitialized(), indexFilter.filtersNodes());\r\n var newEventCache = new CacheNode(eventSnap, initialEventCache.isFullyInitialized(), filter.filtersNodes());\r\n /**\r\n * @type {!ViewCache}\r\n * @private\r\n */\r\n this.viewCache_ = new ViewCache(newEventCache, newServerCache);\r\n /**\r\n * @type {!EventGenerator}\r\n * @private\r\n */\r\n this.eventGenerator_ = new EventGenerator(this.query_);\r\n }\r\n /**\r\n * @return {!Query}\r\n */\r\n View.prototype.getQuery = function () {\r\n return this.query_;\r\n };\r\n /**\r\n * @return {?Node}\r\n */\r\n View.prototype.getServerCache = function () {\r\n return this.viewCache_.getServerCache().getNode();\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @return {?Node}\r\n */\r\n View.prototype.getCompleteServerCache = function (path) {\r\n var cache = this.viewCache_.getCompleteServerSnap();\r\n if (cache) {\r\n // If this isn't a \"loadsAllData\" view, then cache isn't actually a complete cache and\r\n // we need to see if it contains the child we're interested in.\r\n if (this.query_.getQueryParams().loadsAllData() ||\r\n (!path.isEmpty() && !cache.getImmediateChild(path.getFront()).isEmpty())) {\r\n return cache.getChild(path);\r\n }\r\n }\r\n return null;\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n View.prototype.isEmpty = function () {\r\n return this.eventRegistrations_.length === 0;\r\n };\r\n /**\r\n * @param {!EventRegistration} eventRegistration\r\n */\r\n View.prototype.addEventRegistration = function (eventRegistration) {\r\n this.eventRegistrations_.push(eventRegistration);\r\n };\r\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 */\r\n View.prototype.removeEventRegistration = function (eventRegistration, cancelError) {\r\n var cancelEvents = [];\r\n if (cancelError) {\r\n assert(eventRegistration == null, 'A cancel should cancel all event registrations.');\r\n var path_1 = this.query_.path;\r\n this.eventRegistrations_.forEach(function (registration) {\r\n cancelError /** @type {!Error} */ = cancelError;\r\n var maybeEvent = registration.createCancelEvent(cancelError, path_1);\r\n if (maybeEvent) {\r\n cancelEvents.push(maybeEvent);\r\n }\r\n });\r\n }\r\n if (eventRegistration) {\r\n var remaining = [];\r\n for (var i = 0; i < this.eventRegistrations_.length; ++i) {\r\n var existing = this.eventRegistrations_[i];\r\n if (!existing.matches(eventRegistration)) {\r\n remaining.push(existing);\r\n }\r\n else if (eventRegistration.hasAnyCallback()) {\r\n // We're removing just this one\r\n remaining = remaining.concat(this.eventRegistrations_.slice(i + 1));\r\n break;\r\n }\r\n }\r\n this.eventRegistrations_ = remaining;\r\n }\r\n else {\r\n this.eventRegistrations_ = [];\r\n }\r\n return cancelEvents;\r\n };\r\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 */\r\n View.prototype.applyOperation = function (operation, writesCache, completeServerCache) {\r\n if (operation.type === OperationType.MERGE &&\r\n operation.source.queryId !== null) {\r\n assert(this.viewCache_.getCompleteServerSnap(), 'We should always have a full cache before handling merges');\r\n assert(this.viewCache_.getCompleteEventSnap(), 'Missing event cache, even though we have a server cache');\r\n }\r\n var oldViewCache = this.viewCache_;\r\n var result = this.processor_.applyOperation(oldViewCache, operation, writesCache, completeServerCache);\r\n this.processor_.assertIndexed(result.viewCache);\r\n assert(result.viewCache.getServerCache().isFullyInitialized() ||\r\n !oldViewCache.getServerCache().isFullyInitialized(), 'Once a server snap is complete, it should never go back');\r\n this.viewCache_ = result.viewCache;\r\n return this.generateEventsForChanges_(result.changes, result.viewCache.getEventCache().getNode(), null);\r\n };\r\n /**\r\n * @param {!EventRegistration} registration\r\n * @return {!Array.}\r\n */\r\n View.prototype.getInitialEvents = function (registration) {\r\n var eventSnap = this.viewCache_.getEventCache();\r\n var initialChanges = [];\r\n if (!eventSnap.getNode().isLeafNode()) {\r\n var eventNode = eventSnap.getNode();\r\n eventNode.forEachChild(PRIORITY_INDEX, function (key, childNode) {\r\n initialChanges.push(Change.childAddedChange(key, childNode));\r\n });\r\n }\r\n if (eventSnap.isFullyInitialized()) {\r\n initialChanges.push(Change.valueChange(eventSnap.getNode()));\r\n }\r\n return this.generateEventsForChanges_(initialChanges, eventSnap.getNode(), registration);\r\n };\r\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 */\r\n View.prototype.generateEventsForChanges_ = function (changes, eventCache, eventRegistration) {\r\n var registrations = eventRegistration\r\n ? [eventRegistration]\r\n : this.eventRegistrations_;\r\n return this.eventGenerator_.generateEventsForChanges(changes, eventCache, registrations);\r\n };\r\n return View;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar __referenceConstructor$1;\r\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 */\r\nvar SyncPoint = /** @class */ (function () {\r\n function SyncPoint() {\r\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 */\r\n this.views_ = {};\r\n }\r\n Object.defineProperty(SyncPoint, \"__referenceConstructor\", {\r\n get: function () {\r\n assert(__referenceConstructor$1, 'Reference.ts has not been loaded');\r\n return __referenceConstructor$1;\r\n },\r\n set: function (val) {\r\n assert(!__referenceConstructor$1, '__referenceConstructor has already been defined');\r\n __referenceConstructor$1 = val;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @return {boolean}\r\n */\r\n SyncPoint.prototype.isEmpty = function () {\r\n return isEmpty(this.views_);\r\n };\r\n /**\r\n *\r\n * @param {!Operation} operation\r\n * @param {!WriteTreeRef} writesCache\r\n * @param {?Node} optCompleteServerCache\r\n * @return {!Array.}\r\n */\r\n SyncPoint.prototype.applyOperation = function (operation, writesCache, optCompleteServerCache) {\r\n var queryId = operation.source.queryId;\r\n if (queryId !== null) {\r\n var view = safeGet(this.views_, queryId);\r\n assert(view != null, 'SyncTree gave us an op for an invalid query.');\r\n return view.applyOperation(operation, writesCache, optCompleteServerCache);\r\n }\r\n else {\r\n var events_1 = [];\r\n forEach(this.views_, function (key, view) {\r\n events_1 = events_1.concat(view.applyOperation(operation, writesCache, optCompleteServerCache));\r\n });\r\n return events_1;\r\n }\r\n };\r\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 */\r\n SyncPoint.prototype.addEventRegistration = function (query, eventRegistration, writesCache, serverCache, serverCacheComplete) {\r\n var queryId = query.queryIdentifier();\r\n var view = safeGet(this.views_, queryId);\r\n if (!view) {\r\n // TODO: make writesCache take flag for complete server node\r\n var eventCache = writesCache.calcCompleteEventCache(serverCacheComplete ? serverCache : null);\r\n var eventCacheComplete = false;\r\n if (eventCache) {\r\n eventCacheComplete = true;\r\n }\r\n else if (serverCache instanceof ChildrenNode) {\r\n eventCache = writesCache.calcCompleteEventChildren(serverCache);\r\n eventCacheComplete = false;\r\n }\r\n else {\r\n eventCache = ChildrenNode.EMPTY_NODE;\r\n eventCacheComplete = false;\r\n }\r\n var viewCache = new ViewCache(new CacheNode(\r\n /** @type {!Node} */ (eventCache), eventCacheComplete, false), new CacheNode(\r\n /** @type {!Node} */ (serverCache), serverCacheComplete, false));\r\n view = new View(query, viewCache);\r\n this.views_[queryId] = view;\r\n }\r\n // This is guaranteed to exist now, we just created anything that was missing\r\n view.addEventRegistration(eventRegistration);\r\n return view.getInitialEvents(eventRegistration);\r\n };\r\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 */\r\n SyncPoint.prototype.removeEventRegistration = function (query, eventRegistration, cancelError) {\r\n var queryId = query.queryIdentifier();\r\n var removed = [];\r\n var cancelEvents = [];\r\n var hadCompleteView = this.hasCompleteView();\r\n if (queryId === 'default') {\r\n // When you do ref.off(...), we search all views for the registration to remove.\r\n var self_1 = this;\r\n forEach(this.views_, function (viewQueryId, view) {\r\n cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));\r\n if (view.isEmpty()) {\r\n delete self_1.views_[viewQueryId];\r\n // We'll deal with complete views later.\r\n if (!view\r\n .getQuery()\r\n .getQueryParams()\r\n .loadsAllData()) {\r\n removed.push(view.getQuery());\r\n }\r\n }\r\n });\r\n }\r\n else {\r\n // remove the callback from the specific view.\r\n var view = safeGet(this.views_, queryId);\r\n if (view) {\r\n cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));\r\n if (view.isEmpty()) {\r\n delete this.views_[queryId];\r\n // We'll deal with complete views later.\r\n if (!view\r\n .getQuery()\r\n .getQueryParams()\r\n .loadsAllData()) {\r\n removed.push(view.getQuery());\r\n }\r\n }\r\n }\r\n }\r\n if (hadCompleteView && !this.hasCompleteView()) {\r\n // We removed our last complete view.\r\n removed.push(new SyncPoint.__referenceConstructor(query.repo, query.path));\r\n }\r\n return { removed: removed, events: cancelEvents };\r\n };\r\n /**\r\n * @return {!Array.}\r\n */\r\n SyncPoint.prototype.getQueryViews = function () {\r\n var _this = this;\r\n var values = Object.keys(this.views_).map(function (key) { return _this.views_[key]; });\r\n return values.filter(function (view) {\r\n return !view\r\n .getQuery()\r\n .getQueryParams()\r\n .loadsAllData();\r\n });\r\n };\r\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 */\r\n SyncPoint.prototype.getCompleteServerCache = function (path) {\r\n var serverCache = null;\r\n forEach(this.views_, function (key, view) {\r\n serverCache = serverCache || view.getCompleteServerCache(path);\r\n });\r\n return serverCache;\r\n };\r\n /**\r\n * @param {!Query} query\r\n * @return {?View}\r\n */\r\n SyncPoint.prototype.viewForQuery = function (query) {\r\n var params = query.getQueryParams();\r\n if (params.loadsAllData()) {\r\n return this.getCompleteView();\r\n }\r\n else {\r\n var queryId = query.queryIdentifier();\r\n return safeGet(this.views_, queryId);\r\n }\r\n };\r\n /**\r\n * @param {!Query} query\r\n * @return {boolean}\r\n */\r\n SyncPoint.prototype.viewExistsForQuery = function (query) {\r\n return this.viewForQuery(query) != null;\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n SyncPoint.prototype.hasCompleteView = function () {\r\n return this.getCompleteView() != null;\r\n };\r\n /**\r\n * @return {?View}\r\n */\r\n SyncPoint.prototype.getCompleteView = function () {\r\n var completeView = findValue(this.views_, function (view) {\r\n return view\r\n .getQuery()\r\n .getQueryParams()\r\n .loadsAllData();\r\n });\r\n return completeView || null;\r\n };\r\n return SyncPoint;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar CompoundWrite = /** @class */ (function () {\r\n function CompoundWrite(writeTree_) {\r\n this.writeTree_ = writeTree_;\r\n }\r\n /**\r\n * @param {!Path} path\r\n * @param {!Node} node\r\n * @return {!CompoundWrite}\r\n */\r\n CompoundWrite.prototype.addWrite = function (path, node) {\r\n if (path.isEmpty()) {\r\n return new CompoundWrite(new ImmutableTree(node));\r\n }\r\n else {\r\n var rootmost = this.writeTree_.findRootMostValueAndPath(path);\r\n if (rootmost != null) {\r\n var rootMostPath = rootmost.path;\r\n var value = rootmost.value;\r\n var relativePath = Path.relativePath(rootMostPath, path);\r\n value = value.updateChild(relativePath, node);\r\n return new CompoundWrite(this.writeTree_.set(rootMostPath, value));\r\n }\r\n else {\r\n var subtree = new ImmutableTree(node);\r\n var newWriteTree = this.writeTree_.setTree(path, subtree);\r\n return new CompoundWrite(newWriteTree);\r\n }\r\n }\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @param {!Object.} updates\r\n * @return {!CompoundWrite}\r\n */\r\n CompoundWrite.prototype.addWrites = function (path, updates) {\r\n var newWrite = this;\r\n forEach(updates, function (childKey, node) {\r\n newWrite = newWrite.addWrite(path.child(childKey), node);\r\n });\r\n return newWrite;\r\n };\r\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 */\r\n CompoundWrite.prototype.removeWrite = function (path) {\r\n if (path.isEmpty()) {\r\n return CompoundWrite.Empty;\r\n }\r\n else {\r\n var newWriteTree = this.writeTree_.setTree(path, ImmutableTree.Empty);\r\n return new CompoundWrite(newWriteTree);\r\n }\r\n };\r\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 */\r\n CompoundWrite.prototype.hasCompleteWrite = function (path) {\r\n return this.getCompleteNode(path) != null;\r\n };\r\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 */\r\n CompoundWrite.prototype.getCompleteNode = function (path) {\r\n var rootmost = this.writeTree_.findRootMostValueAndPath(path);\r\n if (rootmost != null) {\r\n return this.writeTree_\r\n .get(rootmost.path)\r\n .getChild(Path.relativePath(rootmost.path, path));\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\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 */\r\n CompoundWrite.prototype.getCompleteChildren = function () {\r\n var children = [];\r\n var node = this.writeTree_.value;\r\n if (node != null) {\r\n // If it's a leaf node, it has no children; so nothing to do.\r\n if (!node.isLeafNode()) {\r\n node.forEachChild(PRIORITY_INDEX, function (childName, childNode) {\r\n children.push(new NamedNode(childName, childNode));\r\n });\r\n }\r\n }\r\n else {\r\n this.writeTree_.children.inorderTraversal(function (childName, childTree) {\r\n if (childTree.value != null) {\r\n children.push(new NamedNode(childName, childTree.value));\r\n }\r\n });\r\n }\r\n return children;\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @return {!CompoundWrite}\r\n */\r\n CompoundWrite.prototype.childCompoundWrite = function (path) {\r\n if (path.isEmpty()) {\r\n return this;\r\n }\r\n else {\r\n var shadowingNode = this.getCompleteNode(path);\r\n if (shadowingNode != null) {\r\n return new CompoundWrite(new ImmutableTree(shadowingNode));\r\n }\r\n else {\r\n return new CompoundWrite(this.writeTree_.subtree(path));\r\n }\r\n }\r\n };\r\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 */\r\n CompoundWrite.prototype.isEmpty = function () {\r\n return this.writeTree_.isEmpty();\r\n };\r\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 */\r\n CompoundWrite.prototype.apply = function (node) {\r\n return CompoundWrite.applySubtreeWrite_(Path.Empty, this.writeTree_, node);\r\n };\r\n /**\r\n * @type {!CompoundWrite}\r\n */\r\n CompoundWrite.Empty = new CompoundWrite(new ImmutableTree(null));\r\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 */\r\n CompoundWrite.applySubtreeWrite_ = function (relativePath, writeTree, node) {\r\n if (writeTree.value != null) {\r\n // Since there a write is always a leaf, we're done here\r\n return node.updateChild(relativePath, writeTree.value);\r\n }\r\n else {\r\n var priorityWrite_1 = null;\r\n writeTree.children.inorderTraversal(function (childKey, childTree) {\r\n if (childKey === '.priority') {\r\n // Apply priorities at the end so we don't update priorities for either empty nodes or forget\r\n // to apply priorities to empty nodes that are later filled\r\n assert(childTree.value !== null, 'Priority writes must always be leaf nodes');\r\n priorityWrite_1 = childTree.value;\r\n }\r\n else {\r\n node = CompoundWrite.applySubtreeWrite_(relativePath.child(childKey), childTree, node);\r\n }\r\n });\r\n // If there was a priority write, we only apply it if the node is not empty\r\n if (!node.getChild(relativePath).isEmpty() && priorityWrite_1 !== null) {\r\n node = node.updateChild(relativePath.child('.priority'), priorityWrite_1);\r\n }\r\n return node;\r\n }\r\n };\r\n return CompoundWrite;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar WriteTree = /** @class */ (function () {\r\n function WriteTree() {\r\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 */\r\n this.visibleWrites_ = CompoundWrite.Empty;\r\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 */\r\n this.allWrites_ = [];\r\n this.lastWriteId_ = -1;\r\n }\r\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 */\r\n WriteTree.prototype.childWrites = function (path) {\r\n return new WriteTreeRef(path, this);\r\n };\r\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 */\r\n WriteTree.prototype.addOverwrite = function (path, snap, writeId, visible) {\r\n assert(writeId > this.lastWriteId_, 'Stacking an older write on top of newer ones');\r\n if (visible === undefined) {\r\n visible = true;\r\n }\r\n this.allWrites_.push({\r\n path: path,\r\n snap: snap,\r\n writeId: writeId,\r\n visible: visible\r\n });\r\n if (visible) {\r\n this.visibleWrites_ = this.visibleWrites_.addWrite(path, snap);\r\n }\r\n this.lastWriteId_ = writeId;\r\n };\r\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 */\r\n WriteTree.prototype.addMerge = function (path, changedChildren, writeId) {\r\n assert(writeId > this.lastWriteId_, 'Stacking an older merge on top of newer ones');\r\n this.allWrites_.push({\r\n path: path,\r\n children: changedChildren,\r\n writeId: writeId,\r\n visible: true\r\n });\r\n this.visibleWrites_ = this.visibleWrites_.addWrites(path, changedChildren);\r\n this.lastWriteId_ = writeId;\r\n };\r\n /**\r\n * @param {!number} writeId\r\n * @return {?WriteRecord}\r\n */\r\n WriteTree.prototype.getWrite = function (writeId) {\r\n for (var i = 0; i < this.allWrites_.length; i++) {\r\n var record = this.allWrites_[i];\r\n if (record.writeId === writeId) {\r\n return record;\r\n }\r\n }\r\n return null;\r\n };\r\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 */\r\n WriteTree.prototype.removeWrite = function (writeId) {\r\n // Note: disabling this check. It could be a transaction that preempted another transaction, and thus was applied\r\n // out of order.\r\n //const validClear = revert || this.allWrites_.length === 0 || writeId <= this.allWrites_[0].writeId;\r\n //assert(validClear, \"Either we don't have this write, or it's the first one in the queue\");\r\n var _this = this;\r\n var idx = this.allWrites_.findIndex(function (s) {\r\n return s.writeId === writeId;\r\n });\r\n assert(idx >= 0, 'removeWrite called with nonexistent writeId.');\r\n var writeToRemove = this.allWrites_[idx];\r\n this.allWrites_.splice(idx, 1);\r\n var removedWriteWasVisible = writeToRemove.visible;\r\n var removedWriteOverlapsWithOtherWrites = false;\r\n var i = this.allWrites_.length - 1;\r\n while (removedWriteWasVisible && i >= 0) {\r\n var currentWrite = this.allWrites_[i];\r\n if (currentWrite.visible) {\r\n if (i >= idx &&\r\n this.recordContainsPath_(currentWrite, writeToRemove.path)) {\r\n // The removed write was completely shadowed by a subsequent write.\r\n removedWriteWasVisible = false;\r\n }\r\n else if (writeToRemove.path.contains(currentWrite.path)) {\r\n // Either we're covering some writes or they're covering part of us (depending on which came first).\r\n removedWriteOverlapsWithOtherWrites = true;\r\n }\r\n }\r\n i--;\r\n }\r\n if (!removedWriteWasVisible) {\r\n return false;\r\n }\r\n else if (removedWriteOverlapsWithOtherWrites) {\r\n // There's some shadowing going on. Just rebuild the visible writes from scratch.\r\n this.resetTree_();\r\n return true;\r\n }\r\n else {\r\n // There's no shadowing. We can safely just remove the write(s) from visibleWrites.\r\n if (writeToRemove.snap) {\r\n this.visibleWrites_ = this.visibleWrites_.removeWrite(writeToRemove.path);\r\n }\r\n else {\r\n var children = writeToRemove.children;\r\n forEach(children, function (childName) {\r\n _this.visibleWrites_ = _this.visibleWrites_.removeWrite(writeToRemove.path.child(childName));\r\n });\r\n }\r\n return true;\r\n }\r\n };\r\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 */\r\n WriteTree.prototype.getCompleteWriteData = function (path) {\r\n return this.visibleWrites_.getCompleteNode(path);\r\n };\r\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 */\r\n WriteTree.prototype.calcCompleteEventCache = function (treePath, completeServerCache, writeIdsToExclude, includeHiddenWrites) {\r\n if (!writeIdsToExclude && !includeHiddenWrites) {\r\n var shadowingNode = this.visibleWrites_.getCompleteNode(treePath);\r\n if (shadowingNode != null) {\r\n return shadowingNode;\r\n }\r\n else {\r\n var subMerge = this.visibleWrites_.childCompoundWrite(treePath);\r\n if (subMerge.isEmpty()) {\r\n return completeServerCache;\r\n }\r\n else if (completeServerCache == null &&\r\n !subMerge.hasCompleteWrite(Path.Empty)) {\r\n // We wouldn't have a complete snapshot, since there's no underlying data and no complete shadow\r\n return null;\r\n }\r\n else {\r\n var layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE;\r\n return subMerge.apply(layeredCache);\r\n }\r\n }\r\n }\r\n else {\r\n var merge = this.visibleWrites_.childCompoundWrite(treePath);\r\n if (!includeHiddenWrites && merge.isEmpty()) {\r\n return completeServerCache;\r\n }\r\n else {\r\n // If the server cache is null, and we don't have a complete cache, we need to return null\r\n if (!includeHiddenWrites &&\r\n completeServerCache == null &&\r\n !merge.hasCompleteWrite(Path.Empty)) {\r\n return null;\r\n }\r\n else {\r\n var filter = function (write) {\r\n return ((write.visible || includeHiddenWrites) &&\r\n (!writeIdsToExclude ||\r\n !~writeIdsToExclude.indexOf(write.writeId)) &&\r\n (write.path.contains(treePath) || treePath.contains(write.path)));\r\n };\r\n var mergeAtPath = WriteTree.layerTree_(this.allWrites_, filter, treePath);\r\n var layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE;\r\n return mergeAtPath.apply(layeredCache);\r\n }\r\n }\r\n }\r\n };\r\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 */\r\n WriteTree.prototype.calcCompleteEventChildren = function (treePath, completeServerChildren) {\r\n var completeChildren = ChildrenNode.EMPTY_NODE;\r\n var topLevelSet = this.visibleWrites_.getCompleteNode(treePath);\r\n if (topLevelSet) {\r\n if (!topLevelSet.isLeafNode()) {\r\n // we're shadowing everything. Return the children.\r\n topLevelSet.forEachChild(PRIORITY_INDEX, function (childName, childSnap) {\r\n completeChildren = completeChildren.updateImmediateChild(childName, childSnap);\r\n });\r\n }\r\n return completeChildren;\r\n }\r\n else if (completeServerChildren) {\r\n // Layer any children we have on top of this\r\n // We know we don't have a top-level set, so just enumerate existing children\r\n var merge_1 = this.visibleWrites_.childCompoundWrite(treePath);\r\n completeServerChildren.forEachChild(PRIORITY_INDEX, function (childName, childNode) {\r\n var node = merge_1\r\n .childCompoundWrite(new Path(childName))\r\n .apply(childNode);\r\n completeChildren = completeChildren.updateImmediateChild(childName, node);\r\n });\r\n // Add any complete children we have from the set\r\n merge_1.getCompleteChildren().forEach(function (namedNode) {\r\n completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node);\r\n });\r\n return completeChildren;\r\n }\r\n else {\r\n // We don't have anything to layer on top of. Layer on any children we have\r\n // Note that we can return an empty snap if we have a defined delete\r\n var merge = this.visibleWrites_.childCompoundWrite(treePath);\r\n merge.getCompleteChildren().forEach(function (namedNode) {\r\n completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node);\r\n });\r\n return completeChildren;\r\n }\r\n };\r\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 */\r\n WriteTree.prototype.calcEventCacheAfterServerOverwrite = function (treePath, childPath, existingEventSnap, existingServerSnap) {\r\n assert(existingEventSnap || existingServerSnap, 'Either existingEventSnap or existingServerSnap must exist');\r\n var path = treePath.child(childPath);\r\n if (this.visibleWrites_.hasCompleteWrite(path)) {\r\n // At this point we can probably guarantee that we're in case 2, meaning no events\r\n // May need to check visibility while doing the findRootMostValueAndPath call\r\n return null;\r\n }\r\n else {\r\n // No complete shadowing. We're either partially shadowing or not shadowing at all.\r\n var childMerge = this.visibleWrites_.childCompoundWrite(path);\r\n if (childMerge.isEmpty()) {\r\n // We're not shadowing at all. Case 1\r\n return existingServerSnap.getChild(childPath);\r\n }\r\n else {\r\n // This could be more efficient if the serverNode + updates doesn't change the eventSnap\r\n // However this is tricky to find out, since user updates don't necessary change the server\r\n // snap, e.g. priority updates on empty nodes, or deep deletes. Another special case is if the server\r\n // adds nodes, but doesn't change any existing writes. It is therefore not enough to\r\n // only check if the updates change the serverNode.\r\n // Maybe check if the merge tree contains these special cases and only do a full overwrite in that case?\r\n return childMerge.apply(existingServerSnap.getChild(childPath));\r\n }\r\n }\r\n };\r\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 */\r\n WriteTree.prototype.calcCompleteChild = function (treePath, childKey, existingServerSnap) {\r\n var path = treePath.child(childKey);\r\n var shadowingNode = this.visibleWrites_.getCompleteNode(path);\r\n if (shadowingNode != null) {\r\n return shadowingNode;\r\n }\r\n else {\r\n if (existingServerSnap.isCompleteForChild(childKey)) {\r\n var childMerge = this.visibleWrites_.childCompoundWrite(path);\r\n return childMerge.apply(existingServerSnap.getNode().getImmediateChild(childKey));\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n };\r\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 */\r\n WriteTree.prototype.shadowingWrite = function (path) {\r\n return this.visibleWrites_.getCompleteNode(path);\r\n };\r\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 */\r\n WriteTree.prototype.calcIndexedSlice = function (treePath, completeServerData, startPost, count, reverse, index) {\r\n var toIterate;\r\n var merge = this.visibleWrites_.childCompoundWrite(treePath);\r\n var shadowingNode = merge.getCompleteNode(Path.Empty);\r\n if (shadowingNode != null) {\r\n toIterate = shadowingNode;\r\n }\r\n else if (completeServerData != null) {\r\n toIterate = merge.apply(completeServerData);\r\n }\r\n else {\r\n // no children to iterate on\r\n return [];\r\n }\r\n toIterate = toIterate.withIndex(index);\r\n if (!toIterate.isEmpty() && !toIterate.isLeafNode()) {\r\n var nodes = [];\r\n var cmp = index.getCompare();\r\n var iter = reverse\r\n ? toIterate.getReverseIteratorFrom(startPost, index)\r\n : toIterate.getIteratorFrom(startPost, index);\r\n var next = iter.getNext();\r\n while (next && nodes.length < count) {\r\n if (cmp(next, startPost) !== 0) {\r\n nodes.push(next);\r\n }\r\n next = iter.getNext();\r\n }\r\n return nodes;\r\n }\r\n else {\r\n return [];\r\n }\r\n };\r\n /**\r\n * @param {!WriteRecord} writeRecord\r\n * @param {!Path} path\r\n * @return {boolean}\r\n * @private\r\n */\r\n WriteTree.prototype.recordContainsPath_ = function (writeRecord, path) {\r\n if (writeRecord.snap) {\r\n return writeRecord.path.contains(path);\r\n }\r\n else {\r\n // findKey can return undefined, so use !! to coerce to boolean\r\n return !!findKey(writeRecord.children, function (childSnap, childName) {\r\n return writeRecord.path.child(childName).contains(path);\r\n });\r\n }\r\n };\r\n /**\r\n * Re-layer the writes and merges into a tree so we can efficiently calculate event snapshots\r\n * @private\r\n */\r\n WriteTree.prototype.resetTree_ = function () {\r\n this.visibleWrites_ = WriteTree.layerTree_(this.allWrites_, WriteTree.DefaultFilter_, Path.Empty);\r\n if (this.allWrites_.length > 0) {\r\n this.lastWriteId_ = this.allWrites_[this.allWrites_.length - 1].writeId;\r\n }\r\n else {\r\n this.lastWriteId_ = -1;\r\n }\r\n };\r\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 */\r\n WriteTree.DefaultFilter_ = function (write) {\r\n return write.visible;\r\n };\r\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 */\r\n WriteTree.layerTree_ = function (writes, filter, treeRoot) {\r\n var compoundWrite = CompoundWrite.Empty;\r\n for (var i = 0; i < writes.length; ++i) {\r\n var write = writes[i];\r\n // Theory, a later set will either:\r\n // a) abort a relevant transaction, so no need to worry about excluding it from calculating that transaction\r\n // b) not be relevant to a transaction (separate branch), so again will not affect the data for that transaction\r\n if (filter(write)) {\r\n var writePath = write.path;\r\n var relativePath = void 0;\r\n if (write.snap) {\r\n if (treeRoot.contains(writePath)) {\r\n relativePath = Path.relativePath(treeRoot, writePath);\r\n compoundWrite = compoundWrite.addWrite(relativePath, write.snap);\r\n }\r\n else if (writePath.contains(treeRoot)) {\r\n relativePath = Path.relativePath(writePath, treeRoot);\r\n compoundWrite = compoundWrite.addWrite(Path.Empty, write.snap.getChild(relativePath));\r\n }\r\n }\r\n else if (write.children) {\r\n if (treeRoot.contains(writePath)) {\r\n relativePath = Path.relativePath(treeRoot, writePath);\r\n compoundWrite = compoundWrite.addWrites(relativePath, write.children);\r\n }\r\n else if (writePath.contains(treeRoot)) {\r\n relativePath = Path.relativePath(writePath, treeRoot);\r\n if (relativePath.isEmpty()) {\r\n compoundWrite = compoundWrite.addWrites(Path.Empty, write.children);\r\n }\r\n else {\r\n var child = safeGet(write.children, relativePath.getFront());\r\n if (child) {\r\n // There exists a child in this node that matches the root path\r\n var deepNode = child.getChild(relativePath.popFront());\r\n compoundWrite = compoundWrite.addWrite(Path.Empty, deepNode);\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n throw assertionError('WriteRecord should have .snap or .children');\r\n }\r\n }\r\n }\r\n return compoundWrite;\r\n };\r\n return WriteTree;\r\n}());\r\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 */\r\nvar WriteTreeRef = /** @class */ (function () {\r\n /**\r\n * @param {!Path} path\r\n * @param {!WriteTree} writeTree\r\n */\r\n function WriteTreeRef(path, writeTree) {\r\n this.treePath_ = path;\r\n this.writeTree_ = writeTree;\r\n }\r\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 */\r\n WriteTreeRef.prototype.calcCompleteEventCache = function (completeServerCache, writeIdsToExclude, includeHiddenWrites) {\r\n return this.writeTree_.calcCompleteEventCache(this.treePath_, completeServerCache, writeIdsToExclude, includeHiddenWrites);\r\n };\r\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 */\r\n WriteTreeRef.prototype.calcCompleteEventChildren = function (completeServerChildren) {\r\n return this.writeTree_.calcCompleteEventChildren(this.treePath_, completeServerChildren);\r\n };\r\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 */\r\n WriteTreeRef.prototype.calcEventCacheAfterServerOverwrite = function (path, existingEventSnap, existingServerSnap) {\r\n return this.writeTree_.calcEventCacheAfterServerOverwrite(this.treePath_, path, existingEventSnap, existingServerSnap);\r\n };\r\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 */\r\n WriteTreeRef.prototype.shadowingWrite = function (path) {\r\n return this.writeTree_.shadowingWrite(this.treePath_.child(path));\r\n };\r\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 */\r\n WriteTreeRef.prototype.calcIndexedSlice = function (completeServerData, startPost, count, reverse, index) {\r\n return this.writeTree_.calcIndexedSlice(this.treePath_, completeServerData, startPost, count, reverse, index);\r\n };\r\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 */\r\n WriteTreeRef.prototype.calcCompleteChild = function (childKey, existingServerCache) {\r\n return this.writeTree_.calcCompleteChild(this.treePath_, childKey, existingServerCache);\r\n };\r\n /**\r\n * Return a WriteTreeRef for a child.\r\n *\r\n * @param {string} childName\r\n * @return {!WriteTreeRef}\r\n */\r\n WriteTreeRef.prototype.child = function (childName) {\r\n return new WriteTreeRef(this.treePath_.child(childName), this.writeTree_);\r\n };\r\n return WriteTreeRef;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar SyncTree = /** @class */ (function () {\r\n /**\r\n * @param {!ListenProvider} listenProvider_ Used by SyncTree to start / stop listening\r\n * to server data.\r\n */\r\n function SyncTree(listenProvider_) {\r\n this.listenProvider_ = listenProvider_;\r\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 */\r\n this.syncPointTree_ = ImmutableTree.Empty;\r\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 */\r\n this.pendingWriteTree_ = new WriteTree();\r\n this.tagToQueryMap_ = {};\r\n this.queryToTagMap_ = {};\r\n }\r\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 */\r\n SyncTree.prototype.applyUserOverwrite = function (path, newData, writeId, visible) {\r\n // Record pending write.\r\n this.pendingWriteTree_.addOverwrite(path, newData, writeId, visible);\r\n if (!visible) {\r\n return [];\r\n }\r\n else {\r\n return this.applyOperationToSyncPoints_(new Overwrite(OperationSource.User, path, newData));\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.applyUserMerge = function (path, changedChildren, writeId) {\r\n // Record pending merge.\r\n this.pendingWriteTree_.addMerge(path, changedChildren, writeId);\r\n var changeTree = ImmutableTree.fromObject(changedChildren);\r\n return this.applyOperationToSyncPoints_(new Merge(OperationSource.User, path, changeTree));\r\n };\r\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 */\r\n SyncTree.prototype.ackUserWrite = function (writeId, revert) {\r\n if (revert === void 0) { revert = false; }\r\n var write = this.pendingWriteTree_.getWrite(writeId);\r\n var needToReevaluate = this.pendingWriteTree_.removeWrite(writeId);\r\n if (!needToReevaluate) {\r\n return [];\r\n }\r\n else {\r\n var affectedTree_1 = ImmutableTree.Empty;\r\n if (write.snap != null) {\r\n // overwrite\r\n affectedTree_1 = affectedTree_1.set(Path.Empty, true);\r\n }\r\n else {\r\n forEach(write.children, function (pathString, node) {\r\n affectedTree_1 = affectedTree_1.set(new Path(pathString), node);\r\n });\r\n }\r\n return this.applyOperationToSyncPoints_(new AckUserWrite(write.path, affectedTree_1, revert));\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.applyServerOverwrite = function (path, newData) {\r\n return this.applyOperationToSyncPoints_(new Overwrite(OperationSource.Server, path, newData));\r\n };\r\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 */\r\n SyncTree.prototype.applyServerMerge = function (path, changedChildren) {\r\n var changeTree = ImmutableTree.fromObject(changedChildren);\r\n return this.applyOperationToSyncPoints_(new Merge(OperationSource.Server, path, changeTree));\r\n };\r\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 */\r\n SyncTree.prototype.applyListenComplete = function (path) {\r\n return this.applyOperationToSyncPoints_(new ListenComplete(OperationSource.Server, path));\r\n };\r\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 */\r\n SyncTree.prototype.applyTaggedQueryOverwrite = function (path, snap, tag) {\r\n var queryKey = this.queryKeyForTag_(tag);\r\n if (queryKey != null) {\r\n var r = SyncTree.parseQueryKey_(queryKey);\r\n var queryPath = r.path, queryId = r.queryId;\r\n var relativePath = Path.relativePath(queryPath, path);\r\n var op = new Overwrite(OperationSource.forServerTaggedQuery(queryId), relativePath, snap);\r\n return this.applyTaggedOperation_(queryPath, op);\r\n }\r\n else {\r\n // Query must have been removed already\r\n return [];\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.applyTaggedQueryMerge = function (path, changedChildren, tag) {\r\n var queryKey = this.queryKeyForTag_(tag);\r\n if (queryKey) {\r\n var r = SyncTree.parseQueryKey_(queryKey);\r\n var queryPath = r.path, queryId = r.queryId;\r\n var relativePath = Path.relativePath(queryPath, path);\r\n var changeTree = ImmutableTree.fromObject(changedChildren);\r\n var op = new Merge(OperationSource.forServerTaggedQuery(queryId), relativePath, changeTree);\r\n return this.applyTaggedOperation_(queryPath, op);\r\n }\r\n else {\r\n // We've already removed the query. No big deal, ignore the update\r\n return [];\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.applyTaggedListenComplete = function (path, tag) {\r\n var queryKey = this.queryKeyForTag_(tag);\r\n if (queryKey) {\r\n var r = SyncTree.parseQueryKey_(queryKey);\r\n var queryPath = r.path, queryId = r.queryId;\r\n var relativePath = Path.relativePath(queryPath, path);\r\n var op = new ListenComplete(OperationSource.forServerTaggedQuery(queryId), relativePath);\r\n return this.applyTaggedOperation_(queryPath, op);\r\n }\r\n else {\r\n // We've already removed the query. No big deal, ignore the update\r\n return [];\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.addEventRegistration = function (query, eventRegistration) {\r\n var path = query.path;\r\n var serverCache = null;\r\n var foundAncestorDefaultView = false;\r\n // Any covering writes will necessarily be at the root, so really all we need to find is the server cache.\r\n // Consider optimizing this once there's a better understanding of what actual behavior will be.\r\n this.syncPointTree_.foreachOnPath(path, function (pathToSyncPoint, sp) {\r\n var relativePath = Path.relativePath(pathToSyncPoint, path);\r\n serverCache = serverCache || sp.getCompleteServerCache(relativePath);\r\n foundAncestorDefaultView =\r\n foundAncestorDefaultView || sp.hasCompleteView();\r\n });\r\n var syncPoint = this.syncPointTree_.get(path);\r\n if (!syncPoint) {\r\n syncPoint = new SyncPoint();\r\n this.syncPointTree_ = this.syncPointTree_.set(path, syncPoint);\r\n }\r\n else {\r\n foundAncestorDefaultView =\r\n foundAncestorDefaultView || syncPoint.hasCompleteView();\r\n serverCache = serverCache || syncPoint.getCompleteServerCache(Path.Empty);\r\n }\r\n var serverCacheComplete;\r\n if (serverCache != null) {\r\n serverCacheComplete = true;\r\n }\r\n else {\r\n serverCacheComplete = false;\r\n serverCache = ChildrenNode.EMPTY_NODE;\r\n var subtree = this.syncPointTree_.subtree(path);\r\n subtree.foreachChild(function (childName, childSyncPoint) {\r\n var completeCache = childSyncPoint.getCompleteServerCache(Path.Empty);\r\n if (completeCache) {\r\n serverCache = serverCache.updateImmediateChild(childName, completeCache);\r\n }\r\n });\r\n }\r\n var viewAlreadyExists = syncPoint.viewExistsForQuery(query);\r\n if (!viewAlreadyExists && !query.getQueryParams().loadsAllData()) {\r\n // We need to track a tag for this query\r\n var queryKey = SyncTree.makeQueryKey_(query);\r\n assert(!(queryKey in this.queryToTagMap_), 'View does not exist, but we have a tag');\r\n var tag = SyncTree.getNextQueryTag_();\r\n this.queryToTagMap_[queryKey] = tag;\r\n // Coerce to string to avoid sparse arrays.\r\n this.tagToQueryMap_['_' + tag] = queryKey;\r\n }\r\n var writesCache = this.pendingWriteTree_.childWrites(path);\r\n var events = syncPoint.addEventRegistration(query, eventRegistration, writesCache, serverCache, serverCacheComplete);\r\n if (!viewAlreadyExists && !foundAncestorDefaultView) {\r\n var view /** @type !View */ = syncPoint.viewForQuery(query);\r\n events = events.concat(this.setupListener_(query, view));\r\n }\r\n return events;\r\n };\r\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 */\r\n SyncTree.prototype.removeEventRegistration = function (query, eventRegistration, cancelError) {\r\n var _this = this;\r\n // Find the syncPoint first. Then deal with whether or not it has matching listeners\r\n var path = query.path;\r\n var maybeSyncPoint = this.syncPointTree_.get(path);\r\n var cancelEvents = [];\r\n // A removal on a default query affects all queries at that location. A removal on an indexed query, even one without\r\n // other query constraints, does *not* affect all queries at that location. So this check must be for 'default', and\r\n // not loadsAllData().\r\n if (maybeSyncPoint &&\r\n (query.queryIdentifier() === 'default' ||\r\n maybeSyncPoint.viewExistsForQuery(query))) {\r\n /**\r\n * @type {{removed: !Array., events: !Array.}}\r\n */\r\n var removedAndEvents = maybeSyncPoint.removeEventRegistration(query, eventRegistration, cancelError);\r\n if (maybeSyncPoint.isEmpty()) {\r\n this.syncPointTree_ = this.syncPointTree_.remove(path);\r\n }\r\n var removed = removedAndEvents.removed;\r\n cancelEvents = removedAndEvents.events;\r\n // We may have just removed one of many listeners and can short-circuit this whole process\r\n // We may also not have removed a default listener, in which case all of the descendant listeners should already be\r\n // properly set up.\r\n //\r\n // Since indexed queries can shadow if they don't have other query constraints, check for loadsAllData(), instead of\r\n // queryId === 'default'\r\n var removingDefault = -1 !==\r\n removed.findIndex(function (query) {\r\n return query.getQueryParams().loadsAllData();\r\n });\r\n var covered = this.syncPointTree_.findOnPath(path, function (relativePath, parentSyncPoint) {\r\n return parentSyncPoint.hasCompleteView();\r\n });\r\n if (removingDefault && !covered) {\r\n var subtree = this.syncPointTree_.subtree(path);\r\n // There are potentially child listeners. Determine what if any listens we need to send before executing the\r\n // removal\r\n if (!subtree.isEmpty()) {\r\n // We need to fold over our subtree and collect the listeners to send\r\n var newViews = this.collectDistinctViewsForSubTree_(subtree);\r\n // Ok, we've collected all the listens we need. Set them up.\r\n for (var i = 0; i < newViews.length; ++i) {\r\n var view = newViews[i], newQuery = view.getQuery();\r\n var listener = this.createListenerForView_(view);\r\n this.listenProvider_.startListening(SyncTree.queryForListening_(newQuery), this.tagForQuery_(newQuery), listener.hashFn, listener.onComplete);\r\n }\r\n }\r\n }\r\n // If we removed anything and we're not covered by a higher up listen, we need to stop listening on this query\r\n // The above block has us covered in terms of making sure we're set up on listens lower in the tree.\r\n // Also, note that if we have a cancelError, it's already been removed at the provider level.\r\n if (!covered && removed.length > 0 && !cancelError) {\r\n // If we removed a default, then we weren't listening on any of the other queries here. Just cancel the one\r\n // default. Otherwise, we need to iterate through and cancel each individual query\r\n if (removingDefault) {\r\n // We don't tag default listeners\r\n var defaultTag = null;\r\n this.listenProvider_.stopListening(SyncTree.queryForListening_(query), defaultTag);\r\n }\r\n else {\r\n removed.forEach(function (queryToRemove) {\r\n var tagToRemove = _this.queryToTagMap_[SyncTree.makeQueryKey_(queryToRemove)];\r\n _this.listenProvider_.stopListening(SyncTree.queryForListening_(queryToRemove), tagToRemove);\r\n });\r\n }\r\n }\r\n // Now, clear all of the tags we're tracking for the removed listens\r\n this.removeTags_(removed);\r\n }\r\n return cancelEvents;\r\n };\r\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 */\r\n SyncTree.prototype.calcCompleteEventCache = function (path, writeIdsToExclude) {\r\n var includeHiddenSets = true;\r\n var writeTree = this.pendingWriteTree_;\r\n var serverCache = this.syncPointTree_.findOnPath(path, function (pathSoFar, syncPoint) {\r\n var relativePath = Path.relativePath(pathSoFar, path);\r\n var serverCache = syncPoint.getCompleteServerCache(relativePath);\r\n if (serverCache) {\r\n return serverCache;\r\n }\r\n });\r\n return writeTree.calcCompleteEventCache(path, serverCache, writeIdsToExclude, includeHiddenSets);\r\n };\r\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 */\r\n SyncTree.prototype.collectDistinctViewsForSubTree_ = function (subtree) {\r\n return subtree.fold(function (relativePath, maybeChildSyncPoint, childMap) {\r\n if (maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {\r\n var completeView = maybeChildSyncPoint.getCompleteView();\r\n return [completeView];\r\n }\r\n else {\r\n // No complete view here, flatten any deeper listens into an array\r\n var views_1 = [];\r\n if (maybeChildSyncPoint) {\r\n views_1 = maybeChildSyncPoint.getQueryViews();\r\n }\r\n forEach(childMap, function (key, childViews) {\r\n views_1 = views_1.concat(childViews);\r\n });\r\n return views_1;\r\n }\r\n });\r\n };\r\n /**\r\n * @param {!Array.} queries\r\n * @private\r\n */\r\n SyncTree.prototype.removeTags_ = function (queries) {\r\n for (var j = 0; j < queries.length; ++j) {\r\n var removedQuery = queries[j];\r\n if (!removedQuery.getQueryParams().loadsAllData()) {\r\n // We should have a tag for this\r\n var removedQueryKey = SyncTree.makeQueryKey_(removedQuery);\r\n var removedQueryTag = this.queryToTagMap_[removedQueryKey];\r\n delete this.queryToTagMap_[removedQueryKey];\r\n delete this.tagToQueryMap_['_' + removedQueryTag];\r\n }\r\n }\r\n };\r\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 */\r\n SyncTree.queryForListening_ = function (query) {\r\n if (query.getQueryParams().loadsAllData() &&\r\n !query.getQueryParams().isDefault()) {\r\n // We treat queries that load all data as default queries\r\n // Cast is necessary because ref() technically returns Firebase which is actually fb.api.Firebase which inherits\r\n // from Query\r\n return /** @type {!Query} */ query.getRef();\r\n }\r\n else {\r\n return query;\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.setupListener_ = function (query, view) {\r\n var path = query.path;\r\n var tag = this.tagForQuery_(query);\r\n var listener = this.createListenerForView_(view);\r\n var events = this.listenProvider_.startListening(SyncTree.queryForListening_(query), tag, listener.hashFn, listener.onComplete);\r\n var subtree = this.syncPointTree_.subtree(path);\r\n // The root of this subtree has our query. We're here because we definitely need to send a listen for that, but we\r\n // may need to shadow other listens as well.\r\n if (tag) {\r\n assert(!subtree.value.hasCompleteView(), \"If we're adding a query, it shouldn't be shadowed\");\r\n }\r\n else {\r\n // Shadow everything at or below this location, this is a default listener.\r\n var queriesToStop = subtree.fold(function (relativePath, maybeChildSyncPoint, childMap) {\r\n if (!relativePath.isEmpty() &&\r\n maybeChildSyncPoint &&\r\n maybeChildSyncPoint.hasCompleteView()) {\r\n return [maybeChildSyncPoint.getCompleteView().getQuery()];\r\n }\r\n else {\r\n // No default listener here, flatten any deeper queries into an array\r\n var queries_1 = [];\r\n if (maybeChildSyncPoint) {\r\n queries_1 = queries_1.concat(maybeChildSyncPoint.getQueryViews().map(function (view) { return view.getQuery(); }));\r\n }\r\n forEach(childMap, function (key, childQueries) {\r\n queries_1 = queries_1.concat(childQueries);\r\n });\r\n return queries_1;\r\n }\r\n });\r\n for (var i = 0; i < queriesToStop.length; ++i) {\r\n var queryToStop = queriesToStop[i];\r\n this.listenProvider_.stopListening(SyncTree.queryForListening_(queryToStop), this.tagForQuery_(queryToStop));\r\n }\r\n }\r\n return events;\r\n };\r\n /**\r\n *\r\n * @param {!View} view\r\n * @return {{hashFn: function(), onComplete: function(!string, *)}}\r\n * @private\r\n */\r\n SyncTree.prototype.createListenerForView_ = function (view) {\r\n var _this = this;\r\n var query = view.getQuery();\r\n var tag = this.tagForQuery_(query);\r\n return {\r\n hashFn: function () {\r\n var cache = view.getServerCache() || ChildrenNode.EMPTY_NODE;\r\n return cache.hash();\r\n },\r\n onComplete: function (status) {\r\n if (status === 'ok') {\r\n if (tag) {\r\n return _this.applyTaggedListenComplete(query.path, tag);\r\n }\r\n else {\r\n return _this.applyListenComplete(query.path);\r\n }\r\n }\r\n else {\r\n // If a listen failed, kill all of the listeners here, not just the one that triggered the error.\r\n // Note that this may need to be scoped to just this listener if we change permissions on filtered children\r\n var error = errorForServerCode(status, query);\r\n return _this.removeEventRegistration(query, \r\n /*eventRegistration*/ null, error);\r\n }\r\n }\r\n };\r\n };\r\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 */\r\n SyncTree.makeQueryKey_ = function (query) {\r\n return query.path.toString() + '$' + query.queryIdentifier();\r\n };\r\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 */\r\n SyncTree.parseQueryKey_ = function (queryKey) {\r\n var splitIndex = queryKey.indexOf('$');\r\n assert(splitIndex !== -1 && splitIndex < queryKey.length - 1, 'Bad queryKey.');\r\n return {\r\n queryId: queryKey.substr(splitIndex + 1),\r\n path: new Path(queryKey.substr(0, splitIndex))\r\n };\r\n };\r\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 */\r\n SyncTree.prototype.queryKeyForTag_ = function (tag) {\r\n return this.tagToQueryMap_['_' + tag];\r\n };\r\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 */\r\n SyncTree.prototype.tagForQuery_ = function (query) {\r\n var queryKey = SyncTree.makeQueryKey_(query);\r\n return safeGet(this.queryToTagMap_, queryKey);\r\n };\r\n /**\r\n * Static accessor for query tags.\r\n * @return {number}\r\n * @private\r\n */\r\n SyncTree.getNextQueryTag_ = function () {\r\n return SyncTree.nextQueryTag_++;\r\n };\r\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 */\r\n SyncTree.prototype.applyTaggedOperation_ = function (queryPath, operation) {\r\n var syncPoint = this.syncPointTree_.get(queryPath);\r\n assert(syncPoint, \"Missing sync point for query tag that we're tracking\");\r\n var writesCache = this.pendingWriteTree_.childWrites(queryPath);\r\n return syncPoint.applyOperation(operation, writesCache, \r\n /*serverCache=*/ null);\r\n };\r\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 \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 \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 */\r\n SyncTree.prototype.applyOperationToSyncPoints_ = function (operation) {\r\n return this.applyOperationHelper_(operation, this.syncPointTree_, \r\n /*serverCache=*/ null, this.pendingWriteTree_.childWrites(Path.Empty));\r\n };\r\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 */\r\n SyncTree.prototype.applyOperationHelper_ = function (operation, syncPointTree, serverCache, writesCache) {\r\n if (operation.path.isEmpty()) {\r\n return this.applyOperationDescendantsHelper_(operation, syncPointTree, serverCache, writesCache);\r\n }\r\n else {\r\n var syncPoint = syncPointTree.get(Path.Empty);\r\n // If we don't have cached server data, see if we can get it from this SyncPoint.\r\n if (serverCache == null && syncPoint != null) {\r\n serverCache = syncPoint.getCompleteServerCache(Path.Empty);\r\n }\r\n var events = [];\r\n var childName = operation.path.getFront();\r\n var childOperation = operation.operationForChild(childName);\r\n var childTree = syncPointTree.children.get(childName);\r\n if (childTree && childOperation) {\r\n var childServerCache = serverCache\r\n ? serverCache.getImmediateChild(childName)\r\n : null;\r\n var childWritesCache = writesCache.child(childName);\r\n events = events.concat(this.applyOperationHelper_(childOperation, childTree, childServerCache, childWritesCache));\r\n }\r\n if (syncPoint) {\r\n events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));\r\n }\r\n return events;\r\n }\r\n };\r\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 */\r\n SyncTree.prototype.applyOperationDescendantsHelper_ = function (operation, syncPointTree, serverCache, writesCache) {\r\n var _this = this;\r\n var syncPoint = syncPointTree.get(Path.Empty);\r\n // If we don't have cached server data, see if we can get it from this SyncPoint.\r\n if (serverCache == null && syncPoint != null) {\r\n serverCache = syncPoint.getCompleteServerCache(Path.Empty);\r\n }\r\n var events = [];\r\n syncPointTree.children.inorderTraversal(function (childName, childTree) {\r\n var childServerCache = serverCache\r\n ? serverCache.getImmediateChild(childName)\r\n : null;\r\n var childWritesCache = writesCache.child(childName);\r\n var childOperation = operation.operationForChild(childName);\r\n if (childOperation) {\r\n events = events.concat(_this.applyOperationDescendantsHelper_(childOperation, childTree, childServerCache, childWritesCache));\r\n }\r\n });\r\n if (syncPoint) {\r\n events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));\r\n }\r\n return events;\r\n };\r\n /**\r\n * Static tracker for next query tag.\r\n * @type {number}\r\n * @private\r\n */\r\n SyncTree.nextQueryTag_ = 1;\r\n return SyncTree;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Mutable object which basically just stores a reference to the \"latest\" immutable snapshot.\r\n *\r\n * @constructor\r\n */\r\nvar SnapshotHolder = /** @class */ (function () {\r\n function SnapshotHolder() {\r\n this.rootNode_ = ChildrenNode.EMPTY_NODE;\r\n }\r\n SnapshotHolder.prototype.getNode = function (path) {\r\n return this.rootNode_.getChild(path);\r\n };\r\n SnapshotHolder.prototype.updateSnapshot = function (path, newSnapshotNode) {\r\n this.rootNode_ = this.rootNode_.updateChild(path, newSnapshotNode);\r\n };\r\n return SnapshotHolder;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Abstraction around FirebaseApp's token fetching capabilities.\r\n */\r\nvar AuthTokenProvider = /** @class */ (function () {\r\n /**\r\n * @param {!FirebaseApp} app_\r\n */\r\n function AuthTokenProvider(app_) {\r\n this.app_ = app_;\r\n }\r\n /**\r\n * @param {boolean} forceRefresh\r\n * @return {!Promise}\r\n */\r\n AuthTokenProvider.prototype.getToken = function (forceRefresh) {\r\n return this.app_['INTERNAL']['getToken'](forceRefresh).then(null, \r\n // .catch\r\n function (error) {\r\n // TODO: Need to figure out all the cases this is raised and whether\r\n // this makes sense.\r\n if (error && error.code === 'auth/token-not-initialized') {\r\n log('Got auth/token-not-initialized error. Treating as null token.');\r\n return null;\r\n }\r\n else {\r\n return Promise.reject(error);\r\n }\r\n });\r\n };\r\n AuthTokenProvider.prototype.addTokenChangeListener = function (listener) {\r\n // TODO: We might want to wrap the listener and call it with no args to\r\n // avoid a leaky abstraction, but that makes removing the listener harder.\r\n this.app_['INTERNAL']['addAuthTokenListener'](listener);\r\n };\r\n AuthTokenProvider.prototype.removeTokenChangeListener = function (listener) {\r\n this.app_['INTERNAL']['removeAuthTokenListener'](listener);\r\n };\r\n AuthTokenProvider.prototype.notifyForInvalidToken = function () {\r\n var errorMessage = 'Provided authentication credentials for the app named \"' +\r\n this.app_.name +\r\n '\" are invalid. This usually indicates your app was not ' +\r\n 'initialized correctly. ';\r\n if ('credential' in this.app_.options) {\r\n errorMessage +=\r\n 'Make sure the \"credential\" property provided to initializeApp() ' +\r\n 'is authorized to access the specified \"databaseURL\" and is from the correct ' +\r\n 'project.';\r\n }\r\n else if ('serviceAccount' in this.app_.options) {\r\n errorMessage +=\r\n 'Make sure the \"serviceAccount\" property provided to initializeApp() ' +\r\n 'is authorized to access the specified \"databaseURL\" and is from the correct ' +\r\n 'project.';\r\n }\r\n else {\r\n errorMessage +=\r\n 'Make sure the \"apiKey\" and \"databaseURL\" properties provided to ' +\r\n 'initializeApp() match the values provided for your app at ' +\r\n 'https://console.firebase.google.com/.';\r\n }\r\n warn(errorMessage);\r\n };\r\n return AuthTokenProvider;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Tracks a collection of stats.\r\n *\r\n * @constructor\r\n */\r\nvar StatsCollection = /** @class */ (function () {\r\n function StatsCollection() {\r\n this.counters_ = {};\r\n }\r\n StatsCollection.prototype.incrementCounter = function (name, amount) {\r\n if (amount === void 0) { amount = 1; }\r\n if (!contains(this.counters_, name))\r\n this.counters_[name] = 0;\r\n this.counters_[name] += amount;\r\n };\r\n StatsCollection.prototype.get = function () {\r\n return deepCopy(this.counters_);\r\n };\r\n return StatsCollection;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar StatsManager = /** @class */ (function () {\r\n function StatsManager() {\r\n }\r\n StatsManager.getCollection = function (repoInfo) {\r\n var hashString = repoInfo.toString();\r\n if (!this.collections_[hashString]) {\r\n this.collections_[hashString] = new StatsCollection();\r\n }\r\n return this.collections_[hashString];\r\n };\r\n StatsManager.getOrCreateReporter = function (repoInfo, creatorFunction) {\r\n var hashString = repoInfo.toString();\r\n if (!this.reporters_[hashString]) {\r\n this.reporters_[hashString] = creatorFunction();\r\n }\r\n return this.reporters_[hashString];\r\n };\r\n StatsManager.collections_ = {};\r\n StatsManager.reporters_ = {};\r\n return StatsManager;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar StatsListener = /** @class */ (function () {\r\n function StatsListener(collection_) {\r\n this.collection_ = collection_;\r\n this.last_ = null;\r\n }\r\n StatsListener.prototype.get = function () {\r\n var newStats = this.collection_.get();\r\n var delta = clone(newStats);\r\n if (this.last_) {\r\n forEach(this.last_, function (stat, value) {\r\n delta[stat] = delta[stat] - value;\r\n });\r\n }\r\n this.last_ = newStats;\r\n return delta;\r\n };\r\n return StatsListener;\r\n}());\n\n/**\r\n * @license\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 */\r\n// Assuming some apps may have a short amount of time on page, and a bulk of firebase operations probably\r\n// happen on page load, we try to report our first set of stats pretty quickly, but we wait at least 10\r\n// seconds to try to ensure the Firebase connection is established / settled.\r\nvar FIRST_STATS_MIN_TIME = 10 * 1000;\r\nvar FIRST_STATS_MAX_TIME = 30 * 1000;\r\n// We'll continue to report stats on average every 5 minutes.\r\nvar REPORT_STATS_INTERVAL = 5 * 60 * 1000;\r\n/**\r\n * @constructor\r\n */\r\nvar StatsReporter = /** @class */ (function () {\r\n /**\r\n * @param collection\r\n * @param server_\r\n */\r\n function StatsReporter(collection, server_) {\r\n this.server_ = server_;\r\n this.statsToReport_ = {};\r\n this.statsListener_ = new StatsListener(collection);\r\n var timeout = FIRST_STATS_MIN_TIME +\r\n (FIRST_STATS_MAX_TIME - FIRST_STATS_MIN_TIME) * Math.random();\r\n setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(timeout));\r\n }\r\n StatsReporter.prototype.includeStat = function (stat) {\r\n this.statsToReport_[stat] = true;\r\n };\r\n StatsReporter.prototype.reportStats_ = function () {\r\n var _this = this;\r\n var stats = this.statsListener_.get();\r\n var reportedStats = {};\r\n var haveStatsToReport = false;\r\n forEach(stats, function (stat, value) {\r\n if (value > 0 && contains(_this.statsToReport_, stat)) {\r\n reportedStats[stat] = value;\r\n haveStatsToReport = true;\r\n }\r\n });\r\n if (haveStatsToReport) {\r\n this.server_.reportStats(reportedStats);\r\n }\r\n // queue our next run.\r\n setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL));\r\n };\r\n return StatsReporter;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar EventQueue = /** @class */ (function () {\r\n function EventQueue() {\r\n /**\r\n * @private\r\n * @type {!Array.}\r\n */\r\n this.eventLists_ = [];\r\n /**\r\n * Tracks recursion depth of raiseQueuedEvents_, for debugging purposes.\r\n * @private\r\n * @type {!number}\r\n */\r\n this.recursionDepth_ = 0;\r\n }\r\n /**\r\n * @param {!Array.} eventDataList The new events to queue.\r\n */\r\n EventQueue.prototype.queueEvents = function (eventDataList) {\r\n // We group events by path, storing them in a single EventList, to make it easier to skip over them quickly.\r\n var currList = null;\r\n for (var i = 0; i < eventDataList.length; i++) {\r\n var eventData = eventDataList[i];\r\n var eventPath = eventData.getPath();\r\n if (currList !== null && !eventPath.equals(currList.getPath())) {\r\n this.eventLists_.push(currList);\r\n currList = null;\r\n }\r\n if (currList === null) {\r\n currList = new EventList(eventPath);\r\n }\r\n currList.add(eventData);\r\n }\r\n if (currList) {\r\n this.eventLists_.push(currList);\r\n }\r\n };\r\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 */\r\n EventQueue.prototype.raiseEventsAtPath = function (path, eventDataList) {\r\n this.queueEvents(eventDataList);\r\n this.raiseQueuedEventsMatchingPredicate_(function (eventPath) {\r\n return eventPath.equals(path);\r\n });\r\n };\r\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 */\r\n EventQueue.prototype.raiseEventsForChangedPath = function (changedPath, eventDataList) {\r\n this.queueEvents(eventDataList);\r\n this.raiseQueuedEventsMatchingPredicate_(function (eventPath) {\r\n return eventPath.contains(changedPath) || changedPath.contains(eventPath);\r\n });\r\n };\r\n /**\r\n * @param {!function(!Path):boolean} predicate\r\n * @private\r\n */\r\n EventQueue.prototype.raiseQueuedEventsMatchingPredicate_ = function (predicate) {\r\n this.recursionDepth_++;\r\n var sentAll = true;\r\n for (var i = 0; i < this.eventLists_.length; i++) {\r\n var eventList = this.eventLists_[i];\r\n if (eventList) {\r\n var eventPath = eventList.getPath();\r\n if (predicate(eventPath)) {\r\n this.eventLists_[i].raise();\r\n this.eventLists_[i] = null;\r\n }\r\n else {\r\n sentAll = false;\r\n }\r\n }\r\n }\r\n if (sentAll) {\r\n this.eventLists_ = [];\r\n }\r\n this.recursionDepth_--;\r\n };\r\n return EventQueue;\r\n}());\r\n/**\r\n * @param {!Path} path\r\n * @constructor\r\n */\r\nvar EventList = /** @class */ (function () {\r\n function EventList(path_) {\r\n this.path_ = path_;\r\n /**\r\n * @type {!Array.}\r\n * @private\r\n */\r\n this.events_ = [];\r\n }\r\n /**\r\n * @param {!Event} eventData\r\n */\r\n EventList.prototype.add = function (eventData) {\r\n this.events_.push(eventData);\r\n };\r\n /**\r\n * Iterates through the list and raises each event\r\n */\r\n EventList.prototype.raise = function () {\r\n for (var i = 0; i < this.events_.length; i++) {\r\n var eventData = this.events_[i];\r\n if (eventData !== null) {\r\n this.events_[i] = null;\r\n var eventFn = eventData.getEventRunner();\r\n if (logger) {\r\n log('event: ' + eventData.toString());\r\n }\r\n exceptionGuard(eventFn);\r\n }\r\n }\r\n };\r\n /**\r\n * @return {!Path}\r\n */\r\n EventList.prototype.getPath = function () {\r\n return this.path_;\r\n };\r\n return EventList;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar EventEmitter = /** @class */ (function () {\r\n /**\r\n * @param {!Array.} allowedEvents_\r\n */\r\n function EventEmitter(allowedEvents_) {\r\n this.allowedEvents_ = allowedEvents_;\r\n this.listeners_ = {};\r\n assert(Array.isArray(allowedEvents_) && allowedEvents_.length > 0, 'Requires a non-empty array');\r\n }\r\n /**\r\n * To be called by derived classes to trigger events.\r\n * @param {!string} eventType\r\n * @param {...*} var_args\r\n */\r\n EventEmitter.prototype.trigger = function (eventType) {\r\n var var_args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n var_args[_i - 1] = arguments[_i];\r\n }\r\n if (Array.isArray(this.listeners_[eventType])) {\r\n // Clone the list, since callbacks could add/remove listeners.\r\n var listeners = this.listeners_[eventType].slice();\r\n for (var i = 0; i < listeners.length; i++) {\r\n listeners[i].callback.apply(listeners[i].context, var_args);\r\n }\r\n }\r\n };\r\n EventEmitter.prototype.on = function (eventType, callback, context) {\r\n this.validateEventType_(eventType);\r\n this.listeners_[eventType] = this.listeners_[eventType] || [];\r\n this.listeners_[eventType].push({ callback: callback, context: context });\r\n var eventData = this.getInitialEvent(eventType);\r\n if (eventData) {\r\n callback.apply(context, eventData);\r\n }\r\n };\r\n EventEmitter.prototype.off = function (eventType, callback, context) {\r\n this.validateEventType_(eventType);\r\n var listeners = this.listeners_[eventType] || [];\r\n for (var i = 0; i < listeners.length; i++) {\r\n if (listeners[i].callback === callback &&\r\n (!context || context === listeners[i].context)) {\r\n listeners.splice(i, 1);\r\n return;\r\n }\r\n }\r\n };\r\n EventEmitter.prototype.validateEventType_ = function (eventType) {\r\n assert(this.allowedEvents_.find(function (et) {\r\n return et === eventType;\r\n }), 'Unknown event: ' + eventType);\r\n };\r\n return EventEmitter;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * @extends {EventEmitter}\r\n */\r\nvar VisibilityMonitor = /** @class */ (function (_super) {\r\n __extends(VisibilityMonitor, _super);\r\n function VisibilityMonitor() {\r\n var _this = _super.call(this, ['visible']) || this;\r\n var hidden;\r\n var visibilityChange;\r\n if (typeof document !== 'undefined' &&\r\n typeof document.addEventListener !== 'undefined') {\r\n if (typeof document['hidden'] !== 'undefined') {\r\n // Opera 12.10 and Firefox 18 and later support\r\n visibilityChange = 'visibilitychange';\r\n hidden = 'hidden';\r\n }\r\n else if (typeof document['mozHidden'] !== 'undefined') {\r\n visibilityChange = 'mozvisibilitychange';\r\n hidden = 'mozHidden';\r\n }\r\n else if (typeof document['msHidden'] !== 'undefined') {\r\n visibilityChange = 'msvisibilitychange';\r\n hidden = 'msHidden';\r\n }\r\n else if (typeof document['webkitHidden'] !== 'undefined') {\r\n visibilityChange = 'webkitvisibilitychange';\r\n hidden = 'webkitHidden';\r\n }\r\n }\r\n // Initially, we always assume we are visible. This ensures that in browsers\r\n // without page visibility support or in cases where we are never visible\r\n // (e.g. chrome extension), we act as if we are visible, i.e. don't delay\r\n // reconnects\r\n _this.visible_ = true;\r\n if (visibilityChange) {\r\n document.addEventListener(visibilityChange, function () {\r\n var visible = !document[hidden];\r\n if (visible !== _this.visible_) {\r\n _this.visible_ = visible;\r\n _this.trigger('visible', visible);\r\n }\r\n }, false);\r\n }\r\n return _this;\r\n }\r\n VisibilityMonitor.getInstance = function () {\r\n return new VisibilityMonitor();\r\n };\r\n /**\r\n * @param {!string} eventType\r\n * @return {Array.}\r\n */\r\n VisibilityMonitor.prototype.getInitialEvent = function (eventType) {\r\n assert(eventType === 'visible', 'Unknown event type: ' + eventType);\r\n return [this.visible_];\r\n };\r\n return VisibilityMonitor;\r\n}(EventEmitter));\n\n/**\r\n * @license\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 */\r\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 */\r\nvar OnlineMonitor = /** @class */ (function (_super) {\r\n __extends(OnlineMonitor, _super);\r\n function OnlineMonitor() {\r\n var _this = _super.call(this, ['online']) || this;\r\n _this.online_ = true;\r\n // We've had repeated complaints that Cordova apps can get stuck \"offline\", e.g.\r\n // https://forum.ionicframework.com/t/firebase-connection-is-lost-and-never-come-back/43810\r\n // It would seem that the 'online' event does not always fire consistently. So we disable it\r\n // for Cordova.\r\n if (typeof window !== 'undefined' &&\r\n typeof window.addEventListener !== 'undefined' &&\r\n !isMobileCordova()) {\r\n window.addEventListener('online', function () {\r\n if (!_this.online_) {\r\n _this.online_ = true;\r\n _this.trigger('online', true);\r\n }\r\n }, false);\r\n window.addEventListener('offline', function () {\r\n if (_this.online_) {\r\n _this.online_ = false;\r\n _this.trigger('online', false);\r\n }\r\n }, false);\r\n }\r\n return _this;\r\n }\r\n OnlineMonitor.getInstance = function () {\r\n return new OnlineMonitor();\r\n };\r\n /**\r\n * @param {!string} eventType\r\n * @return {Array.}\r\n */\r\n OnlineMonitor.prototype.getInitialEvent = function (eventType) {\r\n assert(eventType === 'online', 'Unknown event type: ' + eventType);\r\n return [this.online_];\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n OnlineMonitor.prototype.currentlyOnline = function () {\r\n return this.online_;\r\n };\r\n return OnlineMonitor;\r\n}(EventEmitter));\n\n/**\r\n * @license\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 */\r\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 */\r\nvar PacketReceiver = /** @class */ (function () {\r\n /**\r\n * @param onMessage_\r\n */\r\n function PacketReceiver(onMessage_) {\r\n this.onMessage_ = onMessage_;\r\n this.pendingResponses = [];\r\n this.currentResponseNum = 0;\r\n this.closeAfterResponse = -1;\r\n this.onClose = null;\r\n }\r\n PacketReceiver.prototype.closeAfter = function (responseNum, callback) {\r\n this.closeAfterResponse = responseNum;\r\n this.onClose = callback;\r\n if (this.closeAfterResponse < this.currentResponseNum) {\r\n this.onClose();\r\n this.onClose = null;\r\n }\r\n };\r\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 */\r\n PacketReceiver.prototype.handleResponse = function (requestNum, data) {\r\n var _this = this;\r\n this.pendingResponses[requestNum] = data;\r\n var _loop_1 = function () {\r\n var toProcess = this_1.pendingResponses[this_1.currentResponseNum];\r\n delete this_1.pendingResponses[this_1.currentResponseNum];\r\n var _loop_2 = function (i) {\r\n if (toProcess[i]) {\r\n exceptionGuard(function () {\r\n _this.onMessage_(toProcess[i]);\r\n });\r\n }\r\n };\r\n for (var i = 0; i < toProcess.length; ++i) {\r\n _loop_2(i);\r\n }\r\n if (this_1.currentResponseNum === this_1.closeAfterResponse) {\r\n if (this_1.onClose) {\r\n this_1.onClose();\r\n this_1.onClose = null;\r\n }\r\n return \"break\";\r\n }\r\n this_1.currentResponseNum++;\r\n };\r\n var this_1 = this;\r\n while (this.pendingResponses[this.currentResponseNum]) {\r\n var state_1 = _loop_1();\r\n if (state_1 === \"break\")\r\n break;\r\n }\r\n };\r\n return PacketReceiver;\r\n}());\n\n/**\r\n * @license\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 */\r\n// URL query parameters associated with longpolling\r\nvar FIREBASE_LONGPOLL_START_PARAM = 'start';\r\nvar FIREBASE_LONGPOLL_CLOSE_COMMAND = 'close';\r\nvar FIREBASE_LONGPOLL_COMMAND_CB_NAME = 'pLPCommand';\r\nvar FIREBASE_LONGPOLL_DATA_CB_NAME = 'pRTLPCB';\r\nvar FIREBASE_LONGPOLL_ID_PARAM = 'id';\r\nvar FIREBASE_LONGPOLL_PW_PARAM = 'pw';\r\nvar FIREBASE_LONGPOLL_SERIAL_PARAM = 'ser';\r\nvar FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = 'cb';\r\nvar FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = 'seg';\r\nvar FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = 'ts';\r\nvar FIREBASE_LONGPOLL_DATA_PARAM = 'd';\r\nvar FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = 'disconn';\r\nvar FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = 'dframe';\r\n//Data size constants.\r\n//TODO: Perf: the maximum length actually differs from browser to browser.\r\n// We should check what browser we're on and set accordingly.\r\nvar MAX_URL_DATA_SIZE = 1870;\r\nvar SEG_HEADER_SIZE = 30; //ie: &seg=8299234&ts=982389123&d=\r\nvar MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE;\r\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 */\r\nvar KEEPALIVE_REQUEST_INTERVAL = 25000;\r\n/**\r\n * How long to wait before aborting a long-polling connection attempt.\r\n * @const\r\n * @type {number}\r\n */\r\nvar LP_CONNECT_TIMEOUT = 30000;\r\n/**\r\n * This class manages a single long-polling connection.\r\n *\r\n * @constructor\r\n * @implements {Transport}\r\n */\r\nvar BrowserPollConnection = /** @class */ (function () {\r\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 */\r\n function BrowserPollConnection(connId, repoInfo, transportSessionId, lastSessionId) {\r\n this.connId = connId;\r\n this.repoInfo = repoInfo;\r\n this.transportSessionId = transportSessionId;\r\n this.lastSessionId = lastSessionId;\r\n this.bytesSent = 0;\r\n this.bytesReceived = 0;\r\n this.everConnected_ = false;\r\n this.log_ = logWrapper(connId);\r\n this.stats_ = StatsManager.getCollection(repoInfo);\r\n this.urlFn = function (params) {\r\n return repoInfo.connectionURL(LONG_POLLING, params);\r\n };\r\n }\r\n /**\r\n *\r\n * @param {function(Object)} onMessage Callback when messages arrive\r\n * @param {function()} onDisconnect Callback with connection lost.\r\n */\r\n BrowserPollConnection.prototype.open = function (onMessage, onDisconnect) {\r\n var _this = this;\r\n this.curSegmentNum = 0;\r\n this.onDisconnect_ = onDisconnect;\r\n this.myPacketOrderer = new PacketReceiver(onMessage);\r\n this.isClosed_ = false;\r\n this.connectTimeoutTimer_ = setTimeout(function () {\r\n _this.log_('Timed out trying to connect.');\r\n // Make sure we clear the host cache\r\n _this.onClosed_();\r\n _this.connectTimeoutTimer_ = null;\r\n }, Math.floor(LP_CONNECT_TIMEOUT));\r\n // Ensure we delay the creation of the iframe until the DOM is loaded.\r\n executeWhenDOMReady(function () {\r\n if (_this.isClosed_)\r\n return;\r\n //Set up a callback that gets triggered once a connection is set up.\r\n _this.scriptTagHolder = new FirebaseIFrameScriptHolder(function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n var command = args[0], arg1 = args[1], arg2 = args[2];\r\n _this.incrementIncomingBytes_(args);\r\n if (!_this.scriptTagHolder)\r\n return; // we closed the connection.\r\n if (_this.connectTimeoutTimer_) {\r\n clearTimeout(_this.connectTimeoutTimer_);\r\n _this.connectTimeoutTimer_ = null;\r\n }\r\n _this.everConnected_ = true;\r\n if (command == FIREBASE_LONGPOLL_START_PARAM) {\r\n _this.id = arg1;\r\n _this.password = arg2;\r\n }\r\n else if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) {\r\n // Don't clear the host cache. We got a response from the server, so we know it's reachable\r\n if (arg1) {\r\n // We aren't expecting any more data (other than what the server's already in the process of sending us\r\n // through our already open polls), so don't send any more.\r\n _this.scriptTagHolder.sendNewPolls = false;\r\n // arg1 in this case is the last response number sent by the server. We should try to receive\r\n // all of the responses up to this one before closing\r\n _this.myPacketOrderer.closeAfter(arg1, function () {\r\n _this.onClosed_();\r\n });\r\n }\r\n else {\r\n _this.onClosed_();\r\n }\r\n }\r\n else {\r\n throw new Error('Unrecognized command received: ' + command);\r\n }\r\n }, function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n var pN = args[0], data = args[1];\r\n _this.incrementIncomingBytes_(args);\r\n _this.myPacketOrderer.handleResponse(pN, data);\r\n }, function () {\r\n _this.onClosed_();\r\n }, _this.urlFn);\r\n //Send the initial request to connect. The serial number is simply to keep the browser from pulling previous results\r\n //from cache.\r\n var urlParams = {};\r\n urlParams[FIREBASE_LONGPOLL_START_PARAM] = 't';\r\n urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(Math.random() * 100000000);\r\n if (_this.scriptTagHolder.uniqueCallbackIdentifier)\r\n urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = _this.scriptTagHolder.uniqueCallbackIdentifier;\r\n urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\r\n if (_this.transportSessionId) {\r\n urlParams[TRANSPORT_SESSION_PARAM] = _this.transportSessionId;\r\n }\r\n if (_this.lastSessionId) {\r\n urlParams[LAST_SESSION_PARAM] = _this.lastSessionId;\r\n }\r\n if (!isNodeSdk() &&\r\n typeof location !== 'undefined' &&\r\n location.href &&\r\n location.href.indexOf(FORGE_DOMAIN) !== -1) {\r\n urlParams[REFERER_PARAM] = FORGE_REF;\r\n }\r\n var connectURL = _this.urlFn(urlParams);\r\n _this.log_('Connecting via long-poll to ' + connectURL);\r\n _this.scriptTagHolder.addTag(connectURL, function () {\r\n /* do nothing */\r\n });\r\n });\r\n };\r\n /**\r\n * Call this when a handshake has completed successfully and we want to consider the connection established\r\n */\r\n BrowserPollConnection.prototype.start = function () {\r\n this.scriptTagHolder.startLongPoll(this.id, this.password);\r\n this.addDisconnectPingFrame(this.id, this.password);\r\n };\r\n /**\r\n * Forces long polling to be considered as a potential transport\r\n */\r\n BrowserPollConnection.forceAllow = function () {\r\n BrowserPollConnection.forceAllow_ = true;\r\n };\r\n /**\r\n * Forces longpolling to not be considered as a potential transport\r\n */\r\n BrowserPollConnection.forceDisallow = function () {\r\n BrowserPollConnection.forceDisallow_ = true;\r\n };\r\n // Static method, use string literal so it can be accessed in a generic way\r\n BrowserPollConnection.isAvailable = function () {\r\n // NOTE: In React-Native there's normally no 'document', but if you debug a React-Native app in\r\n // the Chrome debugger, 'document' is defined, but document.createElement is null (2015/06/08).\r\n return (BrowserPollConnection.forceAllow_ ||\r\n (!BrowserPollConnection.forceDisallow_ &&\r\n typeof document !== 'undefined' &&\r\n document.createElement != null &&\r\n !isChromeExtensionContentScript() &&\r\n !isWindowsStoreApp() &&\r\n !isNodeSdk()));\r\n };\r\n /**\r\n * No-op for polling\r\n */\r\n BrowserPollConnection.prototype.markConnectionHealthy = function () { };\r\n /**\r\n * Stops polling and cleans up the iframe\r\n * @private\r\n */\r\n BrowserPollConnection.prototype.shutdown_ = function () {\r\n this.isClosed_ = true;\r\n if (this.scriptTagHolder) {\r\n this.scriptTagHolder.close();\r\n this.scriptTagHolder = null;\r\n }\r\n //remove the disconnect frame, which will trigger an XHR call to the server to tell it we're leaving.\r\n if (this.myDisconnFrame) {\r\n document.body.removeChild(this.myDisconnFrame);\r\n this.myDisconnFrame = null;\r\n }\r\n if (this.connectTimeoutTimer_) {\r\n clearTimeout(this.connectTimeoutTimer_);\r\n this.connectTimeoutTimer_ = null;\r\n }\r\n };\r\n /**\r\n * Triggered when this transport is closed\r\n * @private\r\n */\r\n BrowserPollConnection.prototype.onClosed_ = function () {\r\n if (!this.isClosed_) {\r\n this.log_('Longpoll is closing itself');\r\n this.shutdown_();\r\n if (this.onDisconnect_) {\r\n this.onDisconnect_(this.everConnected_);\r\n this.onDisconnect_ = null;\r\n }\r\n }\r\n };\r\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 */\r\n BrowserPollConnection.prototype.close = function () {\r\n if (!this.isClosed_) {\r\n this.log_('Longpoll is being closed.');\r\n this.shutdown_();\r\n }\r\n };\r\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 */\r\n BrowserPollConnection.prototype.send = function (data) {\r\n var dataStr = stringify(data);\r\n this.bytesSent += dataStr.length;\r\n this.stats_.incrementCounter('bytes_sent', dataStr.length);\r\n //first, lets get the base64-encoded data\r\n var base64data = base64Encode(dataStr);\r\n //We can only fit a certain amount in each URL, so we need to split this request\r\n //up into multiple pieces if it doesn't fit in one request.\r\n var dataSegs = splitStringBySize(base64data, MAX_PAYLOAD_SIZE);\r\n //Enqueue each segment for transmission. We assign each chunk a sequential ID and a total number\r\n //of segments so that we can reassemble the packet on the server.\r\n for (var i = 0; i < dataSegs.length; i++) {\r\n this.scriptTagHolder.enqueueSegment(this.curSegmentNum, dataSegs.length, dataSegs[i]);\r\n this.curSegmentNum++;\r\n }\r\n };\r\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 */\r\n BrowserPollConnection.prototype.addDisconnectPingFrame = function (id, pw) {\r\n if (isNodeSdk())\r\n return;\r\n this.myDisconnFrame = document.createElement('iframe');\r\n var urlParams = {};\r\n urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = 't';\r\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = id;\r\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = pw;\r\n this.myDisconnFrame.src = this.urlFn(urlParams);\r\n this.myDisconnFrame.style.display = 'none';\r\n document.body.appendChild(this.myDisconnFrame);\r\n };\r\n /**\r\n * Used to track the bytes received by this client\r\n * @param {*} args\r\n * @private\r\n */\r\n BrowserPollConnection.prototype.incrementIncomingBytes_ = function (args) {\r\n // TODO: This is an annoying perf hit just to track the number of incoming bytes. Maybe it should be opt-in.\r\n var bytesReceived = stringify(args).length;\r\n this.bytesReceived += bytesReceived;\r\n this.stats_.incrementCounter('bytes_received', bytesReceived);\r\n };\r\n return BrowserPollConnection;\r\n}());\r\n/*********************************************************************************************\r\n * A wrapper around an iframe that is used as a long-polling script holder.\r\n * @constructor\r\n *********************************************************************************************/\r\nvar FirebaseIFrameScriptHolder = /** @class */ (function () {\r\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 */\r\n function FirebaseIFrameScriptHolder(commandCB, onMessageCB, onDisconnect, urlFn) {\r\n this.onDisconnect = onDisconnect;\r\n this.urlFn = urlFn;\r\n //We maintain a count of all of the outstanding requests, because if we have too many active at once it can cause\r\n //problems in some browsers.\r\n /**\r\n * @type {CountedSet.}\r\n */\r\n this.outstandingRequests = new CountedSet();\r\n //A queue of the pending segments waiting for transmission to the server.\r\n this.pendingSegs = [];\r\n //A serial number. We use this for two things:\r\n // 1) A way to ensure the browser doesn't cache responses to polls\r\n // 2) A way to make the server aware when long-polls arrive in a different order than we started them. The\r\n // server needs to release both polls in this case or it will cause problems in Opera since Opera can only execute\r\n // JSONP code in the order it was added to the iframe.\r\n this.currentSerial = Math.floor(Math.random() * 100000000);\r\n // This gets set to false when we're \"closing down\" the connection (e.g. we're switching transports but there's still\r\n // incoming data from the server that we're waiting for).\r\n this.sendNewPolls = true;\r\n if (!isNodeSdk()) {\r\n //Each script holder registers a couple of uniquely named callbacks with the window. These are called from the\r\n //iframes where we put the long-polling script tags. We have two callbacks:\r\n // 1) Command Callback - Triggered for control issues, like starting a connection.\r\n // 2) Message Callback - Triggered when new data arrives.\r\n this.uniqueCallbackIdentifier = LUIDGenerator();\r\n window[FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier] = commandCB;\r\n window[FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier] = onMessageCB;\r\n //Create an iframe for us to add script tags to.\r\n this.myIFrame = FirebaseIFrameScriptHolder.createIFrame_();\r\n // Set the iframe's contents.\r\n var script = '';\r\n // if we set a javascript url, it's IE and we need to set the document domain. The javascript url is sufficient\r\n // for ie9, but ie8 needs to do it again in the document itself.\r\n if (this.myIFrame.src &&\r\n this.myIFrame.src.substr(0, 'javascript:'.length) === 'javascript:') {\r\n var currentDomain = document.domain;\r\n script = '';\r\n }\r\n var iframeContents = '' + script + '';\r\n try {\r\n this.myIFrame.doc.open();\r\n this.myIFrame.doc.write(iframeContents);\r\n this.myIFrame.doc.close();\r\n }\r\n catch (e) {\r\n log('frame writing exception');\r\n if (e.stack) {\r\n log(e.stack);\r\n }\r\n log(e);\r\n }\r\n }\r\n else {\r\n this.commandCB = commandCB;\r\n this.onMessageCB = onMessageCB;\r\n }\r\n }\r\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 */\r\n FirebaseIFrameScriptHolder.createIFrame_ = function () {\r\n var iframe = document.createElement('iframe');\r\n iframe.style.display = 'none';\r\n // This is necessary in order to initialize the document inside the iframe\r\n if (document.body) {\r\n document.body.appendChild(iframe);\r\n try {\r\n // If document.domain has been modified in IE, this will throw an error, and we need to set the\r\n // domain of the iframe's document manually. We can do this via a javascript: url as the src attribute\r\n // Also note that we must do this *after* the iframe has been appended to the page. Otherwise it doesn't work.\r\n var a = iframe.contentWindow.document;\r\n if (!a) {\r\n // Apologies for the log-spam, I need to do something to keep closure from optimizing out the assignment above.\r\n log('No IE domain setting required');\r\n }\r\n }\r\n catch (e) {\r\n var domain = document.domain;\r\n iframe.src =\r\n \"javascript:void((function(){document.open();document.domain='\" +\r\n domain +\r\n \"';document.close();})())\";\r\n }\r\n }\r\n else {\r\n // LongPollConnection attempts to delay initialization until the document is ready, so hopefully this\r\n // never gets hit.\r\n throw 'Document body has not initialized. Wait to initialize Firebase until after the document is ready.';\r\n }\r\n // Get the document of the iframe in a browser-specific way.\r\n if (iframe.contentDocument) {\r\n iframe.doc = iframe.contentDocument; // Firefox, Opera, Safari\r\n }\r\n else if (iframe.contentWindow) {\r\n iframe.doc = iframe.contentWindow.document; // Internet Explorer\r\n }\r\n else if (iframe.document) {\r\n iframe.doc = iframe.document; //others?\r\n }\r\n return iframe;\r\n };\r\n /**\r\n * Cancel all outstanding queries and remove the frame.\r\n */\r\n FirebaseIFrameScriptHolder.prototype.close = function () {\r\n var _this = this;\r\n //Mark this iframe as dead, so no new requests are sent.\r\n this.alive = false;\r\n if (this.myIFrame) {\r\n //We have to actually remove all of the html inside this iframe before removing it from the\r\n //window, or IE will continue loading and executing the script tags we've already added, which\r\n //can lead to some errors being thrown. Setting innerHTML seems to be the easiest way to do this.\r\n this.myIFrame.doc.body.innerHTML = '';\r\n setTimeout(function () {\r\n if (_this.myIFrame !== null) {\r\n document.body.removeChild(_this.myIFrame);\r\n _this.myIFrame = null;\r\n }\r\n }, Math.floor(0));\r\n }\r\n if (isNodeSdk() && this.myID) {\r\n var urlParams = {};\r\n urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM] = 't';\r\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\r\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\r\n var theURL = this.urlFn(urlParams);\r\n FirebaseIFrameScriptHolder.nodeRestRequest(theURL);\r\n }\r\n // Protect from being called recursively.\r\n var onDisconnect = this.onDisconnect;\r\n if (onDisconnect) {\r\n this.onDisconnect = null;\r\n onDisconnect();\r\n }\r\n };\r\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 */\r\n FirebaseIFrameScriptHolder.prototype.startLongPoll = function (id, pw) {\r\n this.myID = id;\r\n this.myPW = pw;\r\n this.alive = true;\r\n //send the initial request. If there are requests queued, make sure that we transmit as many as we are currently able to.\r\n while (this.newRequest_()) { }\r\n };\r\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 */\r\n FirebaseIFrameScriptHolder.prototype.newRequest_ = function () {\r\n // We keep one outstanding request open all the time to receive data, but if we need to send data\r\n // (pendingSegs.length > 0) then we create a new request to send the data. The server will automatically\r\n // close the old request.\r\n if (this.alive &&\r\n this.sendNewPolls &&\r\n this.outstandingRequests.count() < (this.pendingSegs.length > 0 ? 2 : 1)) {\r\n //construct our url\r\n this.currentSerial++;\r\n var urlParams = {};\r\n urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;\r\n urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;\r\n urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial;\r\n var theURL = this.urlFn(urlParams);\r\n //Now add as much data as we can.\r\n var curDataString = '';\r\n var i = 0;\r\n while (this.pendingSegs.length > 0) {\r\n //first, lets see if the next segment will fit.\r\n var nextSeg = this.pendingSegs[0];\r\n if (nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <=\r\n MAX_URL_DATA_SIZE) {\r\n //great, the segment will fit. Lets append it.\r\n var theSeg = this.pendingSegs.shift();\r\n curDataString =\r\n curDataString +\r\n '&' +\r\n FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM +\r\n i +\r\n '=' +\r\n theSeg.seg +\r\n '&' +\r\n FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET +\r\n i +\r\n '=' +\r\n theSeg.ts +\r\n '&' +\r\n FIREBASE_LONGPOLL_DATA_PARAM +\r\n i +\r\n '=' +\r\n theSeg.d;\r\n i++;\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n theURL = theURL + curDataString;\r\n this.addLongPollTag_(theURL, this.currentSerial);\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n };\r\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 */\r\n FirebaseIFrameScriptHolder.prototype.enqueueSegment = function (segnum, totalsegs, data) {\r\n //add this to the queue of segments to send.\r\n this.pendingSegs.push({ seg: segnum, ts: totalsegs, d: data });\r\n //send the data immediately if there isn't already data being transmitted, unless\r\n //startLongPoll hasn't been called yet.\r\n if (this.alive) {\r\n this.newRequest_();\r\n }\r\n };\r\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 */\r\n FirebaseIFrameScriptHolder.prototype.addLongPollTag_ = function (url, serial) {\r\n var _this = this;\r\n //remember that we sent this request.\r\n this.outstandingRequests.add(serial, 1);\r\n var doNewRequest = function () {\r\n _this.outstandingRequests.remove(serial);\r\n _this.newRequest_();\r\n };\r\n // If this request doesn't return on its own accord (by the server sending us some data), we'll\r\n // create a new one after the KEEPALIVE interval to make sure we always keep a fresh request open.\r\n var keepaliveTimeout = setTimeout(doNewRequest, Math.floor(KEEPALIVE_REQUEST_INTERVAL));\r\n var readyStateCB = function () {\r\n // Request completed. Cancel the keepalive.\r\n clearTimeout(keepaliveTimeout);\r\n // Trigger a new request so we can continue receiving data.\r\n doNewRequest();\r\n };\r\n this.addTag(url, readyStateCB);\r\n };\r\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 */\r\n FirebaseIFrameScriptHolder.prototype.addTag = function (url, loadCB) {\r\n var _this = this;\r\n if (isNodeSdk()) {\r\n this.doNodeLongPoll(url, loadCB);\r\n }\r\n else {\r\n setTimeout(function () {\r\n try {\r\n // if we're already closed, don't add this poll\r\n if (!_this.sendNewPolls)\r\n return;\r\n var newScript_1 = _this.myIFrame.doc.createElement('script');\r\n newScript_1.type = 'text/javascript';\r\n newScript_1.async = true;\r\n newScript_1.src = url;\r\n newScript_1.onload = newScript_1.onreadystatechange = function () {\r\n var rstate = newScript_1.readyState;\r\n if (!rstate || rstate === 'loaded' || rstate === 'complete') {\r\n newScript_1.onload = newScript_1.onreadystatechange = null;\r\n if (newScript_1.parentNode) {\r\n newScript_1.parentNode.removeChild(newScript_1);\r\n }\r\n loadCB();\r\n }\r\n };\r\n newScript_1.onerror = function () {\r\n log('Long-poll script failed to load: ' + url);\r\n _this.sendNewPolls = false;\r\n _this.close();\r\n };\r\n _this.myIFrame.doc.body.appendChild(newScript_1);\r\n }\r\n catch (e) {\r\n // TODO: we should make this error visible somehow\r\n }\r\n }, Math.floor(1));\r\n }\r\n };\r\n return FirebaseIFrameScriptHolder;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar WEBSOCKET_MAX_FRAME_SIZE = 16384;\r\nvar WEBSOCKET_KEEPALIVE_INTERVAL = 45000;\r\nvar WebSocketImpl = null;\r\nif (typeof MozWebSocket !== 'undefined') {\r\n WebSocketImpl = MozWebSocket;\r\n}\r\nelse if (typeof WebSocket !== 'undefined') {\r\n WebSocketImpl = WebSocket;\r\n}\r\n/**\r\n * Create a new websocket connection with the given callbacks.\r\n * @constructor\r\n * @implements {Transport}\r\n */\r\nvar WebSocketConnection = /** @class */ (function () {\r\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 */\r\n function WebSocketConnection(connId, repoInfo, transportSessionId, lastSessionId) {\r\n this.connId = connId;\r\n this.keepaliveTimer = null;\r\n this.frames = null;\r\n this.totalFrames = 0;\r\n this.bytesSent = 0;\r\n this.bytesReceived = 0;\r\n this.log_ = logWrapper(this.connId);\r\n this.stats_ = StatsManager.getCollection(repoInfo);\r\n this.connURL = WebSocketConnection.connectionURL_(repoInfo, transportSessionId, lastSessionId);\r\n }\r\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 */\r\n WebSocketConnection.connectionURL_ = function (repoInfo, transportSessionId, lastSessionId) {\r\n var urlParams = {};\r\n urlParams[VERSION_PARAM] = PROTOCOL_VERSION;\r\n if (!isNodeSdk() &&\r\n typeof location !== 'undefined' &&\r\n location.href &&\r\n location.href.indexOf(FORGE_DOMAIN) !== -1) {\r\n urlParams[REFERER_PARAM] = FORGE_REF;\r\n }\r\n if (transportSessionId) {\r\n urlParams[TRANSPORT_SESSION_PARAM] = transportSessionId;\r\n }\r\n if (lastSessionId) {\r\n urlParams[LAST_SESSION_PARAM] = lastSessionId;\r\n }\r\n return repoInfo.connectionURL(WEBSOCKET, urlParams);\r\n };\r\n /**\r\n *\r\n * @param onMessage Callback when messages arrive\r\n * @param onDisconnect Callback with connection lost.\r\n */\r\n WebSocketConnection.prototype.open = function (onMessage, onDisconnect) {\r\n var _this = this;\r\n this.onDisconnect = onDisconnect;\r\n this.onMessage = onMessage;\r\n this.log_('Websocket connecting to ' + this.connURL);\r\n this.everConnected_ = false;\r\n // Assume failure until proven otherwise.\r\n PersistentStorage.set('previous_websocket_failure', true);\r\n try {\r\n if (isNodeSdk()) {\r\n var device = CONSTANTS.NODE_ADMIN ? 'AdminNode' : 'Node';\r\n // UA Format: Firebase////\r\n var options = {\r\n headers: {\r\n 'User-Agent': \"Firebase/\" + PROTOCOL_VERSION + \"/\" + firebase.SDK_VERSION + \"/\" + process.platform + \"/\" + device\r\n }\r\n };\r\n // Plumb appropriate http_proxy environment variable into faye-websocket if it exists.\r\n var env = process['env'];\r\n var proxy = this.connURL.indexOf('wss://') == 0\r\n ? env['HTTPS_PROXY'] || env['https_proxy']\r\n : env['HTTP_PROXY'] || env['http_proxy'];\r\n if (proxy) {\r\n options['proxy'] = { origin: proxy };\r\n }\r\n this.mySock = new WebSocketImpl(this.connURL, [], options);\r\n }\r\n else {\r\n this.mySock = new WebSocketImpl(this.connURL);\r\n }\r\n }\r\n catch (e) {\r\n this.log_('Error instantiating WebSocket.');\r\n var error = e.message || e.data;\r\n if (error) {\r\n this.log_(error);\r\n }\r\n this.onClosed_();\r\n return;\r\n }\r\n this.mySock.onopen = function () {\r\n _this.log_('Websocket connected.');\r\n _this.everConnected_ = true;\r\n };\r\n this.mySock.onclose = function () {\r\n _this.log_('Websocket connection was disconnected.');\r\n _this.mySock = null;\r\n _this.onClosed_();\r\n };\r\n this.mySock.onmessage = function (m) {\r\n _this.handleIncomingFrame(m);\r\n };\r\n this.mySock.onerror = function (e) {\r\n _this.log_('WebSocket error. Closing connection.');\r\n var error = e.message || e.data;\r\n if (error) {\r\n _this.log_(error);\r\n }\r\n _this.onClosed_();\r\n };\r\n };\r\n /**\r\n * No-op for websockets, we don't need to do anything once the connection is confirmed as open\r\n */\r\n WebSocketConnection.prototype.start = function () { };\r\n WebSocketConnection.forceDisallow = function () {\r\n WebSocketConnection.forceDisallow_ = true;\r\n };\r\n WebSocketConnection.isAvailable = function () {\r\n var isOldAndroid = false;\r\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\r\n var oldAndroidRegex = /Android ([0-9]{0,}\\.[0-9]{0,})/;\r\n var oldAndroidMatch = navigator.userAgent.match(oldAndroidRegex);\r\n if (oldAndroidMatch && oldAndroidMatch.length > 1) {\r\n if (parseFloat(oldAndroidMatch[1]) < 4.4) {\r\n isOldAndroid = true;\r\n }\r\n }\r\n }\r\n return (!isOldAndroid &&\r\n WebSocketImpl !== null &&\r\n !WebSocketConnection.forceDisallow_);\r\n };\r\n /**\r\n * Returns true if we previously failed to connect with this transport.\r\n * @return {boolean}\r\n */\r\n WebSocketConnection.previouslyFailed = function () {\r\n // If our persistent storage is actually only in-memory storage,\r\n // we default to assuming that it previously failed to be safe.\r\n return (PersistentStorage.isInMemoryStorage ||\r\n PersistentStorage.get('previous_websocket_failure') === true);\r\n };\r\n WebSocketConnection.prototype.markConnectionHealthy = function () {\r\n PersistentStorage.remove('previous_websocket_failure');\r\n };\r\n WebSocketConnection.prototype.appendFrame_ = function (data) {\r\n this.frames.push(data);\r\n if (this.frames.length == this.totalFrames) {\r\n var fullMess = this.frames.join('');\r\n this.frames = null;\r\n var jsonMess = jsonEval(fullMess);\r\n //handle the message\r\n this.onMessage(jsonMess);\r\n }\r\n };\r\n /**\r\n * @param {number} frameCount The number of frames we are expecting from the server\r\n * @private\r\n */\r\n WebSocketConnection.prototype.handleNewFrameCount_ = function (frameCount) {\r\n this.totalFrames = frameCount;\r\n this.frames = [];\r\n };\r\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 */\r\n WebSocketConnection.prototype.extractFrameCount_ = function (data) {\r\n assert(this.frames === null, 'We already have a frame buffer');\r\n // TODO: The server is only supposed to send up to 9999 frames (i.e. length <= 4), but that isn't being enforced\r\n // currently. So allowing larger frame counts (length <= 6). See https://app.asana.com/0/search/8688598998380/8237608042508\r\n if (data.length <= 6) {\r\n var frameCount = Number(data);\r\n if (!isNaN(frameCount)) {\r\n this.handleNewFrameCount_(frameCount);\r\n return null;\r\n }\r\n }\r\n this.handleNewFrameCount_(1);\r\n return data;\r\n };\r\n /**\r\n * Process a websocket frame that has arrived from the server.\r\n * @param mess The frame data\r\n */\r\n WebSocketConnection.prototype.handleIncomingFrame = function (mess) {\r\n if (this.mySock === null)\r\n return; // Chrome apparently delivers incoming packets even after we .close() the connection sometimes.\r\n var data = mess['data'];\r\n this.bytesReceived += data.length;\r\n this.stats_.incrementCounter('bytes_received', data.length);\r\n this.resetKeepAlive();\r\n if (this.frames !== null) {\r\n // we're buffering\r\n this.appendFrame_(data);\r\n }\r\n else {\r\n // try to parse out a frame count, otherwise, assume 1 and process it\r\n var remainingData = this.extractFrameCount_(data);\r\n if (remainingData !== null) {\r\n this.appendFrame_(remainingData);\r\n }\r\n }\r\n };\r\n /**\r\n * Send a message to the server\r\n * @param {Object} data The JSON object to transmit\r\n */\r\n WebSocketConnection.prototype.send = function (data) {\r\n this.resetKeepAlive();\r\n var dataStr = stringify(data);\r\n this.bytesSent += dataStr.length;\r\n this.stats_.incrementCounter('bytes_sent', dataStr.length);\r\n //We can only fit a certain amount in each websocket frame, so we need to split this request\r\n //up into multiple pieces if it doesn't fit in one request.\r\n var dataSegs = splitStringBySize(dataStr, WEBSOCKET_MAX_FRAME_SIZE);\r\n //Send the length header\r\n if (dataSegs.length > 1) {\r\n this.sendString_(String(dataSegs.length));\r\n }\r\n //Send the actual data in segments.\r\n for (var i = 0; i < dataSegs.length; i++) {\r\n this.sendString_(dataSegs[i]);\r\n }\r\n };\r\n WebSocketConnection.prototype.shutdown_ = function () {\r\n this.isClosed_ = true;\r\n if (this.keepaliveTimer) {\r\n clearInterval(this.keepaliveTimer);\r\n this.keepaliveTimer = null;\r\n }\r\n if (this.mySock) {\r\n this.mySock.close();\r\n this.mySock = null;\r\n }\r\n };\r\n WebSocketConnection.prototype.onClosed_ = function () {\r\n if (!this.isClosed_) {\r\n this.log_('WebSocket is closing itself');\r\n this.shutdown_();\r\n // since this is an internal close, trigger the close listener\r\n if (this.onDisconnect) {\r\n this.onDisconnect(this.everConnected_);\r\n this.onDisconnect = null;\r\n }\r\n }\r\n };\r\n /**\r\n * External-facing close handler.\r\n * Close the websocket and kill the connection.\r\n */\r\n WebSocketConnection.prototype.close = function () {\r\n if (!this.isClosed_) {\r\n this.log_('WebSocket is being closed');\r\n this.shutdown_();\r\n }\r\n };\r\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 */\r\n WebSocketConnection.prototype.resetKeepAlive = function () {\r\n var _this = this;\r\n clearInterval(this.keepaliveTimer);\r\n this.keepaliveTimer = setInterval(function () {\r\n //If there has been no websocket activity for a while, send a no-op\r\n if (_this.mySock) {\r\n _this.sendString_('0');\r\n }\r\n _this.resetKeepAlive();\r\n }, Math.floor(WEBSOCKET_KEEPALIVE_INTERVAL));\r\n };\r\n /**\r\n * Send a string over the websocket.\r\n *\r\n * @param {string} str String to send.\r\n * @private\r\n */\r\n WebSocketConnection.prototype.sendString_ = function (str) {\r\n // Firefox seems to sometimes throw exceptions (NS_ERROR_UNEXPECTED) from websocket .send()\r\n // calls for some unknown reason. We treat these as an error and disconnect.\r\n // See https://app.asana.com/0/58926111402292/68021340250410\r\n try {\r\n this.mySock.send(str);\r\n }\r\n catch (e) {\r\n this.log_('Exception thrown from WebSocket.send():', e.message || e.data, 'Closing connection.');\r\n setTimeout(this.onClosed_.bind(this), 0);\r\n }\r\n };\r\n /**\r\n * Number of response before we consider the connection \"healthy.\"\r\n * @type {number}\r\n */\r\n WebSocketConnection.responsesRequiredToBeHealthy = 2;\r\n /**\r\n * Time to wait for the connection te become healthy before giving up.\r\n * @type {number}\r\n */\r\n WebSocketConnection.healthyTimeout = 30000;\r\n return WebSocketConnection;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar TransportManager = /** @class */ (function () {\r\n /**\r\n * @param {!RepoInfo} repoInfo Metadata around the namespace we're connecting to\r\n */\r\n function TransportManager(repoInfo) {\r\n this.initTransports_(repoInfo);\r\n }\r\n Object.defineProperty(TransportManager, \"ALL_TRANSPORTS\", {\r\n /**\r\n * @const\r\n * @type {!Array.}\r\n */\r\n get: function () {\r\n return [BrowserPollConnection, WebSocketConnection];\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {!RepoInfo} repoInfo\r\n * @private\r\n */\r\n TransportManager.prototype.initTransports_ = function (repoInfo) {\r\n var isWebSocketsAvailable = WebSocketConnection && WebSocketConnection['isAvailable']();\r\n var isSkipPollConnection = isWebSocketsAvailable && !WebSocketConnection.previouslyFailed();\r\n if (repoInfo.webSocketOnly) {\r\n if (!isWebSocketsAvailable)\r\n warn(\"wss:// URL used, but browser isn't known to support websockets. Trying anyway.\");\r\n isSkipPollConnection = true;\r\n }\r\n if (isSkipPollConnection) {\r\n this.transports_ = [WebSocketConnection];\r\n }\r\n else {\r\n var transports_1 = (this.transports_ = []);\r\n each(TransportManager.ALL_TRANSPORTS, function (i, transport) {\r\n if (transport && transport['isAvailable']()) {\r\n transports_1.push(transport);\r\n }\r\n });\r\n }\r\n };\r\n /**\r\n * @return {function(new:Transport, !string, !RepoInfo, string=, string=)} The constructor for the\r\n * initial transport to use\r\n */\r\n TransportManager.prototype.initialTransport = function () {\r\n if (this.transports_.length > 0) {\r\n return this.transports_[0];\r\n }\r\n else {\r\n throw new Error('No transports available');\r\n }\r\n };\r\n /**\r\n * @return {?function(new:Transport, function(),function(), string=)} The constructor for the next\r\n * transport, or null\r\n */\r\n TransportManager.prototype.upgradeTransport = function () {\r\n if (this.transports_.length > 1) {\r\n return this.transports_[1];\r\n }\r\n else {\r\n return null;\r\n }\r\n };\r\n return TransportManager;\r\n}());\n\n/**\r\n * @license\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 */\r\n// Abort upgrade attempt if it takes longer than 60s.\r\nvar UPGRADE_TIMEOUT = 60000;\r\n// For some transports (WebSockets), we need to \"validate\" the transport by exchanging a few requests and responses.\r\n// If we haven't sent enough requests within 5s, we'll start sending noop ping requests.\r\nvar DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5000;\r\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)\r\n// then we may not be able to exchange our ping/pong requests within the healthy timeout. So if we reach the timeout\r\n// but we've sent/received enough bytes, we don't cancel the connection.\r\nvar BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024;\r\nvar BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024;\r\nvar MESSAGE_TYPE = 't';\r\nvar MESSAGE_DATA = 'd';\r\nvar CONTROL_SHUTDOWN = 's';\r\nvar CONTROL_RESET = 'r';\r\nvar CONTROL_ERROR = 'e';\r\nvar CONTROL_PONG = 'o';\r\nvar SWITCH_ACK = 'a';\r\nvar END_TRANSMISSION = 'n';\r\nvar PING = 'p';\r\nvar SERVER_HELLO = 'h';\r\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 */\r\nvar Connection = /** @class */ (function () {\r\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 */\r\n function Connection(id, repoInfo_, onMessage_, onReady_, onDisconnect_, onKill_, lastSessionId) {\r\n this.id = id;\r\n this.repoInfo_ = repoInfo_;\r\n this.onMessage_ = onMessage_;\r\n this.onReady_ = onReady_;\r\n this.onDisconnect_ = onDisconnect_;\r\n this.onKill_ = onKill_;\r\n this.lastSessionId = lastSessionId;\r\n this.connectionCount = 0;\r\n this.pendingDataMessages = [];\r\n this.state_ = 0 /* CONNECTING */;\r\n this.log_ = logWrapper('c:' + this.id + ':');\r\n this.transportManager_ = new TransportManager(repoInfo_);\r\n this.log_('Connection created');\r\n this.start_();\r\n }\r\n /**\r\n * Starts a connection attempt\r\n * @private\r\n */\r\n Connection.prototype.start_ = function () {\r\n var _this = this;\r\n var conn = this.transportManager_.initialTransport();\r\n this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_, undefined, this.lastSessionId);\r\n // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\r\n // can consider the transport healthy.\r\n this.primaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0;\r\n var onMessageReceived = this.connReceiver_(this.conn_);\r\n var onConnectionLost = this.disconnReceiver_(this.conn_);\r\n this.tx_ = this.conn_;\r\n this.rx_ = this.conn_;\r\n this.secondaryConn_ = null;\r\n this.isHealthy_ = false;\r\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 */\r\n setTimeout(function () {\r\n // this.conn_ gets set to null in some of the tests. Check to make sure it still exists before using it\r\n _this.conn_ && _this.conn_.open(onMessageReceived, onConnectionLost);\r\n }, Math.floor(0));\r\n var healthyTimeout_ms = conn['healthyTimeout'] || 0;\r\n if (healthyTimeout_ms > 0) {\r\n this.healthyTimeout_ = setTimeoutNonBlocking(function () {\r\n _this.healthyTimeout_ = null;\r\n if (!_this.isHealthy_) {\r\n if (_this.conn_ &&\r\n _this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE) {\r\n _this.log_('Connection exceeded healthy timeout but has received ' +\r\n _this.conn_.bytesReceived +\r\n ' bytes. Marking connection healthy.');\r\n _this.isHealthy_ = true;\r\n _this.conn_.markConnectionHealthy();\r\n }\r\n else if (_this.conn_ &&\r\n _this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE) {\r\n _this.log_('Connection exceeded healthy timeout but has sent ' +\r\n _this.conn_.bytesSent +\r\n ' bytes. Leaving connection alive.');\r\n // NOTE: We don't want to mark it healthy, since we have no guarantee that the bytes have made it to\r\n // the server.\r\n }\r\n else {\r\n _this.log_('Closing unhealthy connection after timeout.');\r\n _this.close();\r\n }\r\n }\r\n }, Math.floor(healthyTimeout_ms));\r\n }\r\n };\r\n /**\r\n * @return {!string}\r\n * @private\r\n */\r\n Connection.prototype.nextTransportId_ = function () {\r\n return 'c:' + this.id + ':' + this.connectionCount++;\r\n };\r\n Connection.prototype.disconnReceiver_ = function (conn) {\r\n var _this = this;\r\n return function (everConnected) {\r\n if (conn === _this.conn_) {\r\n _this.onConnectionLost_(everConnected);\r\n }\r\n else if (conn === _this.secondaryConn_) {\r\n _this.log_('Secondary connection lost.');\r\n _this.onSecondaryConnectionLost_();\r\n }\r\n else {\r\n _this.log_('closing an old connection');\r\n }\r\n };\r\n };\r\n Connection.prototype.connReceiver_ = function (conn) {\r\n var _this = this;\r\n return function (message) {\r\n if (_this.state_ != 2 /* DISCONNECTED */) {\r\n if (conn === _this.rx_) {\r\n _this.onPrimaryMessageReceived_(message);\r\n }\r\n else if (conn === _this.secondaryConn_) {\r\n _this.onSecondaryMessageReceived_(message);\r\n }\r\n else {\r\n _this.log_('message on old connection');\r\n }\r\n }\r\n };\r\n };\r\n /**\r\n *\r\n * @param {Object} dataMsg An arbitrary data message to be sent to the server\r\n */\r\n Connection.prototype.sendRequest = function (dataMsg) {\r\n // wrap in a data message envelope and send it on\r\n var msg = { t: 'd', d: dataMsg };\r\n this.sendData_(msg);\r\n };\r\n Connection.prototype.tryCleanupConnection = function () {\r\n if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) {\r\n this.log_('cleaning up and promoting a connection: ' + this.secondaryConn_.connId);\r\n this.conn_ = this.secondaryConn_;\r\n this.secondaryConn_ = null;\r\n // the server will shutdown the old connection\r\n }\r\n };\r\n Connection.prototype.onSecondaryControl_ = function (controlData) {\r\n if (MESSAGE_TYPE in controlData) {\r\n var cmd = controlData[MESSAGE_TYPE];\r\n if (cmd === SWITCH_ACK) {\r\n this.upgradeIfSecondaryHealthy_();\r\n }\r\n else if (cmd === CONTROL_RESET) {\r\n // Most likely the session wasn't valid. Abandon the switch attempt\r\n this.log_('Got a reset on secondary, closing it');\r\n this.secondaryConn_.close();\r\n // If we were already using this connection for something, than we need to fully close\r\n if (this.tx_ === this.secondaryConn_ ||\r\n this.rx_ === this.secondaryConn_) {\r\n this.close();\r\n }\r\n }\r\n else if (cmd === CONTROL_PONG) {\r\n this.log_('got pong on secondary.');\r\n this.secondaryResponsesRequired_--;\r\n this.upgradeIfSecondaryHealthy_();\r\n }\r\n }\r\n };\r\n Connection.prototype.onSecondaryMessageReceived_ = function (parsedData) {\r\n var layer = requireKey('t', parsedData);\r\n var data = requireKey('d', parsedData);\r\n if (layer == 'c') {\r\n this.onSecondaryControl_(data);\r\n }\r\n else if (layer == 'd') {\r\n // got a data message, but we're still second connection. Need to buffer it up\r\n this.pendingDataMessages.push(data);\r\n }\r\n else {\r\n throw new Error('Unknown protocol layer: ' + layer);\r\n }\r\n };\r\n Connection.prototype.upgradeIfSecondaryHealthy_ = function () {\r\n if (this.secondaryResponsesRequired_ <= 0) {\r\n this.log_('Secondary connection is healthy.');\r\n this.isHealthy_ = true;\r\n this.secondaryConn_.markConnectionHealthy();\r\n this.proceedWithUpgrade_();\r\n }\r\n else {\r\n // Send a ping to make sure the connection is healthy.\r\n this.log_('sending ping on secondary.');\r\n this.secondaryConn_.send({ t: 'c', d: { t: PING, d: {} } });\r\n }\r\n };\r\n Connection.prototype.proceedWithUpgrade_ = function () {\r\n // tell this connection to consider itself open\r\n this.secondaryConn_.start();\r\n // send ack\r\n this.log_('sending client ack on secondary');\r\n this.secondaryConn_.send({ t: 'c', d: { t: SWITCH_ACK, d: {} } });\r\n // send end packet on primary transport, switch to sending on this one\r\n // can receive on this one, buffer responses until end received on primary transport\r\n this.log_('Ending transmission on primary');\r\n this.conn_.send({ t: 'c', d: { t: END_TRANSMISSION, d: {} } });\r\n this.tx_ = this.secondaryConn_;\r\n this.tryCleanupConnection();\r\n };\r\n Connection.prototype.onPrimaryMessageReceived_ = function (parsedData) {\r\n // Must refer to parsedData properties in quotes, so closure doesn't touch them.\r\n var layer = requireKey('t', parsedData);\r\n var data = requireKey('d', parsedData);\r\n if (layer == 'c') {\r\n this.onControl_(data);\r\n }\r\n else if (layer == 'd') {\r\n this.onDataMessage_(data);\r\n }\r\n };\r\n Connection.prototype.onDataMessage_ = function (message) {\r\n this.onPrimaryResponse_();\r\n // We don't do anything with data messages, just kick them up a level\r\n this.onMessage_(message);\r\n };\r\n Connection.prototype.onPrimaryResponse_ = function () {\r\n if (!this.isHealthy_) {\r\n this.primaryResponsesRequired_--;\r\n if (this.primaryResponsesRequired_ <= 0) {\r\n this.log_('Primary connection is healthy.');\r\n this.isHealthy_ = true;\r\n this.conn_.markConnectionHealthy();\r\n }\r\n }\r\n };\r\n Connection.prototype.onControl_ = function (controlData) {\r\n var cmd = requireKey(MESSAGE_TYPE, controlData);\r\n if (MESSAGE_DATA in controlData) {\r\n var payload = controlData[MESSAGE_DATA];\r\n if (cmd === SERVER_HELLO) {\r\n this.onHandshake_(payload);\r\n }\r\n else if (cmd === END_TRANSMISSION) {\r\n this.log_('recvd end transmission on primary');\r\n this.rx_ = this.secondaryConn_;\r\n for (var i = 0; i < this.pendingDataMessages.length; ++i) {\r\n this.onDataMessage_(this.pendingDataMessages[i]);\r\n }\r\n this.pendingDataMessages = [];\r\n this.tryCleanupConnection();\r\n }\r\n else if (cmd === CONTROL_SHUTDOWN) {\r\n // This was previously the 'onKill' callback passed to the lower-level connection\r\n // payload in this case is the reason for the shutdown. Generally a human-readable error\r\n this.onConnectionShutdown_(payload);\r\n }\r\n else if (cmd === CONTROL_RESET) {\r\n // payload in this case is the host we should contact\r\n this.onReset_(payload);\r\n }\r\n else if (cmd === CONTROL_ERROR) {\r\n error('Server Error: ' + payload);\r\n }\r\n else if (cmd === CONTROL_PONG) {\r\n this.log_('got pong on primary.');\r\n this.onPrimaryResponse_();\r\n this.sendPingOnPrimaryIfNecessary_();\r\n }\r\n else {\r\n error('Unknown control packet command: ' + cmd);\r\n }\r\n }\r\n };\r\n /**\r\n *\r\n * @param {Object} handshake The handshake data returned from the server\r\n * @private\r\n */\r\n Connection.prototype.onHandshake_ = function (handshake) {\r\n var timestamp = handshake.ts;\r\n var version = handshake.v;\r\n var host = handshake.h;\r\n this.sessionId = handshake.s;\r\n this.repoInfo_.updateHost(host);\r\n // if we've already closed the connection, then don't bother trying to progress further\r\n if (this.state_ == 0 /* CONNECTING */) {\r\n this.conn_.start();\r\n this.onConnectionEstablished_(this.conn_, timestamp);\r\n if (PROTOCOL_VERSION !== version) {\r\n warn('Protocol version mismatch detected');\r\n }\r\n // TODO: do we want to upgrade? when? maybe a delay?\r\n this.tryStartUpgrade_();\r\n }\r\n };\r\n Connection.prototype.tryStartUpgrade_ = function () {\r\n var conn = this.transportManager_.upgradeTransport();\r\n if (conn) {\r\n this.startUpgrade_(conn);\r\n }\r\n };\r\n Connection.prototype.startUpgrade_ = function (conn) {\r\n var _this = this;\r\n this.secondaryConn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.sessionId);\r\n // For certain transports (WebSockets), we need to send and receive several messages back and forth before we\r\n // can consider the transport healthy.\r\n this.secondaryResponsesRequired_ =\r\n conn['responsesRequiredToBeHealthy'] || 0;\r\n var onMessage = this.connReceiver_(this.secondaryConn_);\r\n var onDisconnect = this.disconnReceiver_(this.secondaryConn_);\r\n this.secondaryConn_.open(onMessage, onDisconnect);\r\n // If we haven't successfully upgraded after UPGRADE_TIMEOUT, give up and kill the secondary.\r\n setTimeoutNonBlocking(function () {\r\n if (_this.secondaryConn_) {\r\n _this.log_('Timed out trying to upgrade.');\r\n _this.secondaryConn_.close();\r\n }\r\n }, Math.floor(UPGRADE_TIMEOUT));\r\n };\r\n Connection.prototype.onReset_ = function (host) {\r\n this.log_('Reset packet received. New host: ' + host);\r\n this.repoInfo_.updateHost(host);\r\n // TODO: if we're already \"connected\", we need to trigger a disconnect at the next layer up.\r\n // We don't currently support resets after the connection has already been established\r\n if (this.state_ === 1 /* CONNECTED */) {\r\n this.close();\r\n }\r\n else {\r\n // Close whatever connections we have open and start again.\r\n this.closeConnections_();\r\n this.start_();\r\n }\r\n };\r\n Connection.prototype.onConnectionEstablished_ = function (conn, timestamp) {\r\n var _this = this;\r\n this.log_('Realtime connection established.');\r\n this.conn_ = conn;\r\n this.state_ = 1 /* CONNECTED */;\r\n if (this.onReady_) {\r\n this.onReady_(timestamp, this.sessionId);\r\n this.onReady_ = null;\r\n }\r\n // If after 5 seconds we haven't sent enough requests to the server to get the connection healthy,\r\n // send some pings.\r\n if (this.primaryResponsesRequired_ === 0) {\r\n this.log_('Primary connection is healthy.');\r\n this.isHealthy_ = true;\r\n }\r\n else {\r\n setTimeoutNonBlocking(function () {\r\n _this.sendPingOnPrimaryIfNecessary_();\r\n }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS));\r\n }\r\n };\r\n Connection.prototype.sendPingOnPrimaryIfNecessary_ = function () {\r\n // If the connection isn't considered healthy yet, we'll send a noop ping packet request.\r\n if (!this.isHealthy_ && this.state_ === 1 /* CONNECTED */) {\r\n this.log_('sending ping on primary.');\r\n this.sendData_({ t: 'c', d: { t: PING, d: {} } });\r\n }\r\n };\r\n Connection.prototype.onSecondaryConnectionLost_ = function () {\r\n var conn = this.secondaryConn_;\r\n this.secondaryConn_ = null;\r\n if (this.tx_ === conn || this.rx_ === conn) {\r\n // we are relying on this connection already in some capacity. Therefore, a failure is real\r\n this.close();\r\n }\r\n };\r\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 */\r\n Connection.prototype.onConnectionLost_ = function (everConnected) {\r\n this.conn_ = null;\r\n // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting\r\n // called on window close and RealtimeState.CONNECTING is no longer defined. Just a guess.\r\n if (!everConnected && this.state_ === 0 /* CONNECTING */) {\r\n this.log_('Realtime connection failed.');\r\n // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away\r\n if (this.repoInfo_.isCacheableHost()) {\r\n PersistentStorage.remove('host:' + this.repoInfo_.host);\r\n // reset the internal host to what we would show the user, i.e. .firebaseio.com\r\n this.repoInfo_.internalHost = this.repoInfo_.host;\r\n }\r\n }\r\n else if (this.state_ === 1 /* CONNECTED */) {\r\n this.log_('Realtime connection lost.');\r\n }\r\n this.close();\r\n };\r\n /**\r\n *\r\n * @param {string} reason\r\n * @private\r\n */\r\n Connection.prototype.onConnectionShutdown_ = function (reason) {\r\n this.log_('Connection shutdown command received. Shutting down...');\r\n if (this.onKill_) {\r\n this.onKill_(reason);\r\n this.onKill_ = null;\r\n }\r\n // We intentionally don't want to fire onDisconnect (kill is a different case),\r\n // so clear the callback.\r\n this.onDisconnect_ = null;\r\n this.close();\r\n };\r\n Connection.prototype.sendData_ = function (data) {\r\n if (this.state_ !== 1 /* CONNECTED */) {\r\n throw 'Connection is not connected';\r\n }\r\n else {\r\n this.tx_.send(data);\r\n }\r\n };\r\n /**\r\n * Cleans up this connection, calling the appropriate callbacks\r\n */\r\n Connection.prototype.close = function () {\r\n if (this.state_ !== 2 /* DISCONNECTED */) {\r\n this.log_('Closing realtime connection.');\r\n this.state_ = 2 /* DISCONNECTED */;\r\n this.closeConnections_();\r\n if (this.onDisconnect_) {\r\n this.onDisconnect_();\r\n this.onDisconnect_ = null;\r\n }\r\n }\r\n };\r\n /**\r\n *\r\n * @private\r\n */\r\n Connection.prototype.closeConnections_ = function () {\r\n this.log_('Shutting down all connections');\r\n if (this.conn_) {\r\n this.conn_.close();\r\n this.conn_ = null;\r\n }\r\n if (this.secondaryConn_) {\r\n this.secondaryConn_.close();\r\n this.secondaryConn_ = null;\r\n }\r\n if (this.healthyTimeout_) {\r\n clearTimeout(this.healthyTimeout_);\r\n this.healthyTimeout_ = null;\r\n }\r\n };\r\n return Connection;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar ServerActions = /** @class */ (function () {\r\n function ServerActions() {\r\n }\r\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, string)=} onComplete\r\n * @param {string=} hash\r\n */\r\n ServerActions.prototype.put = function (pathString, data, onComplete, hash) { };\r\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, ?string)} onComplete\r\n * @param {string=} hash\r\n */\r\n ServerActions.prototype.merge = function (pathString, data, onComplete, hash) { };\r\n /**\r\n * Refreshes the auth token for the current connection.\r\n * @param {string} token The authentication token\r\n */\r\n ServerActions.prototype.refreshAuthToken = function (token) { };\r\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, string)=} onComplete\r\n */\r\n ServerActions.prototype.onDisconnectPut = function (pathString, data, onComplete) { };\r\n /**\r\n * @param {string} pathString\r\n * @param {*} data\r\n * @param {function(string, string)=} onComplete\r\n */\r\n ServerActions.prototype.onDisconnectMerge = function (pathString, data, onComplete) { };\r\n /**\r\n * @param {string} pathString\r\n * @param {function(string, string)=} onComplete\r\n */\r\n ServerActions.prototype.onDisconnectCancel = function (pathString, onComplete) { };\r\n /**\r\n * @param {Object.} stats\r\n */\r\n ServerActions.prototype.reportStats = function (stats) { };\r\n return ServerActions;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar RECONNECT_MIN_DELAY = 1000;\r\nvar RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1000; // 5 minutes in milliseconds (Case: 1858)\r\nvar RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1000; // 30 seconds for admin clients (likely to be a backend server)\r\nvar RECONNECT_DELAY_MULTIPLIER = 1.3;\r\nvar RECONNECT_DELAY_RESET_TIMEOUT = 30000; // Reset delay back to MIN_DELAY after being connected for 30sec.\r\nvar SERVER_KILL_INTERRUPT_REASON = 'server_kill';\r\n// If auth fails repeatedly, we'll assume something is wrong and log a warning / back off.\r\nvar INVALID_AUTH_TOKEN_THRESHOLD = 3;\r\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 */\r\nvar PersistentConnection = /** @class */ (function (_super) {\r\n __extends(PersistentConnection, _super);\r\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 */\r\n function PersistentConnection(repoInfo_, onDataUpdate_, onConnectStatus_, onServerInfoUpdate_, authTokenProvider_, authOverride_) {\r\n var _this = _super.call(this) || this;\r\n _this.repoInfo_ = repoInfo_;\r\n _this.onDataUpdate_ = onDataUpdate_;\r\n _this.onConnectStatus_ = onConnectStatus_;\r\n _this.onServerInfoUpdate_ = onServerInfoUpdate_;\r\n _this.authTokenProvider_ = authTokenProvider_;\r\n _this.authOverride_ = authOverride_;\r\n // Used for diagnostic logging.\r\n _this.id = PersistentConnection.nextPersistentConnectionId_++;\r\n _this.log_ = logWrapper('p:' + _this.id + ':');\r\n /** @private {Object} */\r\n _this.interruptReasons_ = {};\r\n _this.listens_ = {};\r\n _this.outstandingPuts_ = [];\r\n _this.outstandingPutCount_ = 0;\r\n _this.onDisconnectRequestQueue_ = [];\r\n _this.connected_ = false;\r\n _this.reconnectDelay_ = RECONNECT_MIN_DELAY;\r\n _this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT;\r\n _this.securityDebugCallback_ = null;\r\n _this.lastSessionId = null;\r\n /** @private {number|null} */\r\n _this.establishConnectionTimer_ = null;\r\n /** @private {boolean} */\r\n _this.visible_ = false;\r\n // Before we get connected, we keep a queue of pending messages to send.\r\n _this.requestCBHash_ = {};\r\n _this.requestNumber_ = 0;\r\n /** @private {?{\r\n * sendRequest(Object),\r\n * close()\r\n * }} */\r\n _this.realtime_ = null;\r\n /** @private {string|null} */\r\n _this.authToken_ = null;\r\n _this.forceTokenRefresh_ = false;\r\n _this.invalidAuthTokenCount_ = 0;\r\n _this.firstConnection_ = true;\r\n _this.lastConnectionAttemptTime_ = null;\r\n _this.lastConnectionEstablishedTime_ = null;\r\n if (authOverride_ && !isNodeSdk()) {\r\n throw new Error('Auth override specified in options, but not supported on non Node.js platforms');\r\n }\r\n _this.scheduleConnect_(0);\r\n VisibilityMonitor.getInstance().on('visible', _this.onVisible_, _this);\r\n if (repoInfo_.host.indexOf('fblocal') === -1) {\r\n OnlineMonitor.getInstance().on('online', _this.onOnline_, _this);\r\n }\r\n return _this;\r\n }\r\n /**\r\n * @param {!string} action\r\n * @param {*} body\r\n * @param {function(*)=} onResponse\r\n * @protected\r\n */\r\n PersistentConnection.prototype.sendRequest = function (action, body, onResponse) {\r\n var curReqNum = ++this.requestNumber_;\r\n var msg = { r: curReqNum, a: action, b: body };\r\n this.log_(stringify(msg));\r\n assert(this.connected_, \"sendRequest call when we're not connected not allowed.\");\r\n this.realtime_.sendRequest(msg);\r\n if (onResponse) {\r\n this.requestCBHash_[curReqNum] = onResponse;\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.listen = function (query, currentHashFn, tag, onComplete) {\r\n var queryId = query.queryIdentifier();\r\n var pathString = query.path.toString();\r\n this.log_('Listen called for ' + pathString + ' ' + queryId);\r\n this.listens_[pathString] = this.listens_[pathString] || {};\r\n assert(query.getQueryParams().isDefault() ||\r\n !query.getQueryParams().loadsAllData(), 'listen() called for non-default but complete query');\r\n assert(!this.listens_[pathString][queryId], 'listen() called twice for same path/queryId.');\r\n var listenSpec = {\r\n onComplete: onComplete,\r\n hashFn: currentHashFn,\r\n query: query,\r\n tag: tag\r\n };\r\n this.listens_[pathString][queryId] = listenSpec;\r\n if (this.connected_) {\r\n this.sendListen_(listenSpec);\r\n }\r\n };\r\n /**\r\n * @param {!{onComplete(),\r\n * hashFn():!string,\r\n * query: !Query,\r\n * tag: ?number}} listenSpec\r\n * @private\r\n */\r\n PersistentConnection.prototype.sendListen_ = function (listenSpec) {\r\n var _this = this;\r\n var query = listenSpec.query;\r\n var pathString = query.path.toString();\r\n var queryId = query.queryIdentifier();\r\n this.log_('Listen on ' + pathString + ' for ' + queryId);\r\n var req = { /*path*/ p: pathString };\r\n var action = 'q';\r\n // Only bother to send query if it's non-default.\r\n if (listenSpec.tag) {\r\n req['q'] = query.queryObject();\r\n req['t'] = listenSpec.tag;\r\n }\r\n req[ /*hash*/'h'] = listenSpec.hashFn();\r\n this.sendRequest(action, req, function (message) {\r\n var payload = message[ /*data*/'d'];\r\n var status = message[ /*status*/'s'];\r\n // print warnings in any case...\r\n PersistentConnection.warnOnListenWarnings_(payload, query);\r\n var currentListenSpec = _this.listens_[pathString] && _this.listens_[pathString][queryId];\r\n // only trigger actions if the listen hasn't been removed and readded\r\n if (currentListenSpec === listenSpec) {\r\n _this.log_('listen response', message);\r\n if (status !== 'ok') {\r\n _this.removeListen_(pathString, queryId);\r\n }\r\n if (listenSpec.onComplete) {\r\n listenSpec.onComplete(status, payload);\r\n }\r\n }\r\n });\r\n };\r\n /**\r\n * @param {*} payload\r\n * @param {!Query} query\r\n * @private\r\n */\r\n PersistentConnection.warnOnListenWarnings_ = function (payload, query) {\r\n if (payload && typeof payload === 'object' && contains(payload, 'w')) {\r\n var warnings = safeGet(payload, 'w');\r\n if (Array.isArray(warnings) && ~warnings.indexOf('no_index')) {\r\n var indexSpec = '\".indexOn\": \"' +\r\n query\r\n .getQueryParams()\r\n .getIndex()\r\n .toString() +\r\n '\"';\r\n var indexPath = query.path.toString();\r\n warn(\"Using an unspecified index. Your data will be downloaded and \" +\r\n (\"filtered on the client. Consider adding \" + indexSpec + \" at \") +\r\n (indexPath + \" to your security rules for better performance.\"));\r\n }\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.refreshAuthToken = function (token) {\r\n this.authToken_ = token;\r\n this.log_('Auth token refreshed');\r\n if (this.authToken_) {\r\n this.tryAuth();\r\n }\r\n else {\r\n //If we're connected we want to let the server know to unauthenticate us. If we're not connected, simply delete\r\n //the credential so we dont become authenticated next time we connect.\r\n if (this.connected_) {\r\n this.sendRequest('unauth', {}, function () { });\r\n }\r\n }\r\n this.reduceReconnectDelayIfAdminCredential_(token);\r\n };\r\n /**\r\n * @param {!string} credential\r\n * @private\r\n */\r\n PersistentConnection.prototype.reduceReconnectDelayIfAdminCredential_ = function (credential) {\r\n // NOTE: This isn't intended to be bulletproof (a malicious developer can always just modify the client).\r\n // Additionally, we don't bother resetting the max delay back to the default if auth fails / expires.\r\n var isFirebaseSecret = credential && credential.length === 40;\r\n if (isFirebaseSecret || isAdmin(credential)) {\r\n this.log_('Admin auth credential detected. Reducing max reconnect time.');\r\n this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\r\n }\r\n };\r\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 */\r\n PersistentConnection.prototype.tryAuth = function () {\r\n var _this = this;\r\n if (this.connected_ && this.authToken_) {\r\n var token_1 = this.authToken_;\r\n var authMethod = isValidFormat(token_1) ? 'auth' : 'gauth';\r\n var requestData = { cred: token_1 };\r\n if (this.authOverride_ === null) {\r\n requestData['noauth'] = true;\r\n }\r\n else if (typeof this.authOverride_ === 'object') {\r\n requestData['authvar'] = this.authOverride_;\r\n }\r\n this.sendRequest(authMethod, requestData, function (res) {\r\n var status = res[ /*status*/'s'];\r\n var data = res[ /*data*/'d'] || 'error';\r\n if (_this.authToken_ === token_1) {\r\n if (status === 'ok') {\r\n _this.invalidAuthTokenCount_ = 0;\r\n }\r\n else {\r\n // Triggers reconnect and force refresh for auth token\r\n _this.onAuthRevoked_(status, data);\r\n }\r\n }\r\n });\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.unlisten = function (query, tag) {\r\n var pathString = query.path.toString();\r\n var queryId = query.queryIdentifier();\r\n this.log_('Unlisten called for ' + pathString + ' ' + queryId);\r\n assert(query.getQueryParams().isDefault() ||\r\n !query.getQueryParams().loadsAllData(), 'unlisten() called for non-default but complete query');\r\n var listen = this.removeListen_(pathString, queryId);\r\n if (listen && this.connected_) {\r\n this.sendUnlisten_(pathString, queryId, query.queryObject(), tag);\r\n }\r\n };\r\n PersistentConnection.prototype.sendUnlisten_ = function (pathString, queryId, queryObj, tag) {\r\n this.log_('Unlisten on ' + pathString + ' for ' + queryId);\r\n var req = { /*path*/ p: pathString };\r\n var action = 'n';\r\n // Only bother sending queryId if it's non-default.\r\n if (tag) {\r\n req['q'] = queryObj;\r\n req['t'] = tag;\r\n }\r\n this.sendRequest(action, req);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.onDisconnectPut = function (pathString, data, onComplete) {\r\n if (this.connected_) {\r\n this.sendOnDisconnect_('o', pathString, data, onComplete);\r\n }\r\n else {\r\n this.onDisconnectRequestQueue_.push({\r\n pathString: pathString,\r\n action: 'o',\r\n data: data,\r\n onComplete: onComplete\r\n });\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.onDisconnectMerge = function (pathString, data, onComplete) {\r\n if (this.connected_) {\r\n this.sendOnDisconnect_('om', pathString, data, onComplete);\r\n }\r\n else {\r\n this.onDisconnectRequestQueue_.push({\r\n pathString: pathString,\r\n action: 'om',\r\n data: data,\r\n onComplete: onComplete\r\n });\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.onDisconnectCancel = function (pathString, onComplete) {\r\n if (this.connected_) {\r\n this.sendOnDisconnect_('oc', pathString, null, onComplete);\r\n }\r\n else {\r\n this.onDisconnectRequestQueue_.push({\r\n pathString: pathString,\r\n action: 'oc',\r\n data: null,\r\n onComplete: onComplete\r\n });\r\n }\r\n };\r\n PersistentConnection.prototype.sendOnDisconnect_ = function (action, pathString, data, onComplete) {\r\n var request = { /*path*/ p: pathString, /*data*/ d: data };\r\n this.log_('onDisconnect ' + action, request);\r\n this.sendRequest(action, request, function (response) {\r\n if (onComplete) {\r\n setTimeout(function () {\r\n onComplete(response[ /*status*/'s'], response[ /* data */'d']);\r\n }, Math.floor(0));\r\n }\r\n });\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.put = function (pathString, data, onComplete, hash) {\r\n this.putInternal('p', pathString, data, onComplete, hash);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.merge = function (pathString, data, onComplete, hash) {\r\n this.putInternal('m', pathString, data, onComplete, hash);\r\n };\r\n PersistentConnection.prototype.putInternal = function (action, pathString, data, onComplete, hash) {\r\n var request = {\r\n /*path*/ p: pathString,\r\n /*data*/ d: data\r\n };\r\n if (hash !== undefined)\r\n request[ /*hash*/'h'] = hash;\r\n // TODO: Only keep track of the most recent put for a given path?\r\n this.outstandingPuts_.push({\r\n action: action,\r\n request: request,\r\n onComplete: onComplete\r\n });\r\n this.outstandingPutCount_++;\r\n var index = this.outstandingPuts_.length - 1;\r\n if (this.connected_) {\r\n this.sendPut_(index);\r\n }\r\n else {\r\n this.log_('Buffering put: ' + pathString);\r\n }\r\n };\r\n PersistentConnection.prototype.sendPut_ = function (index) {\r\n var _this = this;\r\n var action = this.outstandingPuts_[index].action;\r\n var request = this.outstandingPuts_[index].request;\r\n var onComplete = this.outstandingPuts_[index].onComplete;\r\n this.outstandingPuts_[index].queued = this.connected_;\r\n this.sendRequest(action, request, function (message) {\r\n _this.log_(action + ' response', message);\r\n delete _this.outstandingPuts_[index];\r\n _this.outstandingPutCount_--;\r\n // Clean up array occasionally.\r\n if (_this.outstandingPutCount_ === 0) {\r\n _this.outstandingPuts_ = [];\r\n }\r\n if (onComplete)\r\n onComplete(message[ /*status*/'s'], message[ /* data */'d']);\r\n });\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n PersistentConnection.prototype.reportStats = function (stats) {\r\n var _this = this;\r\n // If we're not connected, we just drop the stats.\r\n if (this.connected_) {\r\n var request = { /*counters*/ c: stats };\r\n this.log_('reportStats', request);\r\n this.sendRequest(/*stats*/ 's', request, function (result) {\r\n var status = result[ /*status*/'s'];\r\n if (status !== 'ok') {\r\n var errorReason = result[ /* data */'d'];\r\n _this.log_('reportStats', 'Error sending stats: ' + errorReason);\r\n }\r\n });\r\n }\r\n };\r\n /**\r\n * @param {*} message\r\n * @private\r\n */\r\n PersistentConnection.prototype.onDataMessage_ = function (message) {\r\n if ('r' in message) {\r\n // this is a response\r\n this.log_('from server: ' + stringify(message));\r\n var reqNum = message['r'];\r\n var onResponse = this.requestCBHash_[reqNum];\r\n if (onResponse) {\r\n delete this.requestCBHash_[reqNum];\r\n onResponse(message[ /*body*/'b']);\r\n }\r\n }\r\n else if ('error' in message) {\r\n throw 'A server-side error has occurred: ' + message['error'];\r\n }\r\n else if ('a' in message) {\r\n // a and b are action and body, respectively\r\n this.onDataPush_(message['a'], message['b']);\r\n }\r\n };\r\n PersistentConnection.prototype.onDataPush_ = function (action, body) {\r\n this.log_('handleServerMessage', action, body);\r\n if (action === 'd')\r\n this.onDataUpdate_(body[ /*path*/'p'], body[ /*data*/'d'], \r\n /*isMerge*/ false, body['t']);\r\n else if (action === 'm')\r\n this.onDataUpdate_(body[ /*path*/'p'], body[ /*data*/'d'], \r\n /*isMerge=*/ true, body['t']);\r\n else if (action === 'c')\r\n this.onListenRevoked_(body[ /*path*/'p'], body[ /*query*/'q']);\r\n else if (action === 'ac')\r\n this.onAuthRevoked_(body[ /*status code*/'s'], body[ /* explanation */'d']);\r\n else if (action === 'sd')\r\n this.onSecurityDebugPacket_(body);\r\n else\r\n error('Unrecognized action received from server: ' +\r\n stringify(action) +\r\n '\\nAre you using the latest client?');\r\n };\r\n PersistentConnection.prototype.onReady_ = function (timestamp, sessionId) {\r\n this.log_('connection ready');\r\n this.connected_ = true;\r\n this.lastConnectionEstablishedTime_ = new Date().getTime();\r\n this.handleTimestamp_(timestamp);\r\n this.lastSessionId = sessionId;\r\n if (this.firstConnection_) {\r\n this.sendConnectStats_();\r\n }\r\n this.restoreState_();\r\n this.firstConnection_ = false;\r\n this.onConnectStatus_(true);\r\n };\r\n PersistentConnection.prototype.scheduleConnect_ = function (timeout) {\r\n var _this = this;\r\n assert(!this.realtime_, \"Scheduling a connect when we're already connected/ing?\");\r\n if (this.establishConnectionTimer_) {\r\n clearTimeout(this.establishConnectionTimer_);\r\n }\r\n // NOTE: Even when timeout is 0, it's important to do a setTimeout to work around an infuriating \"Security Error\" in\r\n // Firefox when trying to write to our long-polling iframe in some scenarios (e.g. Forge or our unit tests).\r\n this.establishConnectionTimer_ = setTimeout(function () {\r\n _this.establishConnectionTimer_ = null;\r\n _this.establishConnection_();\r\n }, Math.floor(timeout));\r\n };\r\n /**\r\n * @param {boolean} visible\r\n * @private\r\n */\r\n PersistentConnection.prototype.onVisible_ = function (visible) {\r\n // NOTE: Tabbing away and back to a window will defeat our reconnect backoff, but I think that's fine.\r\n if (visible &&\r\n !this.visible_ &&\r\n this.reconnectDelay_ === this.maxReconnectDelay_) {\r\n this.log_('Window became visible. Reducing delay.');\r\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\r\n if (!this.realtime_) {\r\n this.scheduleConnect_(0);\r\n }\r\n }\r\n this.visible_ = visible;\r\n };\r\n PersistentConnection.prototype.onOnline_ = function (online) {\r\n if (online) {\r\n this.log_('Browser went online.');\r\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\r\n if (!this.realtime_) {\r\n this.scheduleConnect_(0);\r\n }\r\n }\r\n else {\r\n this.log_('Browser went offline. Killing connection.');\r\n if (this.realtime_) {\r\n this.realtime_.close();\r\n }\r\n }\r\n };\r\n PersistentConnection.prototype.onRealtimeDisconnect_ = function () {\r\n this.log_('data client disconnected');\r\n this.connected_ = false;\r\n this.realtime_ = null;\r\n // Since we don't know if our sent transactions succeeded or not, we need to cancel them.\r\n this.cancelSentTransactions_();\r\n // Clear out the pending requests.\r\n this.requestCBHash_ = {};\r\n if (this.shouldReconnect_()) {\r\n if (!this.visible_) {\r\n this.log_(\"Window isn't visible. Delaying reconnect.\");\r\n this.reconnectDelay_ = this.maxReconnectDelay_;\r\n this.lastConnectionAttemptTime_ = new Date().getTime();\r\n }\r\n else if (this.lastConnectionEstablishedTime_) {\r\n // If we've been connected long enough, reset reconnect delay to minimum.\r\n var timeSinceLastConnectSucceeded = new Date().getTime() - this.lastConnectionEstablishedTime_;\r\n if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT)\r\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\r\n this.lastConnectionEstablishedTime_ = null;\r\n }\r\n var timeSinceLastConnectAttempt = new Date().getTime() - this.lastConnectionAttemptTime_;\r\n var reconnectDelay = Math.max(0, this.reconnectDelay_ - timeSinceLastConnectAttempt);\r\n reconnectDelay = Math.random() * reconnectDelay;\r\n this.log_('Trying to reconnect in ' + reconnectDelay + 'ms');\r\n this.scheduleConnect_(reconnectDelay);\r\n // Adjust reconnect delay for next time.\r\n this.reconnectDelay_ = Math.min(this.maxReconnectDelay_, this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER);\r\n }\r\n this.onConnectStatus_(false);\r\n };\r\n PersistentConnection.prototype.establishConnection_ = function () {\r\n if (this.shouldReconnect_()) {\r\n this.log_('Making a connection attempt');\r\n this.lastConnectionAttemptTime_ = new Date().getTime();\r\n this.lastConnectionEstablishedTime_ = null;\r\n var onDataMessage_1 = this.onDataMessage_.bind(this);\r\n var onReady_1 = this.onReady_.bind(this);\r\n var onDisconnect_1 = this.onRealtimeDisconnect_.bind(this);\r\n var connId_1 = this.id + ':' + PersistentConnection.nextConnectionId_++;\r\n var self_1 = this;\r\n var lastSessionId_1 = this.lastSessionId;\r\n var canceled_1 = false;\r\n var connection_1 = null;\r\n var closeFn_1 = function () {\r\n if (connection_1) {\r\n connection_1.close();\r\n }\r\n else {\r\n canceled_1 = true;\r\n onDisconnect_1();\r\n }\r\n };\r\n var sendRequestFn = function (msg) {\r\n assert(connection_1, \"sendRequest call when we're not connected not allowed.\");\r\n connection_1.sendRequest(msg);\r\n };\r\n this.realtime_ = {\r\n close: closeFn_1,\r\n sendRequest: sendRequestFn\r\n };\r\n var forceRefresh = this.forceTokenRefresh_;\r\n this.forceTokenRefresh_ = false;\r\n // First fetch auth token, and establish connection after fetching the token was successful\r\n this.authTokenProvider_\r\n .getToken(forceRefresh)\r\n .then(function (result) {\r\n if (!canceled_1) {\r\n log('getToken() completed. Creating connection.');\r\n self_1.authToken_ = result && result.accessToken;\r\n connection_1 = new Connection(connId_1, self_1.repoInfo_, onDataMessage_1, onReady_1, onDisconnect_1, \r\n /* onKill= */ function (reason) {\r\n warn(reason + ' (' + self_1.repoInfo_.toString() + ')');\r\n self_1.interrupt(SERVER_KILL_INTERRUPT_REASON);\r\n }, lastSessionId_1);\r\n }\r\n else {\r\n log('getToken() completed but was canceled');\r\n }\r\n })\r\n .then(null, function (error) {\r\n self_1.log_('Failed to get token: ' + error);\r\n if (!canceled_1) {\r\n if (CONSTANTS.NODE_ADMIN) {\r\n // This may be a critical error for the Admin Node.js SDK, so log a warning.\r\n // But getToken() may also just have temporarily failed, so we still want to\r\n // continue retrying.\r\n warn(error);\r\n }\r\n closeFn_1();\r\n }\r\n });\r\n }\r\n };\r\n /**\r\n * @param {string} reason\r\n */\r\n PersistentConnection.prototype.interrupt = function (reason) {\r\n log('Interrupting connection for reason: ' + reason);\r\n this.interruptReasons_[reason] = true;\r\n if (this.realtime_) {\r\n this.realtime_.close();\r\n }\r\n else {\r\n if (this.establishConnectionTimer_) {\r\n clearTimeout(this.establishConnectionTimer_);\r\n this.establishConnectionTimer_ = null;\r\n }\r\n if (this.connected_) {\r\n this.onRealtimeDisconnect_();\r\n }\r\n }\r\n };\r\n /**\r\n * @param {string} reason\r\n */\r\n PersistentConnection.prototype.resume = function (reason) {\r\n log('Resuming connection for reason: ' + reason);\r\n delete this.interruptReasons_[reason];\r\n if (isEmpty(this.interruptReasons_)) {\r\n this.reconnectDelay_ = RECONNECT_MIN_DELAY;\r\n if (!this.realtime_) {\r\n this.scheduleConnect_(0);\r\n }\r\n }\r\n };\r\n PersistentConnection.prototype.handleTimestamp_ = function (timestamp) {\r\n var delta = timestamp - new Date().getTime();\r\n this.onServerInfoUpdate_({ serverTimeOffset: delta });\r\n };\r\n PersistentConnection.prototype.cancelSentTransactions_ = function () {\r\n for (var i = 0; i < this.outstandingPuts_.length; i++) {\r\n var put = this.outstandingPuts_[i];\r\n if (put && /*hash*/ 'h' in put.request && put.queued) {\r\n if (put.onComplete)\r\n put.onComplete('disconnect');\r\n delete this.outstandingPuts_[i];\r\n this.outstandingPutCount_--;\r\n }\r\n }\r\n // Clean up array occasionally.\r\n if (this.outstandingPutCount_ === 0)\r\n this.outstandingPuts_ = [];\r\n };\r\n /**\r\n * @param {!string} pathString\r\n * @param {Array.<*>=} query\r\n * @private\r\n */\r\n PersistentConnection.prototype.onListenRevoked_ = function (pathString, query) {\r\n // Remove the listen and manufacture a \"permission_denied\" error for the failed listen.\r\n var queryId;\r\n if (!query) {\r\n queryId = 'default';\r\n }\r\n else {\r\n queryId = query.map(function (q) { return ObjectToUniqueKey(q); }).join('$');\r\n }\r\n var listen = this.removeListen_(pathString, queryId);\r\n if (listen && listen.onComplete)\r\n listen.onComplete('permission_denied');\r\n };\r\n /**\r\n * @param {!string} pathString\r\n * @param {!string} queryId\r\n * @return {{queries:Array., onComplete:function(string)}}\r\n * @private\r\n */\r\n PersistentConnection.prototype.removeListen_ = function (pathString, queryId) {\r\n var normalizedPathString = new Path(pathString).toString(); // normalize path.\r\n var listen;\r\n if (this.listens_[normalizedPathString] !== undefined) {\r\n listen = this.listens_[normalizedPathString][queryId];\r\n delete this.listens_[normalizedPathString][queryId];\r\n if (getCount(this.listens_[normalizedPathString]) === 0) {\r\n delete this.listens_[normalizedPathString];\r\n }\r\n }\r\n else {\r\n // all listens for this path has already been removed\r\n listen = undefined;\r\n }\r\n return listen;\r\n };\r\n PersistentConnection.prototype.onAuthRevoked_ = function (statusCode, explanation) {\r\n log('Auth token revoked: ' + statusCode + '/' + explanation);\r\n this.authToken_ = null;\r\n this.forceTokenRefresh_ = true;\r\n this.realtime_.close();\r\n if (statusCode === 'invalid_token' || statusCode === 'permission_denied') {\r\n // We'll wait a couple times before logging the warning / increasing the\r\n // retry period since oauth tokens will report as \"invalid\" if they're\r\n // just expired. Plus there may be transient issues that resolve themselves.\r\n this.invalidAuthTokenCount_++;\r\n if (this.invalidAuthTokenCount_ >= INVALID_AUTH_TOKEN_THRESHOLD) {\r\n // Set a long reconnect delay because recovery is unlikely\r\n this.reconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;\r\n // Notify the auth token provider that the token is invalid, which will log\r\n // a warning\r\n this.authTokenProvider_.notifyForInvalidToken();\r\n }\r\n }\r\n };\r\n PersistentConnection.prototype.onSecurityDebugPacket_ = function (body) {\r\n if (this.securityDebugCallback_) {\r\n this.securityDebugCallback_(body);\r\n }\r\n else {\r\n if ('msg' in body) {\r\n console.log('FIREBASE: ' + body['msg'].replace('\\n', '\\nFIREBASE: '));\r\n }\r\n }\r\n };\r\n PersistentConnection.prototype.restoreState_ = function () {\r\n var _this = this;\r\n //Re-authenticate ourselves if we have a credential stored.\r\n this.tryAuth();\r\n // Puts depend on having received the corresponding data update from the server before they complete, so we must\r\n // make sure to send listens before puts.\r\n forEach(this.listens_, function (pathString, queries) {\r\n forEach(queries, function (key, listenSpec) {\r\n _this.sendListen_(listenSpec);\r\n });\r\n });\r\n for (var i = 0; i < this.outstandingPuts_.length; i++) {\r\n if (this.outstandingPuts_[i])\r\n this.sendPut_(i);\r\n }\r\n while (this.onDisconnectRequestQueue_.length) {\r\n var request = this.onDisconnectRequestQueue_.shift();\r\n this.sendOnDisconnect_(request.action, request.pathString, request.data, request.onComplete);\r\n }\r\n };\r\n /**\r\n * Sends client stats for first connection\r\n * @private\r\n */\r\n PersistentConnection.prototype.sendConnectStats_ = function () {\r\n var stats = {};\r\n var clientName = 'js';\r\n if (CONSTANTS.NODE_ADMIN) {\r\n clientName = 'admin_node';\r\n }\r\n else if (CONSTANTS.NODE_CLIENT) {\r\n clientName = 'node';\r\n }\r\n stats['sdk.' + clientName + '.' + firebase.SDK_VERSION.replace(/\\./g, '-')] = 1;\r\n if (isMobileCordova()) {\r\n stats['framework.cordova'] = 1;\r\n }\r\n else if (isReactNative()) {\r\n stats['framework.reactnative'] = 1;\r\n }\r\n this.reportStats(stats);\r\n };\r\n /**\r\n * @return {boolean}\r\n * @private\r\n */\r\n PersistentConnection.prototype.shouldReconnect_ = function () {\r\n var online = OnlineMonitor.getInstance().currentlyOnline();\r\n return isEmpty(this.interruptReasons_) && online;\r\n };\r\n /**\r\n * @private\r\n */\r\n PersistentConnection.nextPersistentConnectionId_ = 0;\r\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 */\r\n PersistentConnection.nextConnectionId_ = 0;\r\n return PersistentConnection;\r\n}(ServerActions));\n\n/**\r\n * @license\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 */\r\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 */\r\nvar ReadonlyRestClient = /** @class */ (function (_super) {\r\n __extends(ReadonlyRestClient, _super);\r\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 */\r\n function ReadonlyRestClient(repoInfo_, onDataUpdate_, authTokenProvider_) {\r\n var _this = _super.call(this) || this;\r\n _this.repoInfo_ = repoInfo_;\r\n _this.onDataUpdate_ = onDataUpdate_;\r\n _this.authTokenProvider_ = authTokenProvider_;\r\n /** @private {function(...[*])} */\r\n _this.log_ = logWrapper('p:rest:');\r\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 */\r\n _this.listens_ = {};\r\n return _this;\r\n }\r\n ReadonlyRestClient.prototype.reportStats = function (stats) {\r\n throw new Error('Method not implemented.');\r\n };\r\n /**\r\n * @param {!Query} query\r\n * @param {?number=} tag\r\n * @return {string}\r\n * @private\r\n */\r\n ReadonlyRestClient.getListenId_ = function (query, tag) {\r\n if (tag !== undefined) {\r\n return 'tag$' + tag;\r\n }\r\n else {\r\n assert(query.getQueryParams().isDefault(), \"should have a tag if it's not a default query.\");\r\n return query.path.toString();\r\n }\r\n };\r\n /** @inheritDoc */\r\n ReadonlyRestClient.prototype.listen = function (query, currentHashFn, tag, onComplete) {\r\n var _this = this;\r\n var pathString = query.path.toString();\r\n this.log_('Listen called for ' + pathString + ' ' + query.queryIdentifier());\r\n // Mark this listener so we can tell if it's removed.\r\n var listenId = ReadonlyRestClient.getListenId_(query, tag);\r\n var thisListen = {};\r\n this.listens_[listenId] = thisListen;\r\n var queryStringParameters = query\r\n .getQueryParams()\r\n .toRestQueryStringParameters();\r\n this.restRequest_(pathString + '.json', queryStringParameters, function (error, result) {\r\n var data = result;\r\n if (error === 404) {\r\n data = null;\r\n error = null;\r\n }\r\n if (error === null) {\r\n _this.onDataUpdate_(pathString, data, /*isMerge=*/ false, tag);\r\n }\r\n if (safeGet(_this.listens_, listenId) === thisListen) {\r\n var status_1;\r\n if (!error) {\r\n status_1 = 'ok';\r\n }\r\n else if (error == 401) {\r\n status_1 = 'permission_denied';\r\n }\r\n else {\r\n status_1 = 'rest_error:' + error;\r\n }\r\n onComplete(status_1, null);\r\n }\r\n });\r\n };\r\n /** @inheritDoc */\r\n ReadonlyRestClient.prototype.unlisten = function (query, tag) {\r\n var listenId = ReadonlyRestClient.getListenId_(query, tag);\r\n delete this.listens_[listenId];\r\n };\r\n /** @inheritDoc */\r\n ReadonlyRestClient.prototype.refreshAuthToken = function (token) {\r\n // no-op since we just always call getToken.\r\n };\r\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 */\r\n ReadonlyRestClient.prototype.restRequest_ = function (pathString, queryStringParameters, callback) {\r\n var _this = this;\r\n if (queryStringParameters === void 0) { queryStringParameters = {}; }\r\n queryStringParameters['format'] = 'export';\r\n this.authTokenProvider_\r\n .getToken(/*forceRefresh=*/ false)\r\n .then(function (authTokenData) {\r\n var authToken = authTokenData && authTokenData.accessToken;\r\n if (authToken) {\r\n queryStringParameters['auth'] = authToken;\r\n }\r\n var url = (_this.repoInfo_.secure ? 'https://' : 'http://') +\r\n _this.repoInfo_.host +\r\n pathString +\r\n '?' +\r\n 'ns=' +\r\n _this.repoInfo_.namespace +\r\n querystring(queryStringParameters);\r\n _this.log_('Sending REST request for ' + url);\r\n var xhr = new XMLHttpRequest();\r\n xhr.onreadystatechange = function () {\r\n if (callback && xhr.readyState === 4) {\r\n _this.log_('REST Response for ' + url + ' received. status:', xhr.status, 'response:', xhr.responseText);\r\n var res = null;\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n try {\r\n res = jsonEval(xhr.responseText);\r\n }\r\n catch (e) {\r\n warn('Failed to parse JSON response for ' +\r\n url +\r\n ': ' +\r\n xhr.responseText);\r\n }\r\n callback(null, res);\r\n }\r\n else {\r\n // 401 and 404 are expected.\r\n if (xhr.status !== 401 && xhr.status !== 404) {\r\n warn('Got unsuccessful REST response for ' +\r\n url +\r\n ' Status: ' +\r\n xhr.status);\r\n }\r\n callback(xhr.status);\r\n }\r\n callback = null;\r\n }\r\n };\r\n xhr.open('GET', url, /*asynchronous=*/ true);\r\n xhr.send();\r\n });\r\n };\r\n return ReadonlyRestClient;\r\n}(ServerActions));\n\n/**\r\n * @license\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 */\r\nvar INTERRUPT_REASON = 'repo_interrupt';\r\n/**\r\n * A connection to a single data repository.\r\n */\r\nvar Repo = /** @class */ (function () {\r\n /**\r\n * @param {!RepoInfo} repoInfo_\r\n * @param {boolean} forceRestClient\r\n * @param {!FirebaseApp} app\r\n */\r\n function Repo(repoInfo_, forceRestClient, app) {\r\n var _this = this;\r\n this.repoInfo_ = repoInfo_;\r\n this.app = app;\r\n this.dataUpdateCount = 0;\r\n this.statsListener_ = null;\r\n this.eventQueue_ = new EventQueue();\r\n this.nextWriteId_ = 1;\r\n this.interceptServerDataCallback_ = null;\r\n // A list of data pieces and paths to be set when this client disconnects.\r\n this.onDisconnect_ = new SparseSnapshotTree();\r\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 */\r\n this.persistentConnection_ = null;\r\n /** @type {!AuthTokenProvider} */\r\n var authTokenProvider = new AuthTokenProvider(app);\r\n this.stats_ = StatsManager.getCollection(repoInfo_);\r\n if (forceRestClient || beingCrawled()) {\r\n this.server_ = new ReadonlyRestClient(this.repoInfo_, this.onDataUpdate_.bind(this), authTokenProvider);\r\n // Minor hack: Fire onConnect immediately, since there's no actual connection.\r\n setTimeout(this.onConnectStatus_.bind(this, true), 0);\r\n }\r\n else {\r\n var authOverride = app.options['databaseAuthVariableOverride'];\r\n // Validate authOverride\r\n if (typeof authOverride !== 'undefined' && authOverride !== null) {\r\n if (typeof authOverride !== 'object') {\r\n throw new Error('Only objects are supported for option databaseAuthVariableOverride');\r\n }\r\n try {\r\n stringify(authOverride);\r\n }\r\n catch (e) {\r\n throw new Error('Invalid authOverride provided: ' + e);\r\n }\r\n }\r\n this.persistentConnection_ = new PersistentConnection(this.repoInfo_, this.onDataUpdate_.bind(this), this.onConnectStatus_.bind(this), this.onServerInfoUpdate_.bind(this), authTokenProvider, authOverride);\r\n this.server_ = this.persistentConnection_;\r\n }\r\n authTokenProvider.addTokenChangeListener(function (token) {\r\n _this.server_.refreshAuthToken(token);\r\n });\r\n // In the case of multiple Repos for the same repoInfo (i.e. there are multiple Firebase.Contexts being used),\r\n // we only want to create one StatsReporter. As such, we'll report stats over the first Repo created.\r\n this.statsReporter_ = StatsManager.getOrCreateReporter(repoInfo_, function () { return new StatsReporter(_this.stats_, _this.server_); });\r\n this.transactions_init_();\r\n // Used for .info.\r\n this.infoData_ = new SnapshotHolder();\r\n this.infoSyncTree_ = new SyncTree({\r\n startListening: function (query, tag, currentHashFn, onComplete) {\r\n var infoEvents = [];\r\n var node = _this.infoData_.getNode(query.path);\r\n // This is possibly a hack, but we have different semantics for .info endpoints. We don't raise null events\r\n // on initial data...\r\n if (!node.isEmpty()) {\r\n infoEvents = _this.infoSyncTree_.applyServerOverwrite(query.path, node);\r\n setTimeout(function () {\r\n onComplete('ok');\r\n }, 0);\r\n }\r\n return infoEvents;\r\n },\r\n stopListening: function () { }\r\n });\r\n this.updateInfo_('connected', false);\r\n this.serverSyncTree_ = new SyncTree({\r\n startListening: function (query, tag, currentHashFn, onComplete) {\r\n _this.server_.listen(query, currentHashFn, tag, function (status, data) {\r\n var events = onComplete(status, data);\r\n _this.eventQueue_.raiseEventsForChangedPath(query.path, events);\r\n });\r\n // No synchronous events for network-backed sync trees\r\n return [];\r\n },\r\n stopListening: function (query, tag) {\r\n _this.server_.unlisten(query, tag);\r\n }\r\n });\r\n }\r\n /**\r\n * @return {string} The URL corresponding to the root of this Firebase.\r\n */\r\n Repo.prototype.toString = function () {\r\n return ((this.repoInfo_.secure ? 'https://' : 'http://') + this.repoInfo_.host);\r\n };\r\n /**\r\n * @return {!string} The namespace represented by the repo.\r\n */\r\n Repo.prototype.name = function () {\r\n return this.repoInfo_.namespace;\r\n };\r\n /**\r\n * @return {!number} The time in milliseconds, taking the server offset into account if we have one.\r\n */\r\n Repo.prototype.serverTime = function () {\r\n var offsetNode = this.infoData_.getNode(new Path('.info/serverTimeOffset'));\r\n var offset = offsetNode.val() || 0;\r\n return new Date().getTime() + offset;\r\n };\r\n /**\r\n * Generate ServerValues using some variables from the repo object.\r\n * @return {!Object}\r\n */\r\n Repo.prototype.generateServerValues = function () {\r\n return generateWithValues({\r\n timestamp: this.serverTime()\r\n });\r\n };\r\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 */\r\n Repo.prototype.onDataUpdate_ = function (pathString, data, isMerge, tag) {\r\n // For testing.\r\n this.dataUpdateCount++;\r\n var path = new Path(pathString);\r\n data = this.interceptServerDataCallback_\r\n ? this.interceptServerDataCallback_(pathString, data)\r\n : data;\r\n var events = [];\r\n if (tag) {\r\n if (isMerge) {\r\n var taggedChildren = map(data, function (raw) {\r\n return nodeFromJSON$1(raw);\r\n });\r\n events = this.serverSyncTree_.applyTaggedQueryMerge(path, taggedChildren, tag);\r\n }\r\n else {\r\n var taggedSnap = nodeFromJSON$1(data);\r\n events = this.serverSyncTree_.applyTaggedQueryOverwrite(path, taggedSnap, tag);\r\n }\r\n }\r\n else if (isMerge) {\r\n var changedChildren = map(data, function (raw) {\r\n return nodeFromJSON$1(raw);\r\n });\r\n events = this.serverSyncTree_.applyServerMerge(path, changedChildren);\r\n }\r\n else {\r\n var snap = nodeFromJSON$1(data);\r\n events = this.serverSyncTree_.applyServerOverwrite(path, snap);\r\n }\r\n var affectedPath = path;\r\n if (events.length > 0) {\r\n // Since we have a listener outstanding for each transaction, receiving any events\r\n // is a proxy for some change having occurred.\r\n affectedPath = this.rerunTransactions_(path);\r\n }\r\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, events);\r\n };\r\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 */\r\n Repo.prototype.interceptServerData_ = function (callback) {\r\n this.interceptServerDataCallback_ = callback;\r\n };\r\n /**\r\n * @param {!boolean} connectStatus\r\n * @private\r\n */\r\n Repo.prototype.onConnectStatus_ = function (connectStatus) {\r\n this.updateInfo_('connected', connectStatus);\r\n if (connectStatus === false) {\r\n this.runOnDisconnectEvents_();\r\n }\r\n };\r\n /**\r\n * @param {!Object} updates\r\n * @private\r\n */\r\n Repo.prototype.onServerInfoUpdate_ = function (updates) {\r\n var _this = this;\r\n each(updates, function (value, key) {\r\n _this.updateInfo_(key, value);\r\n });\r\n };\r\n /**\r\n *\r\n * @param {!string} pathString\r\n * @param {*} value\r\n * @private\r\n */\r\n Repo.prototype.updateInfo_ = function (pathString, value) {\r\n var path = new Path('/.info/' + pathString);\r\n var newNode = nodeFromJSON$1(value);\r\n this.infoData_.updateSnapshot(path, newNode);\r\n var events = this.infoSyncTree_.applyServerOverwrite(path, newNode);\r\n this.eventQueue_.raiseEventsForChangedPath(path, events);\r\n };\r\n /**\r\n * @return {!number}\r\n * @private\r\n */\r\n Repo.prototype.getNextWriteId_ = function () {\r\n return this.nextWriteId_++;\r\n };\r\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 */\r\n Repo.prototype.setWithPriority = function (path, newVal, newPriority, onComplete) {\r\n var _this = this;\r\n this.log_('set', {\r\n path: path.toString(),\r\n value: newVal,\r\n priority: newPriority\r\n });\r\n // TODO: Optimize this behavior to either (a) store flag to skip resolving where possible and / or\r\n // (b) store unresolved paths on JSON parse\r\n var serverValues = this.generateServerValues();\r\n var newNodeUnresolved = nodeFromJSON$1(newVal, newPriority);\r\n var newNode = resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\r\n var writeId = this.getNextWriteId_();\r\n var events = this.serverSyncTree_.applyUserOverwrite(path, newNode, writeId, true);\r\n this.eventQueue_.queueEvents(events);\r\n this.server_.put(path.toString(), newNodeUnresolved.val(/*export=*/ true), function (status, errorReason) {\r\n var success = status === 'ok';\r\n if (!success) {\r\n warn('set at ' + path + ' failed: ' + status);\r\n }\r\n var clearEvents = _this.serverSyncTree_.ackUserWrite(writeId, !success);\r\n _this.eventQueue_.raiseEventsForChangedPath(path, clearEvents);\r\n _this.callOnCompleteCallback(onComplete, status, errorReason);\r\n });\r\n var affectedPath = this.abortTransactions_(path);\r\n this.rerunTransactions_(affectedPath);\r\n // We queued the events above, so just flush the queue here\r\n this.eventQueue_.raiseEventsForChangedPath(affectedPath, []);\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @param {!Object} childrenToMerge\r\n * @param {?function(?Error, *=)} onComplete\r\n */\r\n Repo.prototype.update = function (path, childrenToMerge, onComplete) {\r\n var _this = this;\r\n this.log_('update', { path: path.toString(), value: childrenToMerge });\r\n // Start with our existing data and merge each child into it.\r\n var empty = true;\r\n var serverValues = this.generateServerValues();\r\n var changedChildren = {};\r\n forEach(childrenToMerge, function (changedKey, changedValue) {\r\n empty = false;\r\n var newNodeUnresolved = nodeFromJSON$1(changedValue);\r\n changedChildren[changedKey] = resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\r\n });\r\n if (!empty) {\r\n var writeId_1 = this.getNextWriteId_();\r\n var events = this.serverSyncTree_.applyUserMerge(path, changedChildren, writeId_1);\r\n this.eventQueue_.queueEvents(events);\r\n this.server_.merge(path.toString(), childrenToMerge, function (status, errorReason) {\r\n var success = status === 'ok';\r\n if (!success) {\r\n warn('update at ' + path + ' failed: ' + status);\r\n }\r\n var clearEvents = _this.serverSyncTree_.ackUserWrite(writeId_1, !success);\r\n var affectedPath = clearEvents.length > 0 ? _this.rerunTransactions_(path) : path;\r\n _this.eventQueue_.raiseEventsForChangedPath(affectedPath, clearEvents);\r\n _this.callOnCompleteCallback(onComplete, status, errorReason);\r\n });\r\n forEach(childrenToMerge, function (changedPath) {\r\n var affectedPath = _this.abortTransactions_(path.child(changedPath));\r\n _this.rerunTransactions_(affectedPath);\r\n });\r\n // We queued the events above, so just flush the queue here\r\n this.eventQueue_.raiseEventsForChangedPath(path, []);\r\n }\r\n else {\r\n log(\"update() called with empty data. Don't do anything.\");\r\n this.callOnCompleteCallback(onComplete, 'ok');\r\n }\r\n };\r\n /**\r\n * Applies all of the changes stored up in the onDisconnect_ tree.\r\n * @private\r\n */\r\n Repo.prototype.runOnDisconnectEvents_ = function () {\r\n var _this = this;\r\n this.log_('onDisconnectEvents');\r\n var serverValues = this.generateServerValues();\r\n var resolvedOnDisconnectTree = resolveDeferredValueTree(this.onDisconnect_, serverValues);\r\n var events = [];\r\n resolvedOnDisconnectTree.forEachTree(Path.Empty, function (path, snap) {\r\n events = events.concat(_this.serverSyncTree_.applyServerOverwrite(path, snap));\r\n var affectedPath = _this.abortTransactions_(path);\r\n _this.rerunTransactions_(affectedPath);\r\n });\r\n this.onDisconnect_ = new SparseSnapshotTree();\r\n this.eventQueue_.raiseEventsForChangedPath(Path.Empty, events);\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @param {?function(?Error, *=)} onComplete\r\n */\r\n Repo.prototype.onDisconnectCancel = function (path, onComplete) {\r\n var _this = this;\r\n this.server_.onDisconnectCancel(path.toString(), function (status, errorReason) {\r\n if (status === 'ok') {\r\n _this.onDisconnect_.forget(path);\r\n }\r\n _this.callOnCompleteCallback(onComplete, status, errorReason);\r\n });\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @param {*} value\r\n * @param {?function(?Error, *=)} onComplete\r\n */\r\n Repo.prototype.onDisconnectSet = function (path, value, onComplete) {\r\n var _this = this;\r\n var newNode = nodeFromJSON$1(value);\r\n this.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/ true), function (status, errorReason) {\r\n if (status === 'ok') {\r\n _this.onDisconnect_.remember(path, newNode);\r\n }\r\n _this.callOnCompleteCallback(onComplete, status, errorReason);\r\n });\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @param {*} value\r\n * @param {*} priority\r\n * @param {?function(?Error, *=)} onComplete\r\n */\r\n Repo.prototype.onDisconnectSetWithPriority = function (path, value, priority, onComplete) {\r\n var _this = this;\r\n var newNode = nodeFromJSON$1(value, priority);\r\n this.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/ true), function (status, errorReason) {\r\n if (status === 'ok') {\r\n _this.onDisconnect_.remember(path, newNode);\r\n }\r\n _this.callOnCompleteCallback(onComplete, status, errorReason);\r\n });\r\n };\r\n /**\r\n * @param {!Path} path\r\n * @param {*} childrenToMerge\r\n * @param {?function(?Error, *=)} onComplete\r\n */\r\n Repo.prototype.onDisconnectUpdate = function (path, childrenToMerge, onComplete) {\r\n var _this = this;\r\n if (isEmpty(childrenToMerge)) {\r\n log(\"onDisconnect().update() called with empty data. Don't do anything.\");\r\n this.callOnCompleteCallback(onComplete, 'ok');\r\n return;\r\n }\r\n this.server_.onDisconnectMerge(path.toString(), childrenToMerge, function (status, errorReason) {\r\n if (status === 'ok') {\r\n forEach(childrenToMerge, function (childName, childNode) {\r\n var newChildNode = nodeFromJSON$1(childNode);\r\n _this.onDisconnect_.remember(path.child(childName), newChildNode);\r\n });\r\n }\r\n _this.callOnCompleteCallback(onComplete, status, errorReason);\r\n });\r\n };\r\n /**\r\n * @param {!Query} query\r\n * @param {!EventRegistration} eventRegistration\r\n */\r\n Repo.prototype.addEventCallbackForQuery = function (query, eventRegistration) {\r\n var events;\r\n if (query.path.getFront() === '.info') {\r\n events = this.infoSyncTree_.addEventRegistration(query, eventRegistration);\r\n }\r\n else {\r\n events = this.serverSyncTree_.addEventRegistration(query, eventRegistration);\r\n }\r\n this.eventQueue_.raiseEventsAtPath(query.path, events);\r\n };\r\n /**\r\n * @param {!Query} query\r\n * @param {?EventRegistration} eventRegistration\r\n */\r\n Repo.prototype.removeEventCallbackForQuery = function (query, eventRegistration) {\r\n // These are guaranteed not to raise events, since we're not passing in a cancelError. However, we can future-proof\r\n // a little bit by handling the return values anyways.\r\n var events;\r\n if (query.path.getFront() === '.info') {\r\n events = this.infoSyncTree_.removeEventRegistration(query, eventRegistration);\r\n }\r\n else {\r\n events = this.serverSyncTree_.removeEventRegistration(query, eventRegistration);\r\n }\r\n this.eventQueue_.raiseEventsAtPath(query.path, events);\r\n };\r\n Repo.prototype.interrupt = function () {\r\n if (this.persistentConnection_) {\r\n this.persistentConnection_.interrupt(INTERRUPT_REASON);\r\n }\r\n };\r\n Repo.prototype.resume = function () {\r\n if (this.persistentConnection_) {\r\n this.persistentConnection_.resume(INTERRUPT_REASON);\r\n }\r\n };\r\n Repo.prototype.stats = function (showDelta) {\r\n if (showDelta === void 0) { showDelta = false; }\r\n if (typeof console === 'undefined')\r\n return;\r\n var stats;\r\n if (showDelta) {\r\n if (!this.statsListener_)\r\n this.statsListener_ = new StatsListener(this.stats_);\r\n stats = this.statsListener_.get();\r\n }\r\n else {\r\n stats = this.stats_.get();\r\n }\r\n var longestName = Object.keys(stats).reduce(function (previousValue, currentValue) {\r\n return Math.max(currentValue.length, previousValue);\r\n }, 0);\r\n forEach(stats, function (stat, value) {\r\n // pad stat names to be the same length (plus 2 extra spaces).\r\n for (var i = stat.length; i < longestName + 2; i++)\r\n stat += ' ';\r\n console.log(stat + value);\r\n });\r\n };\r\n Repo.prototype.statsIncrementCounter = function (metric) {\r\n this.stats_.incrementCounter(metric);\r\n this.statsReporter_.includeStat(metric);\r\n };\r\n /**\r\n * @param {...*} var_args\r\n * @private\r\n */\r\n Repo.prototype.log_ = function () {\r\n var var_args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n var_args[_i] = arguments[_i];\r\n }\r\n var prefix = '';\r\n if (this.persistentConnection_) {\r\n prefix = this.persistentConnection_.id + ':';\r\n }\r\n log.apply(void 0, [prefix].concat(var_args));\r\n };\r\n /**\r\n * @param {?function(?Error, *=)} callback\r\n * @param {!string} status\r\n * @param {?string=} errorReason\r\n */\r\n Repo.prototype.callOnCompleteCallback = function (callback, status, errorReason) {\r\n if (callback) {\r\n exceptionGuard(function () {\r\n if (status == 'ok') {\r\n callback(null);\r\n }\r\n else {\r\n var code = (status || 'error').toUpperCase();\r\n var message = code;\r\n if (errorReason)\r\n message += ': ' + errorReason;\r\n var error = new Error(message);\r\n error.code = code;\r\n callback(error);\r\n }\r\n });\r\n }\r\n };\r\n Object.defineProperty(Repo.prototype, \"database\", {\r\n get: function () {\r\n return this.__database || (this.__database = new Database(this));\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n return Repo;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar RangedFilter = /** @class */ (function () {\r\n /**\r\n * @param {!QueryParams} params\r\n */\r\n function RangedFilter(params) {\r\n this.indexedFilter_ = new IndexedFilter(params.getIndex());\r\n this.index_ = params.getIndex();\r\n this.startPost_ = RangedFilter.getStartPost_(params);\r\n this.endPost_ = RangedFilter.getEndPost_(params);\r\n }\r\n /**\r\n * @return {!NamedNode}\r\n */\r\n RangedFilter.prototype.getStartPost = function () {\r\n return this.startPost_;\r\n };\r\n /**\r\n * @return {!NamedNode}\r\n */\r\n RangedFilter.prototype.getEndPost = function () {\r\n return this.endPost_;\r\n };\r\n /**\r\n * @param {!NamedNode} node\r\n * @return {boolean}\r\n */\r\n RangedFilter.prototype.matches = function (node) {\r\n return (this.index_.compare(this.getStartPost(), node) <= 0 &&\r\n this.index_.compare(node, this.getEndPost()) <= 0);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n RangedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {\r\n if (!this.matches(new NamedNode(key, newChild))) {\r\n newChild = ChildrenNode.EMPTY_NODE;\r\n }\r\n return this.indexedFilter_.updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n RangedFilter.prototype.updateFullNode = function (oldSnap, newSnap, optChangeAccumulator) {\r\n if (newSnap.isLeafNode()) {\r\n // Make sure we have a children node with the correct index, not a leaf node;\r\n newSnap = ChildrenNode.EMPTY_NODE;\r\n }\r\n var filtered = newSnap.withIndex(this.index_);\r\n // Don't support priorities on queries\r\n filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);\r\n var self = this;\r\n newSnap.forEachChild(PRIORITY_INDEX, function (key, childNode) {\r\n if (!self.matches(new NamedNode(key, childNode))) {\r\n filtered = filtered.updateImmediateChild(key, ChildrenNode.EMPTY_NODE);\r\n }\r\n });\r\n return this.indexedFilter_.updateFullNode(oldSnap, filtered, optChangeAccumulator);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n RangedFilter.prototype.updatePriority = function (oldSnap, newPriority) {\r\n // Don't support priorities on queries\r\n return oldSnap;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n RangedFilter.prototype.filtersNodes = function () {\r\n return true;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n RangedFilter.prototype.getIndexedFilter = function () {\r\n return this.indexedFilter_;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n RangedFilter.prototype.getIndex = function () {\r\n return this.index_;\r\n };\r\n /**\r\n * @param {!QueryParams} params\r\n * @return {!NamedNode}\r\n * @private\r\n */\r\n RangedFilter.getStartPost_ = function (params) {\r\n if (params.hasStart()) {\r\n var startName = params.getIndexStartName();\r\n return params.getIndex().makePost(params.getIndexStartValue(), startName);\r\n }\r\n else {\r\n return params.getIndex().minPost();\r\n }\r\n };\r\n /**\r\n * @param {!QueryParams} params\r\n * @return {!NamedNode}\r\n * @private\r\n */\r\n RangedFilter.getEndPost_ = function (params) {\r\n if (params.hasEnd()) {\r\n var endName = params.getIndexEndName();\r\n return params.getIndex().makePost(params.getIndexEndValue(), endName);\r\n }\r\n else {\r\n return params.getIndex().maxPost();\r\n }\r\n };\r\n return RangedFilter;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar LimitedFilter = /** @class */ (function () {\r\n /**\r\n * @param {!QueryParams} params\r\n */\r\n function LimitedFilter(params) {\r\n this.rangedFilter_ = new RangedFilter(params);\r\n this.index_ = params.getIndex();\r\n this.limit_ = params.getLimit();\r\n this.reverse_ = !params.isViewFromLeft();\r\n }\r\n /**\r\n * @inheritDoc\r\n */\r\n LimitedFilter.prototype.updateChild = function (snap, key, newChild, affectedPath, source, optChangeAccumulator) {\r\n if (!this.rangedFilter_.matches(new NamedNode(key, newChild))) {\r\n newChild = ChildrenNode.EMPTY_NODE;\r\n }\r\n if (snap.getImmediateChild(key).equals(newChild)) {\r\n // No change\r\n return snap;\r\n }\r\n else if (snap.numChildren() < this.limit_) {\r\n return this.rangedFilter_\r\n .getIndexedFilter()\r\n .updateChild(snap, key, newChild, affectedPath, source, optChangeAccumulator);\r\n }\r\n else {\r\n return this.fullLimitUpdateChild_(snap, key, newChild, source, optChangeAccumulator);\r\n }\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LimitedFilter.prototype.updateFullNode = function (oldSnap, newSnap, optChangeAccumulator) {\r\n var filtered;\r\n if (newSnap.isLeafNode() || newSnap.isEmpty()) {\r\n // Make sure we have a children node with the correct index, not a leaf node;\r\n filtered = ChildrenNode.EMPTY_NODE.withIndex(this.index_);\r\n }\r\n else {\r\n if (this.limit_ * 2 < newSnap.numChildren() &&\r\n newSnap.isIndexed(this.index_)) {\r\n // Easier to build up a snapshot, since what we're given has more than twice the elements we want\r\n filtered = ChildrenNode.EMPTY_NODE.withIndex(this.index_);\r\n // anchor to the startPost, endPost, or last element as appropriate\r\n var iterator = void 0;\r\n if (this.reverse_) {\r\n iterator = newSnap.getReverseIteratorFrom(this.rangedFilter_.getEndPost(), this.index_);\r\n }\r\n else {\r\n iterator = newSnap.getIteratorFrom(this.rangedFilter_.getStartPost(), this.index_);\r\n }\r\n var count = 0;\r\n while (iterator.hasNext() && count < this.limit_) {\r\n var next = iterator.getNext();\r\n var inRange = void 0;\r\n if (this.reverse_) {\r\n inRange =\r\n this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;\r\n }\r\n else {\r\n inRange =\r\n this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;\r\n }\r\n if (inRange) {\r\n filtered = filtered.updateImmediateChild(next.name, next.node);\r\n count++;\r\n }\r\n else {\r\n // if we have reached the end post, we cannot keep adding elemments\r\n break;\r\n }\r\n }\r\n }\r\n else {\r\n // The snap contains less than twice the limit. Faster to delete from the snap than build up a new one\r\n filtered = newSnap.withIndex(this.index_);\r\n // Don't support priorities on queries\r\n filtered = filtered.updatePriority(ChildrenNode.EMPTY_NODE);\r\n var startPost = void 0;\r\n var endPost = void 0;\r\n var cmp = void 0;\r\n var iterator = void 0;\r\n if (this.reverse_) {\r\n iterator = filtered.getReverseIterator(this.index_);\r\n startPost = this.rangedFilter_.getEndPost();\r\n endPost = this.rangedFilter_.getStartPost();\r\n var indexCompare_1 = this.index_.getCompare();\r\n cmp = function (a, b) { return indexCompare_1(b, a); };\r\n }\r\n else {\r\n iterator = filtered.getIterator(this.index_);\r\n startPost = this.rangedFilter_.getStartPost();\r\n endPost = this.rangedFilter_.getEndPost();\r\n cmp = this.index_.getCompare();\r\n }\r\n var count = 0;\r\n var foundStartPost = false;\r\n while (iterator.hasNext()) {\r\n var next = iterator.getNext();\r\n if (!foundStartPost && cmp(startPost, next) <= 0) {\r\n // start adding\r\n foundStartPost = true;\r\n }\r\n var inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;\r\n if (inRange) {\r\n count++;\r\n }\r\n else {\r\n filtered = filtered.updateImmediateChild(next.name, ChildrenNode.EMPTY_NODE);\r\n }\r\n }\r\n }\r\n }\r\n return this.rangedFilter_\r\n .getIndexedFilter()\r\n .updateFullNode(oldSnap, filtered, optChangeAccumulator);\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LimitedFilter.prototype.updatePriority = function (oldSnap, newPriority) {\r\n // Don't support priorities on queries\r\n return oldSnap;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LimitedFilter.prototype.filtersNodes = function () {\r\n return true;\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LimitedFilter.prototype.getIndexedFilter = function () {\r\n return this.rangedFilter_.getIndexedFilter();\r\n };\r\n /**\r\n * @inheritDoc\r\n */\r\n LimitedFilter.prototype.getIndex = function () {\r\n return this.index_;\r\n };\r\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 */\r\n LimitedFilter.prototype.fullLimitUpdateChild_ = function (snap, childKey, childSnap, source, changeAccumulator) {\r\n // TODO: rename all cache stuff etc to general snap terminology\r\n var cmp;\r\n if (this.reverse_) {\r\n var indexCmp_1 = this.index_.getCompare();\r\n cmp = function (a, b) { return indexCmp_1(b, a); };\r\n }\r\n else {\r\n cmp = this.index_.getCompare();\r\n }\r\n var oldEventCache = snap;\r\n assert(oldEventCache.numChildren() == this.limit_, '');\r\n var newChildNamedNode = new NamedNode(childKey, childSnap);\r\n var windowBoundary = this.reverse_\r\n ? oldEventCache.getFirstChild(this.index_)\r\n : oldEventCache.getLastChild(this.index_);\r\n var inRange = this.rangedFilter_.matches(newChildNamedNode);\r\n if (oldEventCache.hasChild(childKey)) {\r\n var oldChildSnap = oldEventCache.getImmediateChild(childKey);\r\n var nextChild = source.getChildAfterChild(this.index_, windowBoundary, this.reverse_);\r\n while (nextChild != null &&\r\n (nextChild.name == childKey || oldEventCache.hasChild(nextChild.name))) {\r\n // There is a weird edge case where a node is updated as part of a merge in the write tree, but hasn't\r\n // been applied to the limited filter yet. Ignore this next child which will be updated later in\r\n // the limited filter...\r\n nextChild = source.getChildAfterChild(this.index_, nextChild, this.reverse_);\r\n }\r\n var compareNext = nextChild == null ? 1 : cmp(nextChild, newChildNamedNode);\r\n var remainsInWindow = inRange && !childSnap.isEmpty() && compareNext >= 0;\r\n if (remainsInWindow) {\r\n if (changeAccumulator != null) {\r\n changeAccumulator.trackChildChange(Change.childChangedChange(childKey, childSnap, oldChildSnap));\r\n }\r\n return oldEventCache.updateImmediateChild(childKey, childSnap);\r\n }\r\n else {\r\n if (changeAccumulator != null) {\r\n changeAccumulator.trackChildChange(Change.childRemovedChange(childKey, oldChildSnap));\r\n }\r\n var newEventCache = oldEventCache.updateImmediateChild(childKey, ChildrenNode.EMPTY_NODE);\r\n var nextChildInRange = nextChild != null && this.rangedFilter_.matches(nextChild);\r\n if (nextChildInRange) {\r\n if (changeAccumulator != null) {\r\n changeAccumulator.trackChildChange(Change.childAddedChange(nextChild.name, nextChild.node));\r\n }\r\n return newEventCache.updateImmediateChild(nextChild.name, nextChild.node);\r\n }\r\n else {\r\n return newEventCache;\r\n }\r\n }\r\n }\r\n else if (childSnap.isEmpty()) {\r\n // we're deleting a node, but it was not in the window, so ignore it\r\n return snap;\r\n }\r\n else if (inRange) {\r\n if (cmp(windowBoundary, newChildNamedNode) >= 0) {\r\n if (changeAccumulator != null) {\r\n changeAccumulator.trackChildChange(Change.childRemovedChange(windowBoundary.name, windowBoundary.node));\r\n changeAccumulator.trackChildChange(Change.childAddedChange(childKey, childSnap));\r\n }\r\n return oldEventCache\r\n .updateImmediateChild(childKey, childSnap)\r\n .updateImmediateChild(windowBoundary.name, ChildrenNode.EMPTY_NODE);\r\n }\r\n else {\r\n return snap;\r\n }\r\n }\r\n else {\r\n return snap;\r\n }\r\n };\r\n return LimitedFilter;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar QueryParams = /** @class */ (function () {\r\n function QueryParams() {\r\n this.limitSet_ = false;\r\n this.startSet_ = false;\r\n this.startNameSet_ = false;\r\n this.endSet_ = false;\r\n this.endNameSet_ = false;\r\n this.limit_ = 0;\r\n this.viewFrom_ = '';\r\n this.indexStartValue_ = null;\r\n this.indexStartName_ = '';\r\n this.indexEndValue_ = null;\r\n this.indexEndName_ = '';\r\n this.index_ = PRIORITY_INDEX;\r\n }\r\n /**\r\n * @return {boolean}\r\n */\r\n QueryParams.prototype.hasStart = function () {\r\n return this.startSet_;\r\n };\r\n /**\r\n * @return {boolean} True if it would return from left.\r\n */\r\n QueryParams.prototype.isViewFromLeft = function () {\r\n if (this.viewFrom_ === '') {\r\n // limit(), rather than limitToFirst or limitToLast was called.\r\n // This means that only one of startSet_ and endSet_ is true. Use them\r\n // to calculate which side of the view to anchor to. If neither is set,\r\n // anchor to the end.\r\n return this.startSet_;\r\n }\r\n else {\r\n return (this.viewFrom_ === QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT);\r\n }\r\n };\r\n /**\r\n * Only valid to call if hasStart() returns true\r\n * @return {*}\r\n */\r\n QueryParams.prototype.getIndexStartValue = function () {\r\n assert(this.startSet_, 'Only valid if start has been set');\r\n return this.indexStartValue_;\r\n };\r\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 */\r\n QueryParams.prototype.getIndexStartName = function () {\r\n assert(this.startSet_, 'Only valid if start has been set');\r\n if (this.startNameSet_) {\r\n return this.indexStartName_;\r\n }\r\n else {\r\n return MIN_NAME;\r\n }\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n QueryParams.prototype.hasEnd = function () {\r\n return this.endSet_;\r\n };\r\n /**\r\n * Only valid to call if hasEnd() returns true.\r\n * @return {*}\r\n */\r\n QueryParams.prototype.getIndexEndValue = function () {\r\n assert(this.endSet_, 'Only valid if end has been set');\r\n return this.indexEndValue_;\r\n };\r\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 */\r\n QueryParams.prototype.getIndexEndName = function () {\r\n assert(this.endSet_, 'Only valid if end has been set');\r\n if (this.endNameSet_) {\r\n return this.indexEndName_;\r\n }\r\n else {\r\n return MAX_NAME;\r\n }\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n QueryParams.prototype.hasLimit = function () {\r\n return this.limitSet_;\r\n };\r\n /**\r\n * @return {boolean} True if a limit has been set and it has been explicitly anchored\r\n */\r\n QueryParams.prototype.hasAnchoredLimit = function () {\r\n return this.limitSet_ && this.viewFrom_ !== '';\r\n };\r\n /**\r\n * Only valid to call if hasLimit() returns true\r\n * @return {!number}\r\n */\r\n QueryParams.prototype.getLimit = function () {\r\n assert(this.limitSet_, 'Only valid if limit has been set');\r\n return this.limit_;\r\n };\r\n /**\r\n * @return {!Index}\r\n */\r\n QueryParams.prototype.getIndex = function () {\r\n return this.index_;\r\n };\r\n /**\r\n * @return {!QueryParams}\r\n * @private\r\n */\r\n QueryParams.prototype.copy_ = function () {\r\n var copy = new QueryParams();\r\n copy.limitSet_ = this.limitSet_;\r\n copy.limit_ = this.limit_;\r\n copy.startSet_ = this.startSet_;\r\n copy.indexStartValue_ = this.indexStartValue_;\r\n copy.startNameSet_ = this.startNameSet_;\r\n copy.indexStartName_ = this.indexStartName_;\r\n copy.endSet_ = this.endSet_;\r\n copy.indexEndValue_ = this.indexEndValue_;\r\n copy.endNameSet_ = this.endNameSet_;\r\n copy.indexEndName_ = this.indexEndName_;\r\n copy.index_ = this.index_;\r\n copy.viewFrom_ = this.viewFrom_;\r\n return copy;\r\n };\r\n /**\r\n * @param {!number} newLimit\r\n * @return {!QueryParams}\r\n */\r\n QueryParams.prototype.limit = function (newLimit) {\r\n var newParams = this.copy_();\r\n newParams.limitSet_ = true;\r\n newParams.limit_ = newLimit;\r\n newParams.viewFrom_ = '';\r\n return newParams;\r\n };\r\n /**\r\n * @param {!number} newLimit\r\n * @return {!QueryParams}\r\n */\r\n QueryParams.prototype.limitToFirst = function (newLimit) {\r\n var newParams = this.copy_();\r\n newParams.limitSet_ = true;\r\n newParams.limit_ = newLimit;\r\n newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;\r\n return newParams;\r\n };\r\n /**\r\n * @param {!number} newLimit\r\n * @return {!QueryParams}\r\n */\r\n QueryParams.prototype.limitToLast = function (newLimit) {\r\n var newParams = this.copy_();\r\n newParams.limitSet_ = true;\r\n newParams.limit_ = newLimit;\r\n newParams.viewFrom_ = QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_RIGHT;\r\n return newParams;\r\n };\r\n /**\r\n * @param {*} indexValue\r\n * @param {?string=} key\r\n * @return {!QueryParams}\r\n */\r\n QueryParams.prototype.startAt = function (indexValue, key) {\r\n var newParams = this.copy_();\r\n newParams.startSet_ = true;\r\n if (!(indexValue !== undefined)) {\r\n indexValue = null;\r\n }\r\n newParams.indexStartValue_ = indexValue;\r\n if (key != null) {\r\n newParams.startNameSet_ = true;\r\n newParams.indexStartName_ = key;\r\n }\r\n else {\r\n newParams.startNameSet_ = false;\r\n newParams.indexStartName_ = '';\r\n }\r\n return newParams;\r\n };\r\n /**\r\n * @param {*} indexValue\r\n * @param {?string=} key\r\n * @return {!QueryParams}\r\n */\r\n QueryParams.prototype.endAt = function (indexValue, key) {\r\n var newParams = this.copy_();\r\n newParams.endSet_ = true;\r\n if (!(indexValue !== undefined)) {\r\n indexValue = null;\r\n }\r\n newParams.indexEndValue_ = indexValue;\r\n if (key !== undefined) {\r\n newParams.endNameSet_ = true;\r\n newParams.indexEndName_ = key;\r\n }\r\n else {\r\n newParams.endNameSet_ = false;\r\n newParams.indexEndName_ = '';\r\n }\r\n return newParams;\r\n };\r\n /**\r\n * @param {!Index} index\r\n * @return {!QueryParams}\r\n */\r\n QueryParams.prototype.orderBy = function (index) {\r\n var newParams = this.copy_();\r\n newParams.index_ = index;\r\n return newParams;\r\n };\r\n /**\r\n * @return {!Object}\r\n */\r\n QueryParams.prototype.getQueryObject = function () {\r\n var WIRE_PROTOCOL_CONSTANTS = QueryParams.WIRE_PROTOCOL_CONSTANTS_;\r\n var obj = {};\r\n if (this.startSet_) {\r\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE] = this.indexStartValue_;\r\n if (this.startNameSet_) {\r\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME] = this.indexStartName_;\r\n }\r\n }\r\n if (this.endSet_) {\r\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE] = this.indexEndValue_;\r\n if (this.endNameSet_) {\r\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME] = this.indexEndName_;\r\n }\r\n }\r\n if (this.limitSet_) {\r\n obj[WIRE_PROTOCOL_CONSTANTS.LIMIT] = this.limit_;\r\n var viewFrom = this.viewFrom_;\r\n if (viewFrom === '') {\r\n if (this.isViewFromLeft()) {\r\n viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT;\r\n }\r\n else {\r\n viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT;\r\n }\r\n }\r\n obj[WIRE_PROTOCOL_CONSTANTS.VIEW_FROM] = viewFrom;\r\n }\r\n // For now, priority index is the default, so we only specify if it's some other index\r\n if (this.index_ !== PRIORITY_INDEX) {\r\n obj[WIRE_PROTOCOL_CONSTANTS.INDEX] = this.index_.toString();\r\n }\r\n return obj;\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n QueryParams.prototype.loadsAllData = function () {\r\n return !(this.startSet_ || this.endSet_ || this.limitSet_);\r\n };\r\n /**\r\n * @return {boolean}\r\n */\r\n QueryParams.prototype.isDefault = function () {\r\n return this.loadsAllData() && this.index_ == PRIORITY_INDEX;\r\n };\r\n /**\r\n * @return {!NodeFilter}\r\n */\r\n QueryParams.prototype.getNodeFilter = function () {\r\n if (this.loadsAllData()) {\r\n return new IndexedFilter(this.getIndex());\r\n }\r\n else if (this.hasLimit()) {\r\n return new LimitedFilter(this);\r\n }\r\n else {\r\n return new RangedFilter(this);\r\n }\r\n };\r\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 */\r\n QueryParams.prototype.toRestQueryStringParameters = function () {\r\n var REST_CONSTANTS = QueryParams.REST_QUERY_CONSTANTS_;\r\n var qs = {};\r\n if (this.isDefault()) {\r\n return qs;\r\n }\r\n var orderBy;\r\n if (this.index_ === PRIORITY_INDEX) {\r\n orderBy = REST_CONSTANTS.PRIORITY_INDEX;\r\n }\r\n else if (this.index_ === VALUE_INDEX) {\r\n orderBy = REST_CONSTANTS.VALUE_INDEX;\r\n }\r\n else if (this.index_ === KEY_INDEX) {\r\n orderBy = REST_CONSTANTS.KEY_INDEX;\r\n }\r\n else {\r\n assert(this.index_ instanceof PathIndex, 'Unrecognized index type!');\r\n orderBy = this.index_.toString();\r\n }\r\n qs[REST_CONSTANTS.ORDER_BY] = stringify(orderBy);\r\n if (this.startSet_) {\r\n qs[REST_CONSTANTS.START_AT] = stringify(this.indexStartValue_);\r\n if (this.startNameSet_) {\r\n qs[REST_CONSTANTS.START_AT] += ',' + stringify(this.indexStartName_);\r\n }\r\n }\r\n if (this.endSet_) {\r\n qs[REST_CONSTANTS.END_AT] = stringify(this.indexEndValue_);\r\n if (this.endNameSet_) {\r\n qs[REST_CONSTANTS.END_AT] += ',' + stringify(this.indexEndName_);\r\n }\r\n }\r\n if (this.limitSet_) {\r\n if (this.isViewFromLeft()) {\r\n qs[REST_CONSTANTS.LIMIT_TO_FIRST] = this.limit_;\r\n }\r\n else {\r\n qs[REST_CONSTANTS.LIMIT_TO_LAST] = this.limit_;\r\n }\r\n }\r\n return qs;\r\n };\r\n /**\r\n * Wire Protocol Constants\r\n * @const\r\n * @enum {string}\r\n * @private\r\n */\r\n QueryParams.WIRE_PROTOCOL_CONSTANTS_ = {\r\n INDEX_START_VALUE: 'sp',\r\n INDEX_START_NAME: 'sn',\r\n INDEX_END_VALUE: 'ep',\r\n INDEX_END_NAME: 'en',\r\n LIMIT: 'l',\r\n VIEW_FROM: 'vf',\r\n VIEW_FROM_LEFT: 'l',\r\n VIEW_FROM_RIGHT: 'r',\r\n INDEX: 'i'\r\n };\r\n /**\r\n * REST Query Constants\r\n * @const\r\n * @enum {string}\r\n * @private\r\n */\r\n QueryParams.REST_QUERY_CONSTANTS_ = {\r\n ORDER_BY: 'orderBy',\r\n PRIORITY_INDEX: '$priority',\r\n VALUE_INDEX: '$value',\r\n KEY_INDEX: '$key',\r\n START_AT: 'startAt',\r\n END_AT: 'endAt',\r\n LIMIT_TO_FIRST: 'limitToFirst',\r\n LIMIT_TO_LAST: 'limitToLast'\r\n };\r\n /**\r\n * Default, empty query parameters\r\n * @type {!QueryParams}\r\n * @const\r\n */\r\n QueryParams.DEFAULT = new QueryParams();\r\n return QueryParams;\r\n}());\n\n/**\r\n * @license\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 */\r\nvar Reference = /** @class */ (function (_super) {\r\n __extends(Reference, _super);\r\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 */\r\n function Reference(repo, path) {\r\n var _this = this;\r\n if (!(repo instanceof Repo)) {\r\n throw new Error('new Reference() no longer supported - use app.database().');\r\n }\r\n // call Query's constructor, passing in the repo and path.\r\n _this = _super.call(this, repo, path, QueryParams.DEFAULT, false) || this;\r\n return _this;\r\n }\r\n /** @return {?string} */\r\n Reference.prototype.getKey = function () {\r\n validateArgCount('Reference.key', 0, 0, arguments.length);\r\n if (this.path.isEmpty())\r\n return null;\r\n else\r\n return this.path.getBack();\r\n };\r\n /**\r\n * @param {!(string|Path)} pathString\r\n * @return {!Reference}\r\n */\r\n Reference.prototype.child = function (pathString) {\r\n validateArgCount('Reference.child', 1, 1, arguments.length);\r\n if (typeof pathString === 'number') {\r\n pathString = String(pathString);\r\n }\r\n else if (!(pathString instanceof Path)) {\r\n if (this.path.getFront() === null)\r\n validateRootPathString('Reference.child', 1, pathString, false);\r\n else\r\n validatePathString('Reference.child', 1, pathString, false);\r\n }\r\n return new Reference(this.repo, this.path.child(pathString));\r\n };\r\n /** @return {?Reference} */\r\n Reference.prototype.getParent = function () {\r\n validateArgCount('Reference.parent', 0, 0, arguments.length);\r\n var parentPath = this.path.parent();\r\n return parentPath === null ? null : new Reference(this.repo, parentPath);\r\n };\r\n /** @return {!Reference} */\r\n Reference.prototype.getRoot = function () {\r\n validateArgCount('Reference.root', 0, 0, arguments.length);\r\n var ref = this;\r\n while (ref.getParent() !== null) {\r\n ref = ref.getParent();\r\n }\r\n return ref;\r\n };\r\n /** @return {!Database} */\r\n Reference.prototype.databaseProp = function () {\r\n return this.repo.database;\r\n };\r\n /**\r\n * @param {*} newVal\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\r\n Reference.prototype.set = function (newVal, onComplete) {\r\n validateArgCount('Reference.set', 1, 2, arguments.length);\r\n validateWritablePath('Reference.set', this.path);\r\n validateFirebaseDataArg('Reference.set', 1, newVal, this.path, false);\r\n validateCallback('Reference.set', 2, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo.setWithPriority(this.path, newVal, \r\n /*priority=*/ null, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {!Object} objectToMerge\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\r\n Reference.prototype.update = function (objectToMerge, onComplete) {\r\n validateArgCount('Reference.update', 1, 2, arguments.length);\r\n validateWritablePath('Reference.update', this.path);\r\n if (Array.isArray(objectToMerge)) {\r\n var newObjectToMerge = {};\r\n for (var i = 0; i < objectToMerge.length; ++i) {\r\n newObjectToMerge['' + i] = objectToMerge[i];\r\n }\r\n objectToMerge = newObjectToMerge;\r\n warn('Passing an Array to Firebase.update() is deprecated. ' +\r\n 'Use set() if you want to overwrite the existing data, or ' +\r\n 'an Object with integer keys if you really do want to ' +\r\n 'only update some of the children.');\r\n }\r\n validateFirebaseMergeDataArg('Reference.update', 1, objectToMerge, this.path, false);\r\n validateCallback('Reference.update', 2, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo.update(this.path, objectToMerge, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {*} newVal\r\n * @param {string|number|null} newPriority\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\r\n Reference.prototype.setWithPriority = function (newVal, newPriority, onComplete) {\r\n validateArgCount('Reference.setWithPriority', 2, 3, arguments.length);\r\n validateWritablePath('Reference.setWithPriority', this.path);\r\n validateFirebaseDataArg('Reference.setWithPriority', 1, newVal, this.path, false);\r\n validatePriority('Reference.setWithPriority', 2, newPriority, false);\r\n validateCallback('Reference.setWithPriority', 3, onComplete, true);\r\n if (this.getKey() === '.length' || this.getKey() === '.keys')\r\n throw 'Reference.setWithPriority failed: ' +\r\n this.getKey() +\r\n ' is a read-only object.';\r\n var deferred = new Deferred();\r\n this.repo.setWithPriority(this.path, newVal, newPriority, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\r\n Reference.prototype.remove = function (onComplete) {\r\n validateArgCount('Reference.remove', 0, 1, arguments.length);\r\n validateWritablePath('Reference.remove', this.path);\r\n validateCallback('Reference.remove', 1, onComplete, true);\r\n return this.set(null, onComplete);\r\n };\r\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 */\r\n Reference.prototype.transaction = function (transactionUpdate, onComplete, applyLocally) {\r\n validateArgCount('Reference.transaction', 1, 3, arguments.length);\r\n validateWritablePath('Reference.transaction', this.path);\r\n validateCallback('Reference.transaction', 1, transactionUpdate, false);\r\n validateCallback('Reference.transaction', 2, onComplete, true);\r\n // NOTE: applyLocally is an internal-only option for now. We need to decide if we want to keep it and how\r\n // to expose it.\r\n validateBoolean('Reference.transaction', 3, applyLocally, true);\r\n if (this.getKey() === '.length' || this.getKey() === '.keys')\r\n throw 'Reference.transaction failed: ' +\r\n this.getKey() +\r\n ' is a read-only object.';\r\n if (applyLocally === undefined)\r\n applyLocally = true;\r\n var deferred = new Deferred();\r\n if (typeof onComplete === 'function') {\r\n deferred.promise.catch(function () { });\r\n }\r\n var promiseComplete = function (error, committed, snapshot) {\r\n if (error) {\r\n deferred.reject(error);\r\n }\r\n else {\r\n deferred.resolve(new TransactionResult(committed, snapshot));\r\n }\r\n if (typeof onComplete === 'function') {\r\n onComplete(error, committed, snapshot);\r\n }\r\n };\r\n this.repo.startTransaction(this.path, transactionUpdate, promiseComplete, applyLocally);\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {string|number|null} priority\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Promise}\r\n */\r\n Reference.prototype.setPriority = function (priority, onComplete) {\r\n validateArgCount('Reference.setPriority', 1, 2, arguments.length);\r\n validateWritablePath('Reference.setPriority', this.path);\r\n validatePriority('Reference.setPriority', 1, priority, false);\r\n validateCallback('Reference.setPriority', 2, onComplete, true);\r\n var deferred = new Deferred();\r\n this.repo.setWithPriority(this.path.child('.priority'), priority, null, deferred.wrapCallback(onComplete));\r\n return deferred.promise;\r\n };\r\n /**\r\n * @param {*=} value\r\n * @param {function(?Error)=} onComplete\r\n * @return {!Reference}\r\n */\r\n Reference.prototype.push = function (value, onComplete) {\r\n validateArgCount('Reference.push', 0, 2, arguments.length);\r\n validateWritablePath('Reference.push', this.path);\r\n validateFirebaseDataArg('Reference.push', 1, value, this.path, true);\r\n validateCallback('Reference.push', 2, onComplete, true);\r\n var now = this.repo.serverTime();\r\n var name = nextPushId(now);\r\n // push() returns a ThennableReference whose promise is fulfilled with a regular Reference.\r\n // We use child() to create handles to two different references. The first is turned into a\r\n // ThennableReference below by adding then() and catch() methods and is used as the\r\n // return value of push(). The second remains a regular Reference and is used as the fulfilled\r\n // value of the first ThennableReference.\r\n var thennablePushRef = this.child(name);\r\n var pushRef = this.child(name);\r\n var promise;\r\n if (value != null) {\r\n promise = thennablePushRef.set(value, onComplete).then(function () { return pushRef; });\r\n }\r\n else {\r\n promise = Promise.resolve(pushRef);\r\n }\r\n thennablePushRef.then = promise.then.bind(promise);\r\n thennablePushRef.catch = promise.then.bind(promise, undefined);\r\n if (typeof onComplete === 'function') {\r\n promise.catch(function () { });\r\n }\r\n return thennablePushRef;\r\n };\r\n /**\r\n * @return {!OnDisconnect}\r\n */\r\n Reference.prototype.onDisconnect = function () {\r\n validateWritablePath('Reference.onDisconnect', this.path);\r\n return new OnDisconnect(this.repo, this.path);\r\n };\r\n Object.defineProperty(Reference.prototype, \"database\", {\r\n get: function () {\r\n return this.databaseProp();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(Reference.prototype, \"key\", {\r\n get: function () {\r\n return this.getKey();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(Reference.prototype, \"parent\", {\r\n get: function () {\r\n return this.getParent();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Object.defineProperty(Reference.prototype, \"root\", {\r\n get: function () {\r\n return this.getRoot();\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n return Reference;\r\n}(Query));\r\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 */\r\nQuery.__referenceConstructor = Reference;\r\nSyncPoint.__referenceConstructor = Reference;\n\n/**\r\n * @license\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 */\r\n/**\r\n * Node in a Tree.\r\n */\r\nvar TreeNode = /** @class */ (function () {\r\n function TreeNode() {\r\n // TODO: Consider making accessors that create children and value lazily or\r\n // separate Internal / Leaf 'types'.\r\n this.children = {};\r\n this.childCount = 0;\r\n this.value = null;\r\n }\r\n return TreeNode;\r\n}());\r\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 */\r\nvar Tree = /** @class */ (function () {\r\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 */\r\n function Tree(name_, parent_, node_) {\r\n if (name_ === void 0) { name_ = ''; }\r\n if (parent_ === void 0) { parent_ = null; }\r\n if (node_ === void 0) { node_ = new TreeNode(); }\r\n this.name_ = name_;\r\n this.parent_ = parent_;\r\n this.node_ = node_;\r\n }\r\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 */\r\n Tree.prototype.subTree = function (pathObj) {\r\n // TODO: Require pathObj to be Path?\r\n var path = pathObj instanceof Path ? pathObj : new Path(pathObj);\r\n var child = this, next;\r\n while ((next = path.getFront()) !== null) {\r\n var childNode = safeGet(child.node_.children, next) || new TreeNode();\r\n child = new Tree(next, child, childNode);\r\n path = path.popFront();\r\n }\r\n return child;\r\n };\r\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 */\r\n Tree.prototype.getValue = function () {\r\n return this.node_.value;\r\n };\r\n /**\r\n * Sets data to this tree node.\r\n *\r\n * @param {!T} value Value to set.\r\n */\r\n Tree.prototype.setValue = function (value) {\r\n assert(typeof value !== 'undefined', 'Cannot set value to undefined');\r\n this.node_.value = value;\r\n this.updateParents_();\r\n };\r\n /**\r\n * Clears the contents of the tree node (its value and all children).\r\n */\r\n Tree.prototype.clear = function () {\r\n this.node_.value = null;\r\n this.node_.children = {};\r\n this.node_.childCount = 0;\r\n this.updateParents_();\r\n };\r\n /**\r\n * @return {boolean} Whether the tree has any children.\r\n */\r\n Tree.prototype.hasChildren = function () {\r\n return this.node_.childCount > 0;\r\n };\r\n /**\r\n * @return {boolean} Whether the tree is empty (no value or children).\r\n */\r\n Tree.prototype.isEmpty = function () {\r\n return this.getValue() === null && !this.hasChildren();\r\n };\r\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 */\r\n Tree.prototype.forEachChild = function (action) {\r\n var _this = this;\r\n forEach(this.node_.children, function (child, childTree) {\r\n action(new Tree(child, _this, childTree));\r\n });\r\n };\r\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 */\r\n Tree.prototype.forEachDescendant = function (action, includeSelf, childrenFirst) {\r\n if (includeSelf && !childrenFirst)\r\n action(this);\r\n this.forEachChild(function (child) {\r\n child.forEachDescendant(action, /*includeSelf=*/ true, childrenFirst);\r\n });\r\n if (includeSelf && childrenFirst)\r\n action(this);\r\n };\r\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 */\r\n Tree.prototype.forEachAncestor = function (action, includeSelf) {\r\n var node = includeSelf ? this : this.parent();\r\n while (node !== null) {\r\n if (action(node)) {\r\n return true;\r\n }\r\n node = node.parent();\r\n }\r\n return false;\r\n };\r\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 */\r\n Tree.prototype.forEachImmediateDescendantWithValue = function (action) {\r\n this.forEachChild(function (child) {\r\n if (child.getValue() !== null)\r\n action(child);\r\n else\r\n child.forEachImmediateDescendantWithValue(action);\r\n });\r\n };\r\n /**\r\n * @return {!Path} The path of this tree node, as a Path.\r\n */\r\n Tree.prototype.path = function () {\r\n return new Path(this.parent_ === null\r\n ? this.name_\r\n : this.parent_.path() + '/' + this.name_);\r\n };\r\n /**\r\n * @return {string} The name of the tree node.\r\n */\r\n Tree.prototype.name = function () {\r\n return this.name_;\r\n };\r\n /**\r\n * @return {?Tree} The parent tree node, or null if this is the root of the tree.\r\n */\r\n Tree.prototype.parent = function () {\r\n return this.parent_;\r\n };\r\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 */\r\n Tree.prototype.updateParents_ = function () {\r\n if (this.parent_ !== null)\r\n this.parent_.updateChild_(this.name_, this);\r\n };\r\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 */\r\n Tree.prototype.updateChild_ = function (childName, child) {\r\n var childEmpty = child.isEmpty();\r\n var childExists = contains(this.node_.children, childName);\r\n if (childEmpty && childExists) {\r\n delete this.node_.children[childName];\r\n this.node_.childCount--;\r\n this.updateParents_();\r\n }\r\n else if (!childEmpty && !childExists) {\r\n this.node_.children[childName] = child.node_;\r\n this.node_.childCount++;\r\n this.updateParents_();\r\n }\r\n };\r\n return Tree;\r\n}());\n\n/**\r\n * @license\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 */\r\n// TODO: This is pretty messy. Ideally, a lot of this would move into FirebaseData, or a transaction-specific\r\n// component used by FirebaseData, but it has ties to user callbacks (transaction update and onComplete) as well\r\n// as the realtime connection (to send transactions to the server). So that all needs to be decoupled first.\r\n// For now it's part of Repo, but in its own file.\r\n/**\r\n * @enum {number}\r\n */\r\nvar TransactionStatus;\r\n(function (TransactionStatus) {\r\n // We've run the transaction and updated transactionResultData_ with the result, but it isn't currently sent to the\r\n // server. A transaction will go from RUN -> SENT -> RUN if it comes back from the server as rejected due to\r\n // mismatched hash.\r\n TransactionStatus[TransactionStatus[\"RUN\"] = 0] = \"RUN\";\r\n // We've run the transaction and sent it to the server and it's currently outstanding (hasn't come back as accepted\r\n // or rejected yet).\r\n TransactionStatus[TransactionStatus[\"SENT\"] = 1] = \"SENT\";\r\n // Temporary state used to mark completed transactions (whether successful or aborted). The transaction will be\r\n // removed when we get a chance to prune completed ones.\r\n TransactionStatus[TransactionStatus[\"COMPLETED\"] = 2] = \"COMPLETED\";\r\n // Used when an already-sent transaction needs to be aborted (e.g. due to a conflicting set() call that was made).\r\n // If it comes back as unsuccessful, we'll abort it.\r\n TransactionStatus[TransactionStatus[\"SENT_NEEDS_ABORT\"] = 3] = \"SENT_NEEDS_ABORT\";\r\n // Temporary state used to mark transactions that need to be aborted.\r\n TransactionStatus[TransactionStatus[\"NEEDS_ABORT\"] = 4] = \"NEEDS_ABORT\";\r\n})(TransactionStatus || (TransactionStatus = {}));\r\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 */\r\nRepo.MAX_TRANSACTION_RETRIES_ = 25;\r\n/**\r\n * Setup the transaction data structures\r\n * @private\r\n */\r\nRepo.prototype.transactions_init_ = function () {\r\n /**\r\n * Stores queues of outstanding transactions for Firebase locations.\r\n *\r\n * @type {!Tree.>}\r\n * @private\r\n */\r\n this.transactionQueueTree_ = new Tree();\r\n};\r\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 */\r\nRepo.prototype.startTransaction = function (path, transactionUpdate, onComplete, applyLocally) {\r\n this.log_('transaction on ' + path);\r\n // Add a watch to make sure we get server updates.\r\n var valueCallback = function () { };\r\n var watchRef = new Reference(this, path);\r\n watchRef.on('value', valueCallback);\r\n var unwatcher = function () {\r\n watchRef.off('value', valueCallback);\r\n };\r\n // Initialize transaction.\r\n var transaction = {\r\n path: path,\r\n update: transactionUpdate,\r\n onComplete: onComplete,\r\n // One of TransactionStatus enums.\r\n status: null,\r\n // Used when combining transactions at different locations to figure out which one goes first.\r\n order: LUIDGenerator(),\r\n // Whether to raise local events for this transaction.\r\n applyLocally: applyLocally,\r\n // Count of how many times we've retried the transaction.\r\n retryCount: 0,\r\n // Function to call to clean up our .on() listener.\r\n unwatcher: unwatcher,\r\n // Stores why a transaction was aborted.\r\n abortReason: null,\r\n currentWriteId: null,\r\n currentInputSnapshot: null,\r\n currentOutputSnapshotRaw: null,\r\n currentOutputSnapshotResolved: null\r\n };\r\n // Run transaction initially.\r\n var currentState = this.getLatestState_(path);\r\n transaction.currentInputSnapshot = currentState;\r\n var newVal = transaction.update(currentState.val());\r\n if (newVal === undefined) {\r\n // Abort transaction.\r\n transaction.unwatcher();\r\n transaction.currentOutputSnapshotRaw = null;\r\n transaction.currentOutputSnapshotResolved = null;\r\n if (transaction.onComplete) {\r\n // We just set the input snapshot, so this cast should be safe\r\n var snapshot = new DataSnapshot(transaction.currentInputSnapshot, new Reference(this, transaction.path), PRIORITY_INDEX);\r\n transaction.onComplete(null, false, snapshot);\r\n }\r\n }\r\n else {\r\n validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path);\r\n // Mark as run and add to our queue.\r\n transaction.status = TransactionStatus.RUN;\r\n var queueNode = this.transactionQueueTree_.subTree(path);\r\n var nodeQueue = queueNode.getValue() || [];\r\n nodeQueue.push(transaction);\r\n queueNode.setValue(nodeQueue);\r\n // Update visibleData and raise events\r\n // Note: We intentionally raise events after updating all of our transaction state, since the user could\r\n // start new transactions from the event callbacks.\r\n var priorityForNode = void 0;\r\n if (typeof newVal === 'object' &&\r\n newVal !== null &&\r\n contains(newVal, '.priority')) {\r\n priorityForNode = safeGet(newVal, '.priority');\r\n assert(isValidPriority(priorityForNode), 'Invalid priority returned by transaction. ' +\r\n 'Priority must be a valid string, finite number, server value, or null.');\r\n }\r\n else {\r\n var currentNode = this.serverSyncTree_.calcCompleteEventCache(path) ||\r\n ChildrenNode.EMPTY_NODE;\r\n priorityForNode = currentNode.getPriority().val();\r\n }\r\n priorityForNode /** @type {null|number|string} */ = priorityForNode;\r\n var serverValues = this.generateServerValues();\r\n var newNodeUnresolved = nodeFromJSON$1(newVal, priorityForNode);\r\n var newNode = resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);\r\n transaction.currentOutputSnapshotRaw = newNodeUnresolved;\r\n transaction.currentOutputSnapshotResolved = newNode;\r\n transaction.currentWriteId = this.getNextWriteId_();\r\n var events = this.serverSyncTree_.applyUserOverwrite(path, newNode, transaction.currentWriteId, transaction.applyLocally);\r\n this.eventQueue_.raiseEventsForChangedPath(path, events);\r\n this.sendReadyTransactions_();\r\n }\r\n};\r\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 */\r\nRepo.prototype.getLatestState_ = function (path, excludeSets) {\r\n return (this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) ||\r\n ChildrenNode.EMPTY_NODE);\r\n};\r\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 */\r\nRepo.prototype.sendReadyTransactions_ = function (node) {\r\n var _this = this;\r\n if (node === void 0) { node = this.transactionQueueTree_; }\r\n // Before recursing, make sure any completed transactions are removed.\r\n if (!node) {\r\n this.pruneCompletedTransactionsBelowNode_(node);\r\n }\r\n if (node.getValue() !== null) {\r\n var queue = this.buildTransactionQueue_(node);\r\n assert(queue.length > 0, 'Sending zero length transaction queue');\r\n var allRun = queue.every(function (transaction) { return transaction.status === TransactionStatus.RUN; });\r\n // If they're all run (and not sent), we can send them. Else, we must wait.\r\n if (allRun) {\r\n this.sendTransactionQueue_(node.path(), queue);\r\n }\r\n }\r\n else if (node.hasChildren()) {\r\n node.forEachChild(function (childNode) {\r\n _this.sendReadyTransactions_(childNode);\r\n });\r\n }\r\n};\r\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 */\r\nRepo.prototype.sendTransactionQueue_ = function (path, queue) {\r\n var _this = this;\r\n // Mark transactions as sent and increment retry count!\r\n var setsToIgnore = queue.map(function (txn) {\r\n return txn.currentWriteId;\r\n });\r\n var latestState = this.getLatestState_(path, setsToIgnore);\r\n var snapToSend = latestState;\r\n var latestHash = latestState.hash();\r\n for (var i = 0; i < queue.length; i++) {\r\n var txn = queue[i];\r\n assert(txn.status === TransactionStatus.RUN, 'tryToSendTransactionQueue_: items in queue should all be run.');\r\n txn.status = TransactionStatus.SENT;\r\n txn.retryCount++;\r\n var relativePath = Path.relativePath(path, txn.path);\r\n // If we've gotten to this point, the output snapshot must be defined.\r\n snapToSend = snapToSend.updateChild(relativePath /**@type {!Node} */, txn.currentOutputSnapshotRaw);\r\n }\r\n var dataToSend = snapToSend.val(true);\r\n var pathToSend = path;\r\n // Send the put.\r\n this.server_.put(pathToSend.toString(), dataToSend, function (status) {\r\n _this.log_('transaction put response', {\r\n path: pathToSend.toString(),\r\n status: status\r\n });\r\n var events = [];\r\n if (status === 'ok') {\r\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\r\n // the callback could trigger more transactions or sets.\r\n var callbacks = [];\r\n for (var i = 0; i < queue.length; i++) {\r\n queue[i].status = TransactionStatus.COMPLETED;\r\n events = events.concat(_this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId));\r\n if (queue[i].onComplete) {\r\n // We never unset the output snapshot, and given that this transaction is complete, it should be set\r\n var node = queue[i].currentOutputSnapshotResolved;\r\n var ref = new Reference(_this, queue[i].path);\r\n var snapshot = new DataSnapshot(node, ref, PRIORITY_INDEX);\r\n callbacks.push(queue[i].onComplete.bind(null, null, true, snapshot));\r\n }\r\n queue[i].unwatcher();\r\n }\r\n // Now remove the completed transactions.\r\n _this.pruneCompletedTransactionsBelowNode_(_this.transactionQueueTree_.subTree(path));\r\n // There may be pending transactions that we can now send.\r\n _this.sendReadyTransactions_();\r\n _this.eventQueue_.raiseEventsForChangedPath(path, events);\r\n // Finally, trigger onComplete callbacks.\r\n for (var i = 0; i < callbacks.length; i++) {\r\n exceptionGuard(callbacks[i]);\r\n }\r\n }\r\n else {\r\n // transactions are no longer sent. Update their status appropriately.\r\n if (status === 'datastale') {\r\n for (var i = 0; i < queue.length; i++) {\r\n if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT)\r\n queue[i].status = TransactionStatus.NEEDS_ABORT;\r\n else\r\n queue[i].status = TransactionStatus.RUN;\r\n }\r\n }\r\n else {\r\n warn('transaction at ' + pathToSend.toString() + ' failed: ' + status);\r\n for (var i = 0; i < queue.length; i++) {\r\n queue[i].status = TransactionStatus.NEEDS_ABORT;\r\n queue[i].abortReason = status;\r\n }\r\n }\r\n _this.rerunTransactions_(path);\r\n }\r\n }, latestHash);\r\n};\r\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 */\r\nRepo.prototype.rerunTransactions_ = function (changedPath) {\r\n var rootMostTransactionNode = this.getAncestorTransactionNode_(changedPath);\r\n var path = rootMostTransactionNode.path();\r\n var queue = this.buildTransactionQueue_(rootMostTransactionNode);\r\n this.rerunTransactionQueue_(queue, path);\r\n return path;\r\n};\r\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 */\r\nRepo.prototype.rerunTransactionQueue_ = function (queue, path) {\r\n if (queue.length === 0) {\r\n return; // Nothing to do!\r\n }\r\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\r\n // the callback could trigger more transactions or sets.\r\n var callbacks = [];\r\n var events = [];\r\n // Ignore all of the sets we're going to re-run.\r\n var txnsToRerun = queue.filter(function (q) {\r\n return q.status === TransactionStatus.RUN;\r\n });\r\n var setsToIgnore = txnsToRerun.map(function (q) {\r\n return q.currentWriteId;\r\n });\r\n for (var i = 0; i < queue.length; i++) {\r\n var transaction = queue[i];\r\n var relativePath = Path.relativePath(path, transaction.path);\r\n var abortTransaction = false, abortReason = void 0;\r\n assert(relativePath !== null, 'rerunTransactionsUnderNode_: relativePath should not be null.');\r\n if (transaction.status === TransactionStatus.NEEDS_ABORT) {\r\n abortTransaction = true;\r\n abortReason = transaction.abortReason;\r\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\r\n }\r\n else if (transaction.status === TransactionStatus.RUN) {\r\n if (transaction.retryCount >= Repo.MAX_TRANSACTION_RETRIES_) {\r\n abortTransaction = true;\r\n abortReason = 'maxretry';\r\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\r\n }\r\n else {\r\n // This code reruns a transaction\r\n var currentNode = this.getLatestState_(transaction.path, setsToIgnore);\r\n transaction.currentInputSnapshot = currentNode;\r\n var newData = queue[i].update(currentNode.val());\r\n if (newData !== undefined) {\r\n validateFirebaseData('transaction failed: Data returned ', newData, transaction.path);\r\n var newDataNode = nodeFromJSON$1(newData);\r\n var hasExplicitPriority = typeof newData === 'object' &&\r\n newData != null &&\r\n contains(newData, '.priority');\r\n if (!hasExplicitPriority) {\r\n // Keep the old priority if there wasn't a priority explicitly specified.\r\n newDataNode = newDataNode.updatePriority(currentNode.getPriority());\r\n }\r\n var oldWriteId = transaction.currentWriteId;\r\n var serverValues = this.generateServerValues();\r\n var newNodeResolved = resolveDeferredValueSnapshot(newDataNode, serverValues);\r\n transaction.currentOutputSnapshotRaw = newDataNode;\r\n transaction.currentOutputSnapshotResolved = newNodeResolved;\r\n transaction.currentWriteId = this.getNextWriteId_();\r\n // Mutates setsToIgnore in place\r\n setsToIgnore.splice(setsToIgnore.indexOf(oldWriteId), 1);\r\n events = events.concat(this.serverSyncTree_.applyUserOverwrite(transaction.path, newNodeResolved, transaction.currentWriteId, transaction.applyLocally));\r\n events = events.concat(this.serverSyncTree_.ackUserWrite(oldWriteId, true));\r\n }\r\n else {\r\n abortTransaction = true;\r\n abortReason = 'nodata';\r\n events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));\r\n }\r\n }\r\n }\r\n this.eventQueue_.raiseEventsForChangedPath(path, events);\r\n events = [];\r\n if (abortTransaction) {\r\n // Abort.\r\n queue[i].status = TransactionStatus.COMPLETED;\r\n // Removing a listener can trigger pruning which can muck with mergedData/visibleData (as it prunes data).\r\n // So defer the unwatcher until we're done.\r\n (function (unwatcher) {\r\n setTimeout(unwatcher, Math.floor(0));\r\n })(queue[i].unwatcher);\r\n if (queue[i].onComplete) {\r\n if (abortReason === 'nodata') {\r\n var ref = new Reference(this, queue[i].path);\r\n // We set this field immediately, so it's safe to cast to an actual snapshot\r\n var lastInput /** @type {!Node} */ = queue[i].currentInputSnapshot;\r\n var snapshot = new DataSnapshot(lastInput, ref, PRIORITY_INDEX);\r\n callbacks.push(queue[i].onComplete.bind(null, null, false, snapshot));\r\n }\r\n else {\r\n callbacks.push(queue[i].onComplete.bind(null, new Error(abortReason), false, null));\r\n }\r\n }\r\n }\r\n }\r\n // Clean up completed transactions.\r\n this.pruneCompletedTransactionsBelowNode_(this.transactionQueueTree_);\r\n // Now fire callbacks, now that we're in a good, known state.\r\n for (var i = 0; i < callbacks.length; i++) {\r\n exceptionGuard(callbacks[i]);\r\n }\r\n // Try to send the transaction result to the server.\r\n this.sendReadyTransactions_();\r\n};\r\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 */\r\nRepo.prototype.getAncestorTransactionNode_ = function (path) {\r\n var front;\r\n // Start at the root and walk deeper into the tree towards path until we find a node with pending transactions.\r\n var transactionNode = this.transactionQueueTree_;\r\n while ((front = path.getFront()) !== null &&\r\n transactionNode.getValue() === null) {\r\n transactionNode = transactionNode.subTree(front);\r\n path = path.popFront();\r\n }\r\n return transactionNode;\r\n};\r\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 */\r\nRepo.prototype.buildTransactionQueue_ = function (transactionNode) {\r\n // Walk any child transaction queues and aggregate them into a single queue.\r\n var transactionQueue = [];\r\n this.aggregateTransactionQueuesForNode_(transactionNode, transactionQueue);\r\n // Sort them by the order the transactions were created.\r\n transactionQueue.sort(function (a, b) {\r\n return a.order - b.order;\r\n });\r\n return transactionQueue;\r\n};\r\n/**\r\n * @param {!Tree.>} node\r\n * @param {Array.} queue\r\n * @private\r\n */\r\nRepo.prototype.aggregateTransactionQueuesForNode_ = function (node, queue) {\r\n var _this = this;\r\n var nodeQueue = node.getValue();\r\n if (nodeQueue !== null) {\r\n for (var i = 0; i < nodeQueue.length; i++) {\r\n queue.push(nodeQueue[i]);\r\n }\r\n }\r\n node.forEachChild(function (child) {\r\n _this.aggregateTransactionQueuesForNode_(child, queue);\r\n });\r\n};\r\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 */\r\nRepo.prototype.pruneCompletedTransactionsBelowNode_ = function (node) {\r\n var _this = this;\r\n var queue = node.getValue();\r\n if (queue) {\r\n var to = 0;\r\n for (var from = 0; from < queue.length; from++) {\r\n if (queue[from].status !== TransactionStatus.COMPLETED) {\r\n queue[to] = queue[from];\r\n to++;\r\n }\r\n }\r\n queue.length = to;\r\n node.setValue(queue.length > 0 ? queue : null);\r\n }\r\n node.forEachChild(function (childNode) {\r\n _this.pruneCompletedTransactionsBelowNode_(childNode);\r\n });\r\n};\r\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 */\r\nRepo.prototype.abortTransactions_ = function (path) {\r\n var _this = this;\r\n var affectedPath = this.getAncestorTransactionNode_(path).path();\r\n var transactionNode = this.transactionQueueTree_.subTree(path);\r\n transactionNode.forEachAncestor(function (node) {\r\n _this.abortTransactionsOnNode_(node);\r\n });\r\n this.abortTransactionsOnNode_(transactionNode);\r\n transactionNode.forEachDescendant(function (node) {\r\n _this.abortTransactionsOnNode_(node);\r\n });\r\n return affectedPath;\r\n};\r\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 */\r\nRepo.prototype.abortTransactionsOnNode_ = function (node) {\r\n var queue = node.getValue();\r\n if (queue !== null) {\r\n // Queue up the callbacks and fire them after cleaning up all of our transaction state, since\r\n // the callback could trigger more transactions or sets.\r\n var callbacks = [];\r\n // Go through queue. Any already-sent transactions must be marked for abort, while the unsent ones\r\n // can be immediately aborted and removed.\r\n var events = [];\r\n var lastSent = -1;\r\n for (var i = 0; i < queue.length; i++) {\r\n if (queue[i].status === TransactionStatus.SENT_NEEDS_ABORT) ;\r\n else if (queue[i].status === TransactionStatus.SENT) {\r\n assert(lastSent === i - 1, 'All SENT items should be at beginning of queue.');\r\n lastSent = i;\r\n // Mark transaction for abort when it comes back.\r\n queue[i].status = TransactionStatus.SENT_NEEDS_ABORT;\r\n queue[i].abortReason = 'set';\r\n }\r\n else {\r\n assert(queue[i].status === TransactionStatus.RUN, 'Unexpected transaction status in abort');\r\n // We can abort it immediately.\r\n queue[i].unwatcher();\r\n events = events.concat(this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId, true));\r\n if (queue[i].onComplete) {\r\n var snapshot = null;\r\n callbacks.push(queue[i].onComplete.bind(null, new Error('set'), false, snapshot));\r\n }\r\n }\r\n }\r\n if (lastSent === -1) {\r\n // We're not waiting for any sent transactions. We can clear the queue.\r\n node.setValue(null);\r\n }\r\n else {\r\n // Remove the transactions we aborted.\r\n queue.length = lastSent + 1;\r\n }\r\n // Now fire the callbacks.\r\n this.eventQueue_.raiseEventsForChangedPath(node.path(), events);\r\n for (var i = 0; i < callbacks.length; i++) {\r\n exceptionGuard(callbacks[i]);\r\n }\r\n }\r\n};\n\n/**\r\n * @license\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 */\r\n/** @const {string} */\r\nvar DATABASE_URL_OPTION = 'databaseURL';\r\nvar _staticInstance;\r\n/**\r\n * Creates and caches Repo instances.\r\n */\r\nvar RepoManager = /** @class */ (function () {\r\n function RepoManager() {\r\n /**\r\n * @private {!Object.>}\r\n */\r\n this.repos_ = {};\r\n /**\r\n * If true, new Repos will be created to use ReadonlyRestClient (for testing purposes).\r\n * @private {boolean}\r\n */\r\n this.useRestClient_ = false;\r\n }\r\n RepoManager.getInstance = function () {\r\n if (!_staticInstance) {\r\n _staticInstance = new RepoManager();\r\n }\r\n return _staticInstance;\r\n };\r\n // TODO(koss): Remove these functions unless used in tests?\r\n RepoManager.prototype.interrupt = function () {\r\n for (var appName in this.repos_) {\r\n for (var dbUrl in this.repos_[appName]) {\r\n this.repos_[appName][dbUrl].interrupt();\r\n }\r\n }\r\n };\r\n RepoManager.prototype.resume = function () {\r\n for (var appName in this.repos_) {\r\n for (var dbUrl in this.repos_[appName]) {\r\n this.repos_[appName][dbUrl].resume();\r\n }\r\n }\r\n };\r\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 */\r\n RepoManager.prototype.databaseFromApp = function (app, url) {\r\n var dbUrl = url || app.options[DATABASE_URL_OPTION];\r\n if (dbUrl === undefined) {\r\n fatal(\"Can't determine Firebase Database URL. Be sure to include \" +\r\n DATABASE_URL_OPTION +\r\n ' option when calling firebase.initializeApp().');\r\n }\r\n var parsedUrl = parseRepoInfo(dbUrl);\r\n var repoInfo = parsedUrl.repoInfo;\r\n validateUrl('Invalid Firebase Database URL', 1, parsedUrl);\r\n if (!parsedUrl.path.isEmpty()) {\r\n fatal('Database URL must point to the root of a Firebase Database ' +\r\n '(not including a child path).');\r\n }\r\n var repo = this.createRepo(repoInfo, app);\r\n return repo.database;\r\n };\r\n /**\r\n * Remove the repo and make sure it is disconnected.\r\n *\r\n * @param {!Repo} repo\r\n */\r\n RepoManager.prototype.deleteRepo = function (repo) {\r\n var appRepos = safeGet(this.repos_, repo.app.name);\r\n // This should never happen...\r\n if (!appRepos || safeGet(appRepos, repo.repoInfo_.toURLString()) !== repo) {\r\n fatal(\"Database \" + repo.app.name + \"(\" + repo.repoInfo_ + \") has already been deleted.\");\r\n }\r\n repo.interrupt();\r\n delete appRepos[repo.repoInfo_.toURLString()];\r\n };\r\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 */\r\n RepoManager.prototype.createRepo = function (repoInfo, app) {\r\n var appRepos = safeGet(this.repos_, app.name);\r\n if (!appRepos) {\r\n appRepos = {};\r\n this.repos_[app.name] = appRepos;\r\n }\r\n var repo = safeGet(appRepos, repoInfo.toURLString());\r\n if (repo) {\r\n fatal('Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.');\r\n }\r\n repo = new Repo(repoInfo, this.useRestClient_, app);\r\n appRepos[repoInfo.toURLString()] = repo;\r\n return repo;\r\n };\r\n /**\r\n * Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.\r\n * @param {boolean} forceRestClient\r\n */\r\n RepoManager.prototype.forceRestClient = function (forceRestClient) {\r\n this.useRestClient_ = forceRestClient;\r\n };\r\n return RepoManager;\r\n}());\n\n/**\r\n * @license\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 */\r\n/**\r\n * Class representing a firebase database.\r\n * @implements {FirebaseService}\r\n */\r\nvar Database = /** @class */ (function () {\r\n /**\r\n * The constructor should not be called by users of our public API.\r\n * @param {!Repo} repo_\r\n */\r\n function Database(repo_) {\r\n this.repo_ = repo_;\r\n if (!(repo_ instanceof Repo)) {\r\n fatal(\"Don't call new Database() directly - please use firebase.database().\");\r\n }\r\n /** @type {Reference} */\r\n this.root_ = new Reference(repo_, Path.Empty);\r\n this.INTERNAL = new DatabaseInternals(this);\r\n }\r\n Object.defineProperty(Database.prototype, \"app\", {\r\n get: function () {\r\n return this.repo_.app;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n Database.prototype.ref = function (path) {\r\n this.checkDeleted_('ref');\r\n validateArgCount('database.ref', 0, 1, arguments.length);\r\n if (path instanceof Reference) {\r\n return this.refFromURL(path.toString());\r\n }\r\n return path !== undefined ? this.root_.child(path) : this.root_;\r\n };\r\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 */\r\n Database.prototype.refFromURL = function (url) {\r\n /** @const {string} */\r\n var apiName = 'database.refFromURL';\r\n this.checkDeleted_(apiName);\r\n validateArgCount(apiName, 1, 1, arguments.length);\r\n var parsedURL = parseRepoInfo(url);\r\n validateUrl(apiName, 1, parsedURL);\r\n var repoInfo = parsedURL.repoInfo;\r\n if (repoInfo.host !== this.repo_.repoInfo_.host) {\r\n fatal(apiName +\r\n ': Host name does not match the current database: ' +\r\n '(found ' +\r\n repoInfo.host +\r\n ' but expected ' +\r\n this.repo_.repoInfo_.host +\r\n ')');\r\n }\r\n return this.ref(parsedURL.path.toString());\r\n };\r\n /**\r\n * @param {string} apiName\r\n */\r\n Database.prototype.checkDeleted_ = function (apiName) {\r\n if (this.repo_ === null) {\r\n fatal('Cannot call ' + apiName + ' on a deleted database.');\r\n }\r\n };\r\n // Make individual repo go offline.\r\n Database.prototype.goOffline = function () {\r\n validateArgCount('database.goOffline', 0, 0, arguments.length);\r\n this.checkDeleted_('goOffline');\r\n this.repo_.interrupt();\r\n };\r\n Database.prototype.goOnline = function () {\r\n validateArgCount('database.goOnline', 0, 0, arguments.length);\r\n this.checkDeleted_('goOnline');\r\n this.repo_.resume();\r\n };\r\n Database.ServerValue = {\r\n TIMESTAMP: {\r\n '.sv': 'timestamp'\r\n }\r\n };\r\n return Database;\r\n}());\r\nvar DatabaseInternals = /** @class */ (function () {\r\n /** @param {!Database} database */\r\n function DatabaseInternals(database) {\r\n this.database = database;\r\n }\r\n /** @return {Promise} */\r\n DatabaseInternals.prototype.delete = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n this.database.checkDeleted_('delete');\r\n RepoManager.getInstance().deleteRepo(this.database.repo_);\r\n this.database.repo_ = null;\r\n this.database.root_ = null;\r\n this.database.INTERNAL = null;\r\n this.database = null;\r\n return [2 /*return*/];\r\n });\r\n });\r\n };\r\n return DatabaseInternals;\r\n}());\n\n/**\r\n * @license\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 */\r\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 */\r\nvar forceLongPolling = function () {\r\n WebSocketConnection.forceDisallow();\r\n BrowserPollConnection.forceAllow();\r\n};\r\nvar forceWebSockets = function () {\r\n BrowserPollConnection.forceDisallow();\r\n};\r\n/* Used by App Manager */\r\nvar isWebSocketsAvailable = function () {\r\n return WebSocketConnection['isAvailable']();\r\n};\r\nvar setSecurityDebugCallback = function (ref, callback) {\r\n ref.repo.persistentConnection_.securityDebugCallback_ = callback;\r\n};\r\nvar stats = function (ref, showDelta) {\r\n ref.repo.stats(showDelta);\r\n};\r\nvar statsIncrementCounter = function (ref, metric) {\r\n ref.repo.statsIncrementCounter(metric);\r\n};\r\nvar dataUpdateCount = function (ref) {\r\n return ref.repo.dataUpdateCount;\r\n};\r\nvar interceptServerData = function (ref, callback) {\r\n return ref.repo.interceptServerData_(callback);\r\n};\n\nvar INTERNAL = /*#__PURE__*/Object.freeze({\n forceLongPolling: forceLongPolling,\n forceWebSockets: forceWebSockets,\n isWebSocketsAvailable: isWebSocketsAvailable,\n setSecurityDebugCallback: setSecurityDebugCallback,\n stats: stats,\n statsIncrementCounter: statsIncrementCounter,\n dataUpdateCount: dataUpdateCount,\n interceptServerData: interceptServerData\n});\n\n/**\r\n * @license\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 */\r\nvar DataConnection = PersistentConnection;\r\n/**\r\n * @param {!string} pathString\r\n * @param {function(*)} onComplete\r\n */\r\nPersistentConnection.prototype.simpleListen = function (pathString, onComplete) {\r\n this.sendRequest('q', { p: pathString }, onComplete);\r\n};\r\n/**\r\n * @param {*} data\r\n * @param {function(*)} onEcho\r\n */\r\nPersistentConnection.prototype.echo = function (data, onEcho) {\r\n this.sendRequest('echo', { d: data }, onEcho);\r\n};\r\n// RealTimeConnection properties that we use in tests.\r\nvar RealTimeConnection = Connection;\r\n/**\r\n * @param {function(): string} newHash\r\n * @return {function()}\r\n */\r\nvar hijackHash = function (newHash) {\r\n var oldPut = PersistentConnection.prototype.put;\r\n PersistentConnection.prototype.put = function (pathString, data, opt_onComplete, opt_hash) {\r\n if (opt_hash !== undefined) {\r\n opt_hash = newHash();\r\n }\r\n oldPut.call(this, pathString, data, opt_onComplete, opt_hash);\r\n };\r\n return function () {\r\n PersistentConnection.prototype.put = oldPut;\r\n };\r\n};\r\n/**\r\n * @type {function(new:RepoInfo, !string, boolean, !string, boolean): undefined}\r\n */\r\nvar ConnectionTarget = RepoInfo;\r\n/**\r\n * @param {!Query} query\r\n * @return {!string}\r\n */\r\nvar queryIdentifier = function (query) {\r\n return query.queryIdentifier();\r\n};\r\n/**\r\n * @param {!Query} firebaseRef\r\n * @return {!Object}\r\n */\r\nvar listens = function (firebaseRef) {\r\n return firebaseRef.repo.persistentConnection_.listens_;\r\n};\r\n/**\r\n * Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.\r\n *\r\n * @param {boolean} forceRestClient\r\n */\r\nvar forceRestClient = function (forceRestClient) {\r\n RepoManager.getInstance().forceRestClient(forceRestClient);\r\n};\n\nvar TEST_ACCESS = /*#__PURE__*/Object.freeze({\n DataConnection: DataConnection,\n RealTimeConnection: RealTimeConnection,\n hijackHash: hijackHash,\n ConnectionTarget: ConnectionTarget,\n queryIdentifier: queryIdentifier,\n listens: listens,\n forceRestClient: forceRestClient\n});\n\n/**\r\n * @license\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 */\r\nvar ServerValue = Database.ServerValue;\r\nfunction registerDatabase(instance) {\r\n // Register the Database Service with the 'firebase' namespace.\r\n var namespace = instance.INTERNAL.registerService('database', function (app, unused, url) { return RepoManager.getInstance().databaseFromApp(app, url); }, \r\n // firebase.database namespace properties\r\n {\r\n Reference: Reference,\r\n Query: Query,\r\n Database: Database,\r\n enableLogging: enableLogging,\r\n INTERNAL: INTERNAL,\r\n ServerValue: ServerValue,\r\n TEST_ACCESS: TEST_ACCESS\r\n }, null, true);\r\n if (isNodeSdk()) {\r\n module.exports = namespace;\r\n }\r\n}\r\nregisterDatabase(firebase);\n\nexport { registerDatabase, Database, Query, Reference, enableLogging, ServerValue, DataSnapshot, OnDisconnect };\n"],"names":["extendStatics","Object","setPrototypeOf","__proto__","Array","d","b","p","hasOwnProperty","__extends","__","this","constructor","prototype","create","__generator","thisArg","body","f","y","t","g","_","label","sent","trys","ops","next","verb","throw","return","Symbol","iterator","n","v","op","TypeError","call","done","value","pop","length","push","e","step","CONSTANTS","assert","assertion","message","assertionError","Error","stringToByteArray","str","out","i","c","charCodeAt","base64","byteToCharMap_","charToByteMap_","byteToCharMapWebSafe_","charToByteMapWebSafe_","ENCODED_VALS_BASE","ENCODED_VALS","ENCODED_VALS_WEBSAFE","HAS_NATIVE_SUPPORT","atob","encodeByteArray","input","opt_webSafe","isArray","init_","byteToCharMap","output","byte1","haveByte2","byte2","haveByte3","byte3","outByte1","outByte2","outByte3","outByte4","join","encodeString","btoa","decodeString","bytes","pos","c1","String","fromCharCode","c2","u","c3","byteArrayToString","decodeStringToByteArray","charToByteMap","charAt","byte4","base64Decode","console","error","deepCopy","deepExtend","target","source","Date","dateValue","getTime","undefined","prop","Deferred","_this","promise","Promise","resolve","reject","wrapCallback","callback","catch","isMobileCordova","window","test","navigator","isNodeSdk","ERROR_NAME","captureStackTrace","FirebaseError","code","ErrorFactory","apply","arguments","err","name","defineProperty","get","stack","service","serviceName","errors","pattern","data","template","fullCode","replace","match","key","toString","slice","jsonEval","JSON","parse","stringify","decode","token","header","claims","signature","parts","split","contains","obj","safeGet","forEach","fn","clone","objTo","isEmpty","getCount","rv","map","opt_obj","res","findKey","opt_this","getAnyKey","Sha1","_super","chain_","buf_","W_","pad_","inbuf_","total_","blockSize","reset","compress_","buf","opt_offset","W","k","a","update","opt_length","lengthMinusBlock","inbuf","digest","totalBits","j","validateArgCount","fnName","minCount","maxCount","argCount","argError","errorPrefix","argumentNumber","optional","argName","validateCallback","validateContextObject","context","LogLevel","stringLength","id","defaultLogLevel","INFO","defaultLogHandler","instance","logType","args","_i","logLevel","now","toISOString","DEBUG","VERBOSE","log","concat","info","WARN","warn","ERROR","Logger","_logLevel","_logHandler","set","val","enumerable","configurable","debug","DOMStorageWrapper","domStorage_","prefix_","removeItem","prefixedName_","setItem","storedVal","getItem","remove","MemoryStorage","cache_","isInMemoryStorage","createStoragefor","domStorageName","domStorage","PersistentStorage","SessionStorage","logClient","LUIDGenerator","sha1","utf8Bytes","high","sha1Bytes","buildLogMessage_","var_args","logger","firstLog_","enableLogging","logger_","persistent","bind","logWrapper","prefix","fatal","isInvalidJSONNumber","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","MIN_NAME","MAX_NAME","nameCompare","aAsInt","tryParseInt","bAsInt","stringCompare","requireKey","ObjectToUniqueKey","keys","sort","splitStringBySize","segsize","len","dataSegs","substring","each","doubleToIEEE754String","s","ln","bits","Infinity","Math","abs","pow","min","floor","LN2","round","reverse","hexByteString","hexByte","parseInt","substr","toLowerCase","INTEGER_REGEXP_","RegExp","intVal","exceptionGuard","setTimeout","setTimeoutNonBlocking","time","timeout","Path","pathOrString","pieceNum","pieces_","copyTo","pieceNum_","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","ValidationPath","path","errorPrefix_","parts_","byteLength_","max","checkValid_","last","MAX_PATH_LENGTH_BYTES","MAX_PATH_DEPTH","toErrorString","FORGE_DOMAIN","WEBSOCKET","LONG_POLLING","RepoInfo","host","secure","namespace","webSocketOnly","persistenceKey","domain","indexOf","internalHost","needsQueryParam","isCustomHost","isCacheableHost","isDemoHost","updateHost","newHost","connectionURL","type","params","connURL","pairs","toURLString","PUSH_CHARS","lastPushTime","lastRandChars","__EMPTY_NODE","MAX_NODE","parseRepoInfo","dataURL","parsedUrl","parseURL","subdomain","location","protocol","scheme","repoInfo","port","colonInd","slashInd","questionMarkInd","pathStringDecoded","piece","decodeURIComponent","decodePath","queryParams","queryString","results","_a","segment","kv","decodeQuery","INVALID_KEY_REGEX_","INVALID_PATH_REGEX_","MAX_LEAF_SIZE_","isValidKey","isValidPathString","isValidPriority","priority","validateFirebaseDataArg","validateFirebaseData","path_","hasDotValue_1","hasActualChild_1","validateFirebaseMergeDataArg","errorPrefix$1","mergePaths","curPath","prevPath","validateFirebaseMergePaths","validatePriority","validateEventType","eventType","validateKey","validatePathString","validateWritablePath","validateUrl","OnDisconnect","repo_","cancel","onComplete","deferred","onDisconnectCancel","onDisconnectSet","setWithPriority","onDisconnectSetWithPriority","objectToMerge","newObjectToMerge","onDisconnectUpdate","TransactionResult","committed","snapshot","toJSON","nextPushId","duplicateTime","timeStampChars","random","NamedNode","node","Wrap","Index","getCompare","compare","indexedValueChanged","oldNode","newNode","oldWrapped","newWrapped","minPost","MIN","KeyIndex","isDefinedOn","maxPost","makePost","indexValue","KEY_INDEX","__childrenNodeConstructor","nodeFromJSON","MAX_NODE$1","priorityHashText","validatePriorityNode","priorityNode","isLeafNode","getPriority","LeafNode","value_","priorityNode_","EMPTY_NODE","lazyHash_","updatePriority","newPriorityNode","getImmediateChild","childName","getChild","hasChild","getPredecessorChildName","childNode","updateImmediateChild","newChildNode","updateChild","front","numChildren","forEachChild","index","action","exportFormat",".value","getValue",".priority","hash","toHash","compareTo","compareToLeafNode_","otherLeaf","otherLeafType","thisLeafType","otherIndex","VALUE_TYPE_ORDER","thisIndex","withIndex","isIndexed","_defaultIndexMap","PRIORITY_INDEX","PriorityIndex","aPriority","bPriority","indexCmp","SortedMapIterator","startKey","comparator","isReverse_","resultGenerator_","nodeStack_","getNext","result","hasNext","peek","LLRBNode","color","RED","SortedMap","copy","count","inorderTraversal","reverseTraversal","min_","minKey","maxKey","insert","fixUp_","removeMin_","isRed_","moveRedLeft_","smallest","rotateRight_","moveRedRight_","rotateLeft_","colorFlip_","nl","nr","checkMaxDepth_","blackDepth","check_","BLACK","LLRBEmptyNode","comparator_","root_","getPredecessorKey","rightParent","getIterator","resultGenerator","getIteratorFrom","getReverseIteratorFrom","getReverseIterator","LOG_2","Base12Num","num","current_","mask","bits_","nextBitIsOne","buildChildSet","childList","keyFn","mapSortFn","buildBalancedTree","low","namedNode","middle","root","base12","buildPennant","chunkSize","childTree","attachPennant","pennant","isOne","buildFrom12Array","fallbackObject","IndexMap","indexes_","indexSet_","indexKey","sortedMap","hasIndex","indexDefinition","addIndex","existingChildren","newIndex","sawIndexedValue","iter","indexName","newIndexSet","newIndexes","addToIndexes","indexedChildren","existingSnap","newChildren","removeFromIndexes","NAME_ONLY_COMPARATOR","NAME_COMPARATOR","ChildrenNode","children_","indexMap_","Default","newIndexMap","newImmediateChild","numKeys","allIntegerKeys","array","toHash_1","childHash","idx","resolveIndex_","predecessor","getFirstChildName","getFirstChild","getLastChildName","getLastChild","wrappedNode","startPost","endPost","MAX_NODE$2","otherChildrenNode","thisIter","otherIter","thisCurrent","otherCurrent","MaxNode","defineProperties","MAX","USE_HINZE","nodeFromJSON$1","json","node_1","jsonObj_1","childData","children_1","childrenHavePriority_1","hinzeJsonObj_1","childSet","sortedChildSet","__referenceConstructor","OperationType","VALUE_INDEX","ValueIndex","valueNode","PathIndex","indexPath_","extractChild","snap","aChild","bChild","DataSnapshot","node_","ref_","index_","exportVal","exists","childPathString","childPath","childRef","hasChildren","getKey","getRef","DataEvent","eventRegistration","prevName","getPath","ref","getParent","getEventType","getEventRunner","CancelEvent","ValueEventRegistration","callback_","cancelCallback_","context_","respondsTo","createEvent","change","query","getQueryParams","getIndex","snapshotNode","eventData","ctx","cancelCB_1","cb_1","createCancelEvent","matches","hasAnyCallback","ChildEventRegistration","callbacks_","eventToCheck","cancelCB_2","cb_2","otherCount","every","cb","otherKey","thisKey","Query","repo","queryParams_","orderByCalled_","validateQueryEndpoints_","startNode","endNode","hasStart","getIndexStartValue","hasEnd","getIndexEndValue","tooManyArgsError","wrongArgTypeError","getIndexStartName","getIndexEndName","validateLimit_","hasLimit","hasAnchoredLimit","validateNoPreviousOrderByCall_","on","cancelCallbackOrContext","ret","getCancelAndContextArgs_","onValueEvent","callbacks","onChildEvent","cancelCallback","container","addEventCallbackForQuery","off","removeEventCallbackForQuery","once","userCallback","cancelOrContext","firstCall","onceCallback","limitToFirst","limit","limitToLast","orderByChild","parsedPath","newParams","orderBy","orderByKey","orderByPriority","orderByValue","startAt","endAt","equalTo","queryObject","getQueryObject","queryIdentifier","isEqual","sameRepo","samePath","sameQueryIdentifier","CountedSet","add","item","clear","SparseSnapshotTree","find","childKey","remember","forget","self_1","tree","forEachTree","prefixPath","func","resolveDeferredValue","serverValues","resolveDeferredValueSnapshot","rawPri","leafNode","childrenNode","emptyChildrenSingleton","__referenceConstructor$1","OperationSource","fromUser","fromServer","queryId","tagged","User","Server","forServerTaggedQuery","AckUserWrite","affectedTree","revert","ACK_USER_WRITE","operationForChild","children","subtree","Empty","ImmutableTree","fromObject","childSnap","findRootMostMatchingPathAndValue","predicate","childExistingPathAndValue","findRootMostValueAndPath","toSet","newChild","setTree","newTree","fold","fold_","pathSoFar","accum","findOnPath","findOnPath_","pathToFollow","nextChild","foreachOnPath","foreachOnPath_","currentRelativePath","foreach","foreach_","foreachChild","ListenComplete","LISTEN_COMPLETE","Overwrite","OVERWRITE","Merge","MERGE","CacheNode","fullyInitialized_","filtered_","isFullyInitialized","isFiltered","isCompleteForPath","isCompleteForChild","getNode","ViewCache","eventCache_","serverCache_","updateEventSnap","eventSnap","complete","filtered","updateServerSnap","serverSnap","getEventCache","getCompleteEventSnap","getServerCache","getCompleteServerSnap","Change","oldSnap","valueChange","VALUE","childAddedChange","CHILD_ADDED","childRemovedChange","CHILD_REMOVED","childChangedChange","newSnapshot","oldSnapshot","CHILD_CHANGED","childMovedChange","CHILD_MOVED","IndexedFilter","affectedPath","optChangeAccumulator","oldChild","trackChildChange","updateFullNode","newSnap","newPriority","filtersNodes","getIndexedFilter","ChildChangeAccumulator","changeMap_","oldChange","oldType","getChanges","getValues","NO_COMPLETE_CHILD_SOURCE","NoCompleteChildSource_","getCompleteChild","getChildAfterChild","WriteTreeCompleteChildSource","writes_","viewCache_","optCompleteServerCache_","serverNode","calcCompleteChild","completeServerData","nodes","calcIndexedSlice","ProcessorResult","viewCache","changes","ViewProcessor","filter_","assertIndexed","applyOperation","oldViewCache","operation","writesCache","completeCache","newViewCache","filterServerNode","accumulator","overwrite","applyUserOverwrite_","applyServerOverwrite_","merge","applyUserMerge_","applyServerMerge_","ackUserWrite","revertUserWrite_","ackUserWrite_","listenComplete_","maybeAddValueEvent_","isLeafOrEmpty","oldCompleteSnap","generateEventCacheAfterServerEvent_","changePath","oldEventSnap","shadowingWrite","newEventCache","serverCache","completeChildren","completeEventChildren","calcCompleteEventChildren","completeNode","calcCompleteEventCache","oldEventNode","updatedPriority","calcEventCacheAfterServerOverwrite","childChangePath","newEventChild","eventChildUpdate","changedSnap","newServerCache","oldServerSnap","serverFilter","newServerNode","newEventSnap","cacheHasChild_","changedChildren","curViewCache","writePath","applyMerge_","viewMergeTree","serverChild","childMergeTree","isUnknownDeepMerge","ackPath","changedChildren_1","changedChildren_2","mergePath","serverCachePath","oldServerNode","completeServerCache","oldEventCache","serverChildren","EventGenerator","query_","generateEventsForChanges","eventCache","eventRegistrations","events","moves","generateEventsForType_","registrations","filteredChanges","filter","compareChanges_","materializedChange","materializeSingleChange_","registration","aWrapped","bWrapped","View","initialViewCache","eventRegistrations_","indexFilter","getNodeFilter","processor_","initialServerCache","initialEventCache","eventGenerator_","getQuery","getCompleteServerCache","cache","loadsAllData","addEventRegistration","removeEventRegistration","cancelError","cancelEvents","path_1","maybeEvent","remaining","existing","generateEventsForChanges_","getInitialEvents","initialChanges","SyncPoint","views_","optCompleteServerCache","view","events_1","serverCacheComplete","eventCacheComplete","removed","hadCompleteView","hasCompleteView","viewQueryId","getQueryViews","viewForQuery","getCompleteView","viewExistsForQuery","CompoundWrite","writeTree_","addWrite","rootmost","rootMostPath","addWrites","updates","newWrite","removeWrite","hasCompleteWrite","getCompleteNode","getCompleteChildren","childCompoundWrite","shadowingNode","applySubtreeWrite_","writeTree","priorityWrite_1","WriteTree","visibleWrites_","allWrites_","lastWriteId_","childWrites","WriteTreeRef","addOverwrite","writeId","visible","addMerge","getWrite","record","findIndex","writeToRemove","splice","removedWriteWasVisible","removedWriteOverlapsWithOtherWrites","currentWrite","recordContainsPath_","resetTree_","getCompleteWriteData","treePath","writeIdsToExclude","includeHiddenWrites","mergeAtPath","layerTree_","write","layeredCache","subMerge","completeServerChildren","topLevelSet","merge_1","existingEventSnap","existingServerSnap","childMerge","toIterate","writeRecord","DefaultFilter_","writes","treeRoot","compoundWrite","deepNode","treePath_","existingServerCache","SyncTree","listenProvider_","syncPointTree_","pendingWriteTree_","tagToQueryMap_","queryToTagMap_","applyUserOverwrite","newData","applyOperationToSyncPoints_","applyUserMerge","changeTree","affectedTree_1","applyServerOverwrite","applyServerMerge","applyListenComplete","applyTaggedQueryOverwrite","tag","queryKey","queryKeyForTag_","r","parseQueryKey_","queryPath","applyTaggedOperation_","applyTaggedQueryMerge","applyTaggedListenComplete","foundAncestorDefaultView","pathToSyncPoint","sp","syncPoint","childSyncPoint","viewAlreadyExists","makeQueryKey_","getNextQueryTag_","setupListener_","maybeSyncPoint","removedAndEvents","removingDefault","covered","parentSyncPoint","newViews","collectDistinctViewsForSubTree_","newQuery","listener","createListenerForView_","startListening","queryForListening_","tagForQuery_","hashFn","stopListening","queryToRemove","tagToRemove","removeTags_","maybeChildSyncPoint","childMap","views_1","childViews","queries","removedQuery","removedQueryKey","removedQueryTag","isDefault","queriesToStop","queries_1","childQueries","queryToStop","status","reason","toUpperCase","errorForServerCode","splitIndex","nextQueryTag_","applyOperationHelper_","syncPointTree","applyOperationDescendantsHelper_","childOperation","childServerCache","childWritesCache","SnapshotHolder","rootNode_","updateSnapshot","newSnapshotNode","AuthTokenProvider","app_","getToken","forceRefresh","then","addTokenChangeListener","removeTokenChangeListener","notifyForInvalidToken","errorMessage","options","StatsCollection","counters_","incrementCounter","amount","StatsManager","getCollection","hashString","collections_","getOrCreateReporter","creatorFunction","reporters_","StatsListener","collection_","last_","newStats","delta","stat","StatsReporter","collection","server_","statsToReport_","statsListener_","reportStats_","includeStat","stats","reportedStats","haveStatsToReport","reportStats","EventQueue","eventLists_","recursionDepth_","queueEvents","eventDataList","currList","eventPath","EventList","raiseEventsAtPath","raiseQueuedEventsMatchingPredicate_","raiseEventsForChangedPath","changedPath","sentAll","eventList","raise","events_","eventFn","EventEmitter","allowedEvents_","listeners_","trigger","listeners","validateEventType_","getInitialEvent","et","VisibilityMonitor","hidden","visibilityChange","document","addEventListener","visible_","getInstance","OnlineMonitor","online_","currentlyOnline","PacketReceiver","onMessage_","pendingResponses","currentResponseNum","closeAfterResponse","onClose","closeAfter","responseNum","handleResponse","requestNum","_loop_1","toProcess","this_1","_loop_2","BrowserPollConnection","connId","transportSessionId","lastSessionId","bytesSent","bytesReceived","everConnected_","log_","stats_","urlFn","open","onMessage","onDisconnect","curSegmentNum","onDisconnect_","myPacketOrderer","isClosed_","connectTimeoutTimer_","onClosed_","readyState","called_1","wrappedFn_1","attachEvent","executeWhenDOMReady","scriptTagHolder","FirebaseIFrameScriptHolder","command","arg1","arg2","incrementIncomingBytes_","clearTimeout","password","sendNewPolls","pN","urlParams","start","uniqueCallbackIdentifier","href","connectURL","addTag","startLongPoll","addDisconnectPingFrame","forceAllow","forceAllow_","forceDisallow","forceDisallow_","isAvailable","createElement","Windows","UI","markConnectionHealthy","shutdown_","close","myDisconnFrame","removeChild","send","dataStr","base64data","MAX_URL_DATA_SIZE","enqueueSegment","pw","dframe","src","style","display","appendChild","commandCB","onMessageCB","outstandingRequests","pendingSegs","currentSerial","myIFrame","createIFrame_","script","iframeContents","doc","iframe","contentWindow","contentDocument","alive","innerHTML","myID","disconn","myPW","theURL","nodeRestRequest","newRequest_","curDataString","theSeg","shift","seg","ts","addLongPollTag_","segnum","totalsegs","url","serial","doNewRequest","keepaliveTimeout","loadCB","doNodeLongPoll","newScript_1","async","onload","onreadystatechange","rstate","parentNode","onerror","WebSocketImpl","MozWebSocket","WebSocket","WebSocketConnection","keepaliveTimer","frames","totalFrames","connectionURL_","headers","User-Agent","firebase","SDK_VERSION","process","platform","env","proxy","origin","mySock","onopen","onclose","onmessage","m","handleIncomingFrame","isOldAndroid","userAgent","oldAndroidMatch","parseFloat","previouslyFailed","appendFrame_","fullMess","jsonMess","handleNewFrameCount_","frameCount","extractFrameCount_","isNaN","mess","resetKeepAlive","remainingData","sendString_","clearInterval","setInterval","responsesRequiredToBeHealthy","healthyTimeout","TransportManager","initTransports_","isWebSocketsAvailable","isSkipPollConnection","transports_","transports_1","ALL_TRANSPORTS","transport","initialTransport","upgradeTransport","Connection","repoInfo_","onReady_","onKill_","connectionCount","pendingDataMessages","state_","transportManager_","start_","conn","conn_","nextTransportId_","primaryResponsesRequired_","onMessageReceived","connReceiver_","onConnectionLost","disconnReceiver_","tx_","rx_","secondaryConn_","isHealthy_","healthyTimeout_ms","healthyTimeout_","everConnected","onConnectionLost_","onSecondaryConnectionLost_","onPrimaryMessageReceived_","onSecondaryMessageReceived_","sendRequest","dataMsg","msg","sendData_","tryCleanupConnection","onSecondaryControl_","controlData","cmd","upgradeIfSecondaryHealthy_","secondaryResponsesRequired_","parsedData","layer","proceedWithUpgrade_","onControl_","onDataMessage_","onPrimaryResponse_","payload","onHandshake_","onConnectionShutdown_","onReset_","sendPingOnPrimaryIfNecessary_","handshake","timestamp","version","h","sessionId","onConnectionEstablished_","tryStartUpgrade_","startUpgrade_","closeConnections_","ServerActions","put","refreshAuthToken","onDisconnectPut","onDisconnectMerge","PersistentConnection","onDataUpdate_","onConnectStatus_","onServerInfoUpdate_","authTokenProvider_","authOverride_","nextPersistentConnectionId_","interruptReasons_","listens_","outstandingPuts_","outstandingPutCount_","onDisconnectRequestQueue_","connected_","reconnectDelay_","maxReconnectDelay_","securityDebugCallback_","establishConnectionTimer_","requestCBHash_","requestNumber_","realtime_","authToken_","forceTokenRefresh_","invalidAuthTokenCount_","firstConnection_","lastConnectionAttemptTime_","lastConnectionEstablishedTime_","scheduleConnect_","onVisible_","onOnline_","onResponse","curReqNum","listen","currentHashFn","listenSpec","sendListen_","req","warnOnListenWarnings_","removeListen_","warnings","indexSpec","indexPath","tryAuth","reduceReconnectDelayIfAdminCredential_","credential","token_1","authMethod","requestData","cred","onAuthRevoked_","unlisten","sendUnlisten_","queryObj","sendOnDisconnect_","request","response","putInternal","sendPut_","queued","errorReason","reqNum","onDataPush_","onListenRevoked_","onSecurityDebugPacket_","handleTimestamp_","sendConnectStats_","restoreState_","establishConnection_","online","onRealtimeDisconnect_","cancelSentTransactions_","shouldReconnect_","timeSinceLastConnectAttempt","reconnectDelay","onDataMessage_1","onReady_1","onDisconnect_1","connId_1","nextConnectionId_","lastSessionId_1","canceled_1","connection_1","closeFn_1","accessToken","interrupt","resume","serverTimeOffset","q","normalizedPathString","statusCode","explanation","ReadonlyRestClient","getListenId_","listenId","thisListen","queryStringParameters","toRestQueryStringParameters","restRequest_","authTokenData","authToken","arrayVal","xhr","XMLHttpRequest","responseText","INTERRUPT_REASON","Repo","forceRestClient","app","dataUpdateCount","eventQueue_","nextWriteId_","interceptServerDataCallback_","persistentConnection_","authTokenProvider","search","authOverride","statsReporter_","transactions_init_","infoData_","infoSyncTree_","infoEvents","updateInfo_","serverSyncTree_","serverTime","offset","generateServerValues","values","isMerge","taggedChildren","raw","taggedSnap","rerunTransactions_","interceptServerData_","connectStatus","runOnDisconnectEvents_","getNextWriteId_","newVal","newNodeUnresolved","success","clearEvents","callOnCompleteCallback","abortTransactions_","childrenToMerge","empty","changedKey","changedValue","writeId_1","resolvedTree","resolvedOnDisconnectTree","showDelta","longestName","reduce","previousValue","currentValue","statsIncrementCounter","metric","__database","Database","RangedFilter","indexedFilter_","startPost_","getStartPost_","endPost_","getEndPost_","getStartPost","getEndPost","self","startName","endName","LimitedFilter","rangedFilter_","limit_","getLimit","reverse_","isViewFromLeft","fullLimitUpdateChild_","indexCompare_1","foundStartPost","changeAccumulator","indexCmp_1","newChildNamedNode","windowBoundary","inRange","oldChildSnap","compareNext","QueryParams","limitSet_","startSet_","startNameSet_","endSet_","endNameSet_","viewFrom_","indexStartValue_","indexStartName_","indexEndValue_","indexEndName_","WIRE_PROTOCOL_CONSTANTS_","VIEW_FROM_LEFT","copy_","newLimit","VIEW_FROM_RIGHT","WIRE_PROTOCOL_CONSTANTS","INDEX_START_VALUE","INDEX_START_NAME","INDEX_END_VALUE","INDEX_END_NAME","LIMIT","viewFrom","VIEW_FROM","INDEX","REST_CONSTANTS","REST_QUERY_CONSTANTS_","qs","ORDER_BY","START_AT","END_AT","LIMIT_TO_FIRST","LIMIT_TO_LAST","DEFAULT","Reference","parentPath","getRoot","databaseProp","database","transaction","transactionUpdate","applyLocally","bool","validateBoolean","startTransaction","setPriority","thennablePushRef","pushRef","TransactionStatus","TreeNode","childCount","Tree","name_","parent_","subTree","pathObj","setValue","updateParents_","forEachDescendant","includeSelf","childrenFirst","forEachAncestor","forEachImmediateDescendantWithValue","updateChild_","childEmpty","childExists","MAX_TRANSACTION_RETRIES_","transactionQueueTree_","valueCallback","watchRef","order","retryCount","unwatcher","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","COMPLETED","SENT_NEEDS_ABORT","NEEDS_ABORT","rootMostTransactionNode","getAncestorTransactionNode_","rerunTransactionQueue_","abortTransaction","currentNode","newDataNode","oldWriteId","newNodeResolved","lastInput","transactionNode","transactionQueue","aggregateTransactionQueuesForNode_","to","from","abortTransactionsOnNode_","lastSent","_staticInstance","DATABASE_URL_OPTION","RepoManager","repos_","useRestClient_","appName","dbUrl","databaseFromApp","createRepo","deleteRepo","appRepos","INTERNAL","DatabaseInternals","checkDeleted_","refFromURL","apiName","parsedURL","goOffline","goOnline","ServerValue","TIMESTAMP",".sv","delete","generator","P","_arguments","fulfilled","rejected","freeze","forceLongPolling","forceWebSockets","setSecurityDebugCallback","interceptServerData","DataConnection","simpleListen","echo","onEcho","RealTimeConnection","ConnectionTarget","TEST_ACCESS","hijackHash","newHash","oldPut","opt_onComplete","opt_hash","listens","firebaseRef","registerService","unused","module","exports"],"mappings":"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"}