mobileapplicationPassvault/node_modules/firebase/firebase-performance-standa...

1 line
320 KiB
Plaintext

{"version":3,"file":"firebase-performance-standalone-compat.es2017.js","sources":["../util/src/crypt.ts","../util/src/deepCopy.ts","../util/src/defaults.ts","../util/src/global.ts","../util/src/deferred.ts","../util/src/environment.ts","../util/src/errors.ts","../util/src/obj.ts","../component/src/component.ts","../component/src/constants.ts","../component/src/provider.ts","../component/src/component_container.ts","../logger/src/logger.ts","../../node_modules/idb/build/wrap-idb-value.js","../../node_modules/idb/build/index.js","../app/src/platformLoggerService.ts","../app/src/logger.ts","../app/src/constants.ts","../app/src/internal.ts","../app/src/errors.ts","../app/src/firebaseApp.ts","../app/src/api.ts","../app/src/indexeddb.ts","../app/src/heartbeatService.ts","../app/src/registerCoreComponents.ts","../app/src/index.ts","../app-compat/src/lite/firebaseAppLite.ts","../app-compat/src/errors.ts","../app-compat/src/firebaseNamespaceCore.ts","../app-compat/src/index.lite.ts","../app-compat/src/lite/firebaseNamespaceLite.ts","../app-compat/src/registerCoreComponents.ts","compat/app/index.ts","../installations/src/util/constants.ts","../installations/src/util/errors.ts","../installations/src/functions/common.ts","../installations/src/util/sleep.ts","../installations/src/helpers/generate-fid.ts","../installations/src/helpers/buffer-to-base64-url-safe.ts","../installations/src/util/get-key.ts","../installations/src/helpers/fid-changed.ts","../installations/src/helpers/idb-manager.ts","../installations/src/helpers/get-installation-entry.ts","../installations/src/functions/create-installation-request.ts","../installations/src/functions/generate-auth-token-request.ts","../installations/src/helpers/refresh-auth-token.ts","../installations/src/api/get-token.ts","../installations/src/helpers/extract-app-config.ts","../installations/src/functions/config.ts","../installations/src/api/get-id.ts","../installations/src/index.ts","../performance/src/constants.ts","../performance/src/utils/errors.ts","../performance/src/utils/console_logger.ts","../performance/src/services/api_service.ts","../performance/src/services/iid_service.ts","../performance/src/services/settings_service.ts","../performance/src/utils/string_merger.ts","../performance/src/utils/attributes_utils.ts","../performance/src/utils/app_utils.ts","../performance/src/services/remote_config_service.ts","../performance/src/services/initialization_service.ts","../performance/src/services/transport_service.ts","../performance/src/services/perf_logger.ts","../performance/src/utils/metric_utils.ts","../performance/src/resources/trace.ts","../performance/src/resources/network_request.ts","../performance/src/services/oob_resources_service.ts","../performance/src/controllers/perf.ts","../performance/src/index.ts","../performance-compat/src/performance.ts","../util/src/compat.ts","../performance-compat/src/index.ts","compat/index.perf.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst stringToByteArray = function (str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function (bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\ninterface Base64 {\n byteToCharMap_: { [key: number]: string } | null;\n charToByteMap_: { [key: string]: number } | null;\n byteToCharMapWebSafe_: { [key: number]: string } | null;\n charToByteMapWebSafe_: { [key: string]: number } | null;\n ENCODED_VALS_BASE: string;\n readonly ENCODED_VALS: string;\n readonly ENCODED_VALS_WEBSAFE: string;\n HAS_NATIVE_SUPPORT: boolean;\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string;\n encodeString(input: string, webSafe?: boolean): string;\n decodeString(input: string, webSafe: boolean): string;\n decodeStringToByteArray(input: string, webSafe: boolean): number[];\n init_(): void;\n}\n\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\n// Static lookup maps, lazily populated by init_()\nexport const base64: Base64 = {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: null,\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @private\n */\n byteToCharMapWebSafe_: null,\n\n /**\n * Maps websafe characters to bytes.\n * @private\n */\n charToByteMapWebSafe_: null,\n\n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n */\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n },\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n },\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n },\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw new DecodeBase64StringError();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n },\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n/**\n * An error encountered while decoding base64 string.\n */\nexport class DecodeBase64StringError extends Error {\n readonly name = 'DecodeBase64StringError';\n}\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 encoding (without \".\" padding in the end).\n * e.g. Used in JSON Web Token (JWT) parts.\n */\nexport const base64urlEncodeWithoutPadding = function (str: string): string {\n // Use base64url encoding and remove padding in the end (dot characters).\n return base64Encode(str).replace(/\\./g, '');\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\n};\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Do a deep-copy of basic JavaScript Objects or Arrays.\n */\nexport function deepCopy<T>(value: T): T {\n return deepExtend(undefined, value) as T;\n}\n\n/**\n * Copy properties from source to target (recursively allows extension\n * of Objects and Arrays). Scalar values in the target are over-written.\n * If target is undefined, an object of the appropriate type will be created\n * (and returned).\n *\n * We recursively copy all child properties of plain Objects in the source- so\n * that namespace- like dictionaries are merged.\n *\n * Note that the target can be a function, in which case the properties in\n * the source Object are copied onto it as static properties of the Function.\n *\n * Note: we don't merge __proto__ to prevent prototype pollution\n */\nexport function deepExtend(target: unknown, source: unknown): unknown {\n if (!(source instanceof Object)) {\n return source;\n }\n\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n const dateValue = source as Date;\n return new Date(dateValue.getTime());\n\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n\n for (const prop in source) {\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\n continue;\n }\n (target as Record<string, unknown>)[prop] = deepExtend(\n (target as Record<string, unknown>)[prop],\n (source as Record<string, unknown>)[prop]\n );\n }\n\n return target;\n}\n\nfunction isValidKey(key: string): boolean {\n return key !== '__proto__';\n}\n","/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64Decode } from './crypt';\nimport { getGlobal } from './global';\n\n/**\n * Keys for experimental properties on the `FirebaseDefaults` object.\n * @public\n */\nexport type ExperimentalKey = 'authTokenSyncURL' | 'authIdTokenMaxAge';\n\n/**\n * An object that can be injected into the environment as __FIREBASE_DEFAULTS__,\n * either as a property of globalThis, a shell environment variable, or a\n * cookie.\n *\n * This object can be used to automatically configure and initialize\n * a Firebase app as well as any emulators.\n *\n * @public\n */\nexport interface FirebaseDefaults {\n config?: Record<string, string>;\n emulatorHosts?: Record<string, string>;\n _authTokenSyncURL?: string;\n _authIdTokenMaxAge?: number;\n /**\n * Override Firebase's runtime environment detection and\n * force the SDK to act as if it were in the specified environment.\n */\n forceEnvironment?: 'browser' | 'node';\n [key: string]: unknown;\n}\n\ndeclare global {\n // Need `var` for this to work.\n // eslint-disable-next-line no-var\n var __FIREBASE_DEFAULTS__: FirebaseDefaults | undefined;\n}\n\nconst getDefaultsFromGlobal = (): FirebaseDefaults | undefined =>\n getGlobal().__FIREBASE_DEFAULTS__;\n\n/**\n * Attempt to read defaults from a JSON string provided to\n * process(.)env(.)__FIREBASE_DEFAULTS__ or a JSON file whose path is in\n * process(.)env(.)__FIREBASE_DEFAULTS_PATH__\n * The dots are in parens because certain compilers (Vite?) cannot\n * handle seeing that variable in comments.\n * See https://github.com/firebase/firebase-js-sdk/issues/6838\n */\nconst getDefaultsFromEnvVariable = (): FirebaseDefaults | undefined => {\n if (typeof process === 'undefined' || typeof process.env === 'undefined') {\n return;\n }\n const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__;\n if (defaultsJsonString) {\n return JSON.parse(defaultsJsonString);\n }\n};\n\nconst getDefaultsFromCookie = (): FirebaseDefaults | undefined => {\n if (typeof document === 'undefined') {\n return;\n }\n let match;\n try {\n match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/);\n } catch (e) {\n // Some environments such as Angular Universal SSR have a\n // `document` object but error on accessing `document.cookie`.\n return;\n }\n const decoded = match && base64Decode(match[1]);\n return decoded && JSON.parse(decoded);\n};\n\n/**\n * Get the __FIREBASE_DEFAULTS__ object. It checks in order:\n * (1) if such an object exists as a property of `globalThis`\n * (2) if such an object was provided on a shell environment variable\n * (3) if such an object exists in a cookie\n * @public\n */\nexport const getDefaults = (): FirebaseDefaults | undefined => {\n try {\n return (\n getDefaultsFromGlobal() ||\n getDefaultsFromEnvVariable() ||\n getDefaultsFromCookie()\n );\n } catch (e) {\n /**\n * Catch-all for being unable to get __FIREBASE_DEFAULTS__ due\n * to any environment case we have not accounted for. Log to\n * info instead of swallowing so we can find these unknown cases\n * and add paths for them if needed.\n */\n console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`);\n return;\n }\n};\n\n/**\n * Returns emulator host stored in the __FIREBASE_DEFAULTS__ object\n * for the given product.\n * @returns a URL host formatted like `127.0.0.1:9999` or `[::1]:4000` if available\n * @public\n */\nexport const getDefaultEmulatorHost = (\n productName: string\n): string | undefined => getDefaults()?.emulatorHosts?.[productName];\n\n/**\n * Returns emulator hostname and port stored in the __FIREBASE_DEFAULTS__ object\n * for the given product.\n * @returns a pair of hostname and port like `[\"::1\", 4000]` if available\n * @public\n */\nexport const getDefaultEmulatorHostnameAndPort = (\n productName: string\n): [hostname: string, port: number] | undefined => {\n const host = getDefaultEmulatorHost(productName);\n if (!host) {\n return undefined;\n }\n const separatorIndex = host.lastIndexOf(':'); // Finding the last since IPv6 addr also has colons.\n if (separatorIndex <= 0 || separatorIndex + 1 === host.length) {\n throw new Error(`Invalid host ${host} with no separate hostname and port!`);\n }\n // eslint-disable-next-line no-restricted-globals\n const port = parseInt(host.substring(separatorIndex + 1), 10);\n if (host[0] === '[') {\n // Bracket-quoted `[ipv6addr]:port` => return \"ipv6addr\" (without brackets).\n return [host.substring(1, separatorIndex - 1), port];\n } else {\n return [host.substring(0, separatorIndex), port];\n }\n};\n\n/**\n * Returns Firebase app config stored in the __FIREBASE_DEFAULTS__ object.\n * @public\n */\nexport const getDefaultAppConfig = (): Record<string, string> | undefined =>\n getDefaults()?.config;\n\n/**\n * Returns an experimental setting on the __FIREBASE_DEFAULTS__ object (properties\n * prefixed by \"_\")\n * @public\n */\nexport const getExperimentalSetting = <T extends ExperimentalKey>(\n name: T\n): FirebaseDefaults[`_${T}`] =>\n getDefaults()?.[`_${name}`] as FirebaseDefaults[`_${T}`];\n","/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Polyfill for `globalThis` object.\n * @returns the `globalThis` object for the given environment.\n * @public\n */\nexport function getGlobal(): typeof globalThis {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n throw new Error('Unable to locate global object.');\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class Deferred<R> {\n promise: Promise<R>;\n reject: (value?: unknown) => void = () => {};\n resolve: (value?: unknown) => void = () => {};\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve as (value?: unknown) => void;\n this.reject = reject as (value?: unknown) => void;\n });\n }\n\n /**\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\n */\n wrapCallback(\n callback?: (error?: unknown, value?: unknown) => void\n ): (error: unknown, value?: unknown) => void {\n return (error, value?) => {\n if (error) {\n this.reject(error);\n } else {\n this.resolve(value);\n }\n if (typeof callback === 'function') {\n // Attaching noop handler just in case developer wasn't expecting\n // promises\n this.promise.catch(() => {});\n\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (callback.length === 1) {\n callback(error);\n } else {\n callback(error, value);\n }\n }\n };\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\nimport { getDefaults } from './defaults';\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return user agent string\n */\nexport function getUA(): string {\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\n return navigator['userAgent'];\n } else {\n return '';\n }\n}\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\n * wait for a callback.\n */\nexport function isMobileCordova(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-ignore Setting up an broadly applicable index signature for Window\n // just to deal with this case would probably be a bad idea.\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())\n );\n}\n\n/**\n * Detect Node.js.\n *\n * @return true if Node.js environment is detected or specified.\n */\n// Node detection logic from: https://github.com/iliakan/detect-node/\nexport function isNode(): boolean {\n const forceEnvironment = getDefaults()?.forceEnvironment;\n if (forceEnvironment === 'node') {\n return true;\n } else if (forceEnvironment === 'browser') {\n return false;\n }\n\n try {\n return (\n Object.prototype.toString.call(global.process) === '[object process]'\n );\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Detect Browser Environment\n */\nexport function isBrowser(): boolean {\n return typeof self === 'object' && self.self === self;\n}\n\n/**\n * Detect browser extensions (Chrome and Firefox at least).\n */\ninterface BrowserRuntime {\n id?: unknown;\n}\ndeclare const chrome: { runtime?: BrowserRuntime };\ndeclare const browser: { runtime?: BrowserRuntime };\nexport function isBrowserExtension(): boolean {\n const runtime =\n typeof chrome === 'object'\n ? chrome.runtime\n : typeof browser === 'object'\n ? browser.runtime\n : undefined;\n return typeof runtime === 'object' && runtime.id !== undefined;\n}\n\n/**\n * Detect React Native.\n *\n * @return true if ReactNative environment is detected.\n */\nexport function isReactNative(): boolean {\n return (\n typeof navigator === 'object' && navigator['product'] === 'ReactNative'\n );\n}\n\n/** Detects Electron apps. */\nexport function isElectron(): boolean {\n return getUA().indexOf('Electron/') >= 0;\n}\n\n/** Detects Internet Explorer. */\nexport function isIE(): boolean {\n const ua = getUA();\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\n}\n\n/** Detects Universal Windows Platform apps. */\nexport function isUWP(): boolean {\n return getUA().indexOf('MSAppHost/') >= 0;\n}\n\n/**\n * Detect whether the current SDK build is the Node version.\n *\n * @return true if it's the Node SDK build.\n */\nexport function isNodeSdk(): boolean {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n}\n\n/** Returns true if we are running in Safari. */\nexport function isSafari(): boolean {\n return (\n !isNode() &&\n !!navigator.userAgent &&\n navigator.userAgent.includes('Safari') &&\n !navigator.userAgent.includes('Chrome')\n );\n}\n\n/**\n * This method checks if indexedDB is supported by current browser/service worker context\n * @return true if indexedDB is supported by current browser/service worker context\n */\nexport function isIndexedDBAvailable(): boolean {\n try {\n return typeof indexedDB === 'object';\n } catch (e) {\n return false;\n }\n}\n\n/**\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n *\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\n * private browsing)\n */\nexport function validateIndexedDBOpenable(): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n let preExist: boolean = true;\n const DB_CHECK_NAME =\n 'validate-browser-context-for-indexeddb-analytics-module';\n const request = self.indexedDB.open(DB_CHECK_NAME);\n request.onsuccess = () => {\n request.result.close();\n // delete database only when it doesn't pre-exist\n if (!preExist) {\n self.indexedDB.deleteDatabase(DB_CHECK_NAME);\n }\n resolve(true);\n };\n request.onupgradeneeded = () => {\n preExist = false;\n };\n\n request.onerror = () => {\n reject(request.error?.message || '');\n };\n } catch (error) {\n reject(error);\n }\n });\n}\n\n/**\n *\n * This method checks whether cookie is enabled within current browser\n * @return true if cookie is enabled within current browser\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {\n return false;\n }\n return true;\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map<Err, string> = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory<Err>('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap<ErrorCode extends string> = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record<string, unknown>\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap<ErrorCode>\n ) {}\n\n create<K extends ErrorCode>(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function contains<T extends object>(obj: T, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet<T extends object, K extends keyof T>(\n obj: T,\n key: K\n): T[K] | undefined {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key];\n } else {\n return undefined;\n }\n}\n\nexport function isEmpty(obj: object): obj is {} {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport function map<K extends string, V, U>(\n obj: { [key in K]: V },\n fn: (value: V, key: K, obj: { [key in K]: V }) => U,\n contextObj?: unknown\n): { [key in K]: U } {\n const res: Partial<{ [key in K]: U }> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[key] = fn.call(contextObj, obj[key], key, obj);\n }\n }\n return res as { [key in K]: U };\n}\n\n/**\n * Deep equal two objects. Support Arrays and Objects.\n */\nexport function deepEqual(a: object, b: object): boolean {\n if (a === b) {\n return true;\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n for (const k of aKeys) {\n if (!bKeys.includes(k)) {\n return false;\n }\n\n const aProp = (a as Record<string, unknown>)[k];\n const bProp = (b as Record<string, unknown>)[k];\n if (isObject(aProp) && isObject(bProp)) {\n if (!deepEqual(aProp, bProp)) {\n return false;\n }\n } else if (aProp !== bProp) {\n return false;\n }\n }\n\n for (const k of bKeys) {\n if (!aKeys.includes(k)) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(thing: unknown): thing is object {\n return thing !== null && typeof thing === 'object';\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component<T extends Name = Name> {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback<T> | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory<T>,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback<T>): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport {\n InitializeOptions,\n InstantiationMode,\n Name,\n NameServiceMapping,\n OnInitCallBack\n} from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider<T extends Name> {\n private component: Component<T> | null = null;\n private readonly instances: Map<string, NameServiceMapping[T]> = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred<NameServiceMapping[T]>\n > = new Map();\n private readonly instancesOptions: Map<string, Record<string, unknown>> =\n new Map();\n private onInitCallbacks: Map<string, Set<OnInitCallBack<T>>> = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier?: string): Promise<NameServiceMapping[T]> {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred<NameServiceMapping[T]>();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n // initialize the service if it can be auto-initialized\n try {\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n options?.identifier\n );\n const optional = options?.optional ?? false;\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n try {\n return this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n } else {\n // In case a component is not initialized and should/can not be auto-initialized at the moment, return null if the optional flag is set, or throw\n if (optional) {\n return null;\n } else {\n throw Error(`Service ${this.name} is not available`);\n }\n }\n }\n\n getComponent(): Component<T> | null {\n return this.component;\n }\n\n setComponent(component: Component<T>): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\n if (!this.shouldAutoInitialize()) {\n return;\n }\n\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n })!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instancesOptions.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise<void> {\n const services = Array.from(this.instances.values());\n\n await Promise.all([\n ...services\n .filter(service => 'INTERNAL' in service) // legacy services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete()),\n ...services\n .filter(service => '_delete' in service) // modularized services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any)._delete())\n ]);\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n isInitialized(identifier: string = DEFAULT_ENTRY_NAME): boolean {\n return this.instances.has(identifier);\n }\n\n getOptions(identifier: string = DEFAULT_ENTRY_NAME): Record<string, unknown> {\n return this.instancesOptions.get(identifier) || {};\n }\n\n initialize(opts: InitializeOptions = {}): NameServiceMapping[T] {\n const { options = {} } = opts;\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n opts.instanceIdentifier\n );\n if (this.isInitialized(normalizedIdentifier)) {\n throw Error(\n `${this.name}(${normalizedIdentifier}) has already been initialized`\n );\n }\n\n if (!this.isComponentSet()) {\n throw Error(`Component ${this.name} has not been registered yet`);\n }\n\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier,\n options\n })!;\n\n // resolve any pending promise waiting for the service instance\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedDeferredIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\n instanceDeferred.resolve(instance);\n }\n }\n\n return instance;\n }\n\n /**\n *\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\n *\n * @param identifier An optional instance identifier\n * @returns a function to unregister the callback\n */\n onInit(callback: OnInitCallBack<T>, identifier?: string): () => void {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n const existingCallbacks =\n this.onInitCallbacks.get(normalizedIdentifier) ??\n new Set<OnInitCallBack<T>>();\n existingCallbacks.add(callback);\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\n\n const existingInstance = this.instances.get(normalizedIdentifier);\n if (existingInstance) {\n callback(existingInstance, normalizedIdentifier);\n }\n\n return () => {\n existingCallbacks.delete(callback);\n };\n }\n\n /**\n * Invoke onInit callbacks synchronously\n * @param instance the service instance`\n */\n private invokeOnInitCallbacks(\n instance: NameServiceMapping[T],\n identifier: string\n ): void {\n const callbacks = this.onInitCallbacks.get(identifier);\n if (!callbacks) {\n return;\n }\n for (const callback of callbacks) {\n try {\n callback(instance, identifier);\n } catch {\n // ignore errors in the onInit callback\n }\n }\n }\n\n private getOrInitializeService({\n instanceIdentifier,\n options = {}\n }: {\n instanceIdentifier: string;\n options?: Record<string, unknown>;\n }): NameServiceMapping[T] | null {\n let instance = this.instances.get(instanceIdentifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(this.container, {\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\n options\n });\n this.instances.set(instanceIdentifier, instance);\n this.instancesOptions.set(instanceIdentifier, options);\n\n /**\n * Invoke onInit listeners.\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\n * while onInit listeners are registered by consumers of the provider.\n */\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\n\n /**\n * Order is important\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\n * makes `isInitialized()` return true.\n */\n if (this.component.onInstanceCreated) {\n try {\n this.component.onInstanceCreated(\n this.container,\n instanceIdentifier,\n instance\n );\n } catch {\n // ignore errors in the onInstanceCreatedCallback\n }\n }\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(\n identifier: string = DEFAULT_ENTRY_NAME\n ): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n\n private shouldAutoInitialize(): boolean {\n return (\n !!this.component &&\n this.component.instantiationMode !== InstantiationMode.EXPLICIT\n );\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager<T extends Name>(component: Component<T>): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map<string, Provider<Name>>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent<T extends Name>(component: Component<T>): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent<T extends Name>(component: Component<T>): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider<T extends Name>(name: T): Provider<T> {\n if (this.providers.has(name)) {\n return this.providers.get(name) as unknown as Provider<T>;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider<T>(name, this);\n this.providers.set(name, provider as unknown as Provider<Name>);\n\n return provider as Provider<T>;\n }\n\n getProviders(): Array<Provider<Name>> {\n return Array.from(this.providers.values());\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n","const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n","import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);\n });\n }\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event.newVersion, event));\n }\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking) {\n db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));\n }\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event));\n }\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentContainer,\n ComponentType,\n Provider,\n Name\n} from '@firebase/component';\nimport { PlatformLoggerService, VersionService } from './types';\n\nexport class PlatformLoggerServiceImpl implements PlatformLoggerService {\n constructor(private readonly container: ComponentContainer) {}\n // In initial implementation, this will be called by installations on\n // auth token refresh, and installations will send this string.\n getPlatformInfoString(): string {\n const providers = this.container.getProviders();\n // Loop through providers and get library/version pairs from any that are\n // version components.\n return providers\n .map(provider => {\n if (isVersionServiceProvider(provider)) {\n const service = provider.getImmediate() as VersionService;\n return `${service.library}/${service.version}`;\n } else {\n return null;\n }\n })\n .filter(logString => logString)\n .join(' ');\n }\n}\n/**\n *\n * @param provider check if this provider provides a VersionService\n *\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\n * provides VersionService. The provider is not necessarily a 'app-version'\n * provider.\n */\nfunction isVersionServiceProvider(provider: Provider<Name>): boolean {\n const component = provider.getComponent();\n return component?.type === ComponentType.VERSION;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/app');\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { name as appName } from '../package.json';\nimport { name as appCompatName } from '../../app-compat/package.json';\nimport { name as analyticsCompatName } from '../../../packages/analytics-compat/package.json';\nimport { name as analyticsName } from '../../../packages/analytics/package.json';\nimport { name as appCheckCompatName } from '../../../packages/app-check-compat/package.json';\nimport { name as appCheckName } from '../../../packages/app-check/package.json';\nimport { name as authName } from '../../../packages/auth/package.json';\nimport { name as authCompatName } from '../../../packages/auth-compat/package.json';\nimport { name as databaseName } from '../../../packages/database/package.json';\nimport { name as databaseCompatName } from '../../../packages/database-compat/package.json';\nimport { name as functionsName } from '../../../packages/functions/package.json';\nimport { name as functionsCompatName } from '../../../packages/functions-compat/package.json';\nimport { name as installationsName } from '../../../packages/installations/package.json';\nimport { name as installationsCompatName } from '../../../packages/installations-compat/package.json';\nimport { name as messagingName } from '../../../packages/messaging/package.json';\nimport { name as messagingCompatName } from '../../../packages/messaging-compat/package.json';\nimport { name as performanceName } from '../../../packages/performance/package.json';\nimport { name as performanceCompatName } from '../../../packages/performance-compat/package.json';\nimport { name as remoteConfigName } from '../../../packages/remote-config/package.json';\nimport { name as remoteConfigCompatName } from '../../../packages/remote-config-compat/package.json';\nimport { name as storageName } from '../../../packages/storage/package.json';\nimport { name as storageCompatName } from '../../../packages/storage-compat/package.json';\nimport { name as firestoreName } from '../../../packages/firestore/package.json';\nimport { name as firestoreCompatName } from '../../../packages/firestore-compat/package.json';\nimport { name as packageName } from '../../../packages/firebase/package.json';\n\n/**\n * The default app name\n *\n * @internal\n */\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\nexport const PLATFORM_LOG_STRING = {\n [appName]: 'fire-core',\n [appCompatName]: 'fire-core-compat',\n [analyticsName]: 'fire-analytics',\n [analyticsCompatName]: 'fire-analytics-compat',\n [appCheckName]: 'fire-app-check',\n [appCheckCompatName]: 'fire-app-check-compat',\n [authName]: 'fire-auth',\n [authCompatName]: 'fire-auth-compat',\n [databaseName]: 'fire-rtdb',\n [databaseCompatName]: 'fire-rtdb-compat',\n [functionsName]: 'fire-fn',\n [functionsCompatName]: 'fire-fn-compat',\n [installationsName]: 'fire-iid',\n [installationsCompatName]: 'fire-iid-compat',\n [messagingName]: 'fire-fcm',\n [messagingCompatName]: 'fire-fcm-compat',\n [performanceName]: 'fire-perf',\n [performanceCompatName]: 'fire-perf-compat',\n [remoteConfigName]: 'fire-rc',\n [remoteConfigCompatName]: 'fire-rc-compat',\n [storageName]: 'fire-gcs',\n [storageCompatName]: 'fire-gcs-compat',\n [firestoreName]: 'fire-fst',\n [firestoreCompatName]: 'fire-fst-compat',\n 'fire-js': 'fire-js', // Platform identifier for JS SDK.\n [packageName]: 'fire-js-all'\n} as const;\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from './public-types';\nimport { Component, Provider, Name } from '@firebase/component';\nimport { logger } from './logger';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { FirebaseAppImpl } from './firebaseApp';\n\n/**\n * @internal\n */\nexport const _apps = new Map<string, FirebaseApp>();\n\n/**\n * Registered components.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const _components = new Map<string, Component<any>>();\n\n/**\n * @param component - the component being added to this app's container\n *\n * @internal\n */\nexport function _addComponent<T extends Name>(\n app: FirebaseApp,\n component: Component<T>\n): void {\n try {\n (app as FirebaseAppImpl).container.addComponent(component);\n } catch (e) {\n logger.debug(\n `Component ${component.name} failed to register with FirebaseApp ${app.name}`,\n e\n );\n }\n}\n\n/**\n *\n * @internal\n */\nexport function _addOrOverwriteComponent(\n app: FirebaseApp,\n component: Component\n): void {\n (app as FirebaseAppImpl).container.addOrOverwriteComponent(component);\n}\n\n/**\n *\n * @param component - the component to register\n * @returns whether or not the component is registered successfully\n *\n * @internal\n */\nexport function _registerComponent<T extends Name>(\n component: Component<T>\n): boolean {\n const componentName = component.name;\n if (_components.has(componentName)) {\n logger.debug(\n `There were multiple attempts to register component ${componentName}.`\n );\n\n return false;\n }\n\n _components.set(componentName, component);\n\n // add the component to existing app instances\n for (const app of _apps.values()) {\n _addComponent(app as FirebaseAppImpl, component);\n }\n\n return true;\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n *\n * @returns the provider for the service with the matching name\n *\n * @internal\n */\nexport function _getProvider<T extends Name>(\n app: FirebaseApp,\n name: T\n): Provider<T> {\n const heartbeatController = (app as FirebaseAppImpl).container\n .getProvider('heartbeat')\n .getImmediate({ optional: true });\n if (heartbeatController) {\n void heartbeatController.triggerHeartbeat();\n }\n return (app as FirebaseAppImpl).container.getProvider(name);\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n * @param instanceIdentifier - service instance identifier in case the service supports multiple instances\n *\n * @internal\n */\nexport function _removeServiceInstance<T extends Name>(\n app: FirebaseApp,\n name: T,\n instanceIdentifier: string = DEFAULT_ENTRY_NAME\n): void {\n _getProvider(app, name).clearInstance(instanceIdentifier);\n}\n\n/**\n * Test only\n *\n * @internal\n */\nexport function _clearComponents(): void {\n _components.clear();\n}\n\n/**\n * Exported in order to be used in app-compat package\n */\nexport { DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME };\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n BAD_APP_NAME = 'bad-app-name',\n DUPLICATE_APP = 'duplicate-app',\n APP_DELETED = 'app-deleted',\n NO_OPTIONS = 'no-options',\n INVALID_APP_ARGUMENT = 'invalid-app-argument',\n INVALID_LOG_ARGUMENT = 'invalid-log-argument',\n IDB_OPEN = 'idb-open',\n IDB_GET = 'idb-get',\n IDB_WRITE = 'idb-set',\n IDB_DELETE = 'idb-delete'\n}\n\nconst ERRORS: ErrorMap<AppError> = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call initializeApp() first',\n [AppError.BAD_APP_NAME]: \"Illegal App name: '{$appName}\",\n [AppError.DUPLICATE_APP]:\n \"Firebase App named '{$appName}' already exists with different options or config\",\n [AppError.APP_DELETED]: \"Firebase App named '{$appName}' already deleted\",\n [AppError.NO_OPTIONS]:\n 'Need to provide options, when not being deployed to hosting via source.',\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.',\n [AppError.INVALID_LOG_ARGUMENT]:\n 'First argument to `onLog` must be null or a function.',\n [AppError.IDB_OPEN]:\n 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_GET]:\n 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_WRITE]:\n 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_DELETE]:\n 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'\n};\n\ninterface ErrorParams {\n [AppError.NO_APP]: { appName: string };\n [AppError.BAD_APP_NAME]: { appName: string };\n [AppError.DUPLICATE_APP]: { appName: string };\n [AppError.APP_DELETED]: { appName: string };\n [AppError.INVALID_APP_ARGUMENT]: { appName: string };\n [AppError.IDB_OPEN]: { originalErrorMessage?: string };\n [AppError.IDB_GET]: { originalErrorMessage?: string };\n [AppError.IDB_WRITE]: { originalErrorMessage?: string };\n [AppError.IDB_DELETE]: { originalErrorMessage?: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<AppError, ErrorParams>(\n 'app',\n 'Firebase',\n ERRORS\n);\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport {\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, AppError } from './errors';\n\nexport class FirebaseAppImpl implements FirebaseApp {\n private readonly _options: FirebaseOptions;\n private readonly _name: string;\n /**\n * Original config values passed in as a constructor parameter.\n * It is only used to compare with another config object to support idempotent initializeApp().\n *\n * Updating automaticDataCollectionEnabled on the App instance will not change its value in _config.\n */\n private readonly _config: Required<FirebaseAppSettings>;\n private _automaticDataCollectionEnabled: boolean;\n private _isDeleted = false;\n private readonly _container: ComponentContainer;\n\n constructor(\n options: FirebaseOptions,\n config: Required<FirebaseAppSettings>,\n container: ComponentContainer\n ) {\n this._options = { ...options };\n this._config = { ...config };\n this._name = config.name;\n this._automaticDataCollectionEnabled =\n config.automaticDataCollectionEnabled;\n this._container = container;\n this.container.addComponent(\n new Component('app', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n this.checkDestroyed();\n return this._automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val: boolean) {\n this.checkDestroyed();\n this._automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n this.checkDestroyed();\n return this._name;\n }\n\n get options(): FirebaseOptions {\n this.checkDestroyed();\n return this._options;\n }\n\n get config(): Required<FirebaseAppSettings> {\n this.checkDestroyed();\n return this._config;\n }\n\n get container(): ComponentContainer {\n return this._container;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted;\n }\n\n set isDeleted(val: boolean) {\n this._isDeleted = val;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n private checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.APP_DELETED, { appName: this._name });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport {\n ComponentContainer,\n Component,\n Name,\n ComponentType\n} from '@firebase/component';\nimport { version } from '../../firebase/package.json';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { _apps, _components, _registerComponent } from './internal';\nimport { logger } from './logger';\nimport {\n LogLevelString,\n setLogLevel as setLogLevelImpl,\n LogCallback,\n LogOptions,\n setUserLogHandler\n} from '@firebase/logger';\nimport { deepEqual, getDefaultAppConfig } from '@firebase/util';\n\nexport { FirebaseError } from '@firebase/util';\n\n/**\n * The current SDK version.\n *\n * @public\n */\nexport const SDK_VERSION = version;\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize default app\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * });\n * ```\n *\n * @example\n * ```javascript\n *\n * // Initialize another app\n * const otherApp = initializeApp({\n * databaseURL: \"https://<OTHER_DATABASE_NAME>.firebaseio.com\",\n * storageBucket: \"<OTHER_STORAGE_BUCKET>.appspot.com\"\n * }, \"otherApp\");\n * ```\n *\n * @param options - Options to configure the app's services.\n * @param name - Optional name of the app to initialize. If no name\n * is provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The initialized app.\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n name?: string\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @param options - Options to configure the app's services.\n * @param config - FirebaseApp Configuration\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n config?: FirebaseAppSettings\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @public\n */\nexport function initializeApp(): FirebaseApp;\nexport function initializeApp(\n _options?: FirebaseOptions,\n rawConfig = {}\n): FirebaseApp {\n let options = _options;\n\n if (typeof rawConfig !== 'object') {\n const name = rawConfig;\n rawConfig = { name };\n }\n\n const config: Required<FirebaseAppSettings> = {\n name: DEFAULT_ENTRY_NAME,\n automaticDataCollectionEnabled: false,\n ...rawConfig\n };\n const name = config.name;\n\n if (typeof name !== 'string' || !name) {\n throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n appName: String(name)\n });\n }\n\n options ||= getDefaultAppConfig();\n\n if (!options) {\n throw ERROR_FACTORY.create(AppError.NO_OPTIONS);\n }\n\n const existingApp = _apps.get(name) as FirebaseAppImpl;\n if (existingApp) {\n // return the existing app if options and config deep equal the ones in the existing app.\n if (\n deepEqual(options, existingApp.options) &&\n deepEqual(config, existingApp.config)\n ) {\n return existingApp;\n } else {\n throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n }\n }\n\n const container = new ComponentContainer(name);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseAppImpl(options, config, container);\n\n _apps.set(name, newApp);\n\n return newApp;\n}\n\n/**\n * Retrieves a {@link @firebase/app#FirebaseApp} instance.\n *\n * When called with no arguments, the default app is returned. When an app name\n * is provided, the app corresponding to that name is returned.\n *\n * An exception is thrown if the app being retrieved has not yet been\n * initialized.\n *\n * @example\n * ```javascript\n * // Return the default app\n * const app = getApp();\n * ```\n *\n * @example\n * ```javascript\n * // Return a named app\n * const otherApp = getApp(\"otherApp\");\n * ```\n *\n * @param name - Optional name of the app to return. If no name is\n * provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The app corresponding to the provided app name.\n * If no app name is provided, the default app is returned.\n *\n * @public\n */\nexport function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {\n const app = _apps.get(name);\n if (!app && name === DEFAULT_ENTRY_NAME && getDefaultAppConfig()) {\n return initializeApp();\n }\n if (!app) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n\n return app;\n}\n\n/**\n * A (read-only) array of all initialized apps.\n * @public\n */\nexport function getApps(): FirebaseApp[] {\n return Array.from(_apps.values());\n}\n\n/**\n * Renders this app unusable and frees the resources of all associated\n * services.\n *\n * @example\n * ```javascript\n * deleteApp(app)\n * .then(function() {\n * console.log(\"App deleted successfully\");\n * })\n * .catch(function(error) {\n * console.log(\"Error deleting app:\", error);\n * });\n * ```\n *\n * @public\n */\nexport async function deleteApp(app: FirebaseApp): Promise<void> {\n const name = app.name;\n if (_apps.has(name)) {\n _apps.delete(name);\n await Promise.all(\n (app as FirebaseAppImpl).container\n .getProviders()\n .map(provider => provider.delete())\n );\n (app as FirebaseAppImpl).isDeleted = true;\n }\n}\n\n/**\n * Registers a library's name and version for platform logging purposes.\n * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)\n * @param version - Current version of that library.\n * @param variant - Bundle variant, e.g., node, rn, etc.\n *\n * @public\n */\nexport function registerVersion(\n libraryKeyOrName: string,\n version: string,\n variant?: string\n): void {\n // TODO: We can use this check to whitelist strings when/if we set up\n // a good whitelist system.\n let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;\n if (variant) {\n library += `-${variant}`;\n }\n const libraryMismatch = library.match(/\\s|\\//);\n const versionMismatch = version.match(/\\s|\\//);\n if (libraryMismatch || versionMismatch) {\n const warning = [\n `Unable to register library \"${library}\" with version \"${version}\":`\n ];\n if (libraryMismatch) {\n warning.push(\n `library name \"${library}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n if (libraryMismatch && versionMismatch) {\n warning.push('and');\n }\n if (versionMismatch) {\n warning.push(\n `version name \"${version}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n logger.warn(warning.join(' '));\n return;\n }\n _registerComponent(\n new Component(\n `${library}-version` as Name,\n () => ({ library, version }),\n ComponentType.VERSION\n )\n );\n}\n\n/**\n * Sets log handler for all Firebase SDKs.\n * @param logCallback - An optional custom log handler that executes user code whenever\n * the Firebase SDK makes a logging call.\n *\n * @public\n */\nexport function onLog(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n if (logCallback !== null && typeof logCallback !== 'function') {\n throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT);\n }\n setUserLogHandler(logCallback, options);\n}\n\n/**\n * Sets log level for all Firebase SDKs.\n *\n * All of the log types above the current log level are captured (i.e. if\n * you set the log level to `info`, errors are logged, but `debug` and\n * `verbose` logs are not).\n *\n * @public\n */\nexport function setLogLevel(logLevel: LogLevelString): void {\n setLogLevelImpl(logLevel);\n}\n","/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { DBSchema, openDB, IDBPDatabase } from 'idb';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from './public-types';\nimport { HeartbeatsInIndexedDB } from './types';\nimport { logger } from './logger';\n\nconst DB_NAME = 'firebase-heartbeat-database';\nconst DB_VERSION = 1;\nconst STORE_NAME = 'firebase-heartbeat-store';\n\ninterface AppDB extends DBSchema {\n 'firebase-heartbeat-store': {\n key: string;\n value: HeartbeatsInIndexedDB;\n };\n}\n\nlet dbPromise: Promise<IDBPDatabase<AppDB>> | null = null;\nfunction getDbPromise(): Promise<IDBPDatabase<AppDB>> {\n if (!dbPromise) {\n dbPromise = openDB<AppDB>(DB_NAME, DB_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n try {\n db.createObjectStore(STORE_NAME);\n } catch (e) {\n // Safari/iOS browsers throw occasional exceptions on\n // db.createObjectStore() that may be a bug. Avoid blocking\n // the rest of the app functionality.\n console.warn(e);\n }\n }\n }\n }).catch(e => {\n throw ERROR_FACTORY.create(AppError.IDB_OPEN, {\n originalErrorMessage: e.message\n });\n });\n }\n return dbPromise;\n}\n\nexport async function readHeartbeatsFromIndexedDB(\n app: FirebaseApp\n): Promise<HeartbeatsInIndexedDB | undefined> {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME);\n const result = await tx.objectStore(STORE_NAME).get(computeKey(app));\n // We already have the value but tx.done can throw,\n // so we need to await it here to catch errors\n await tx.done;\n return result;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_GET, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nexport async function writeHeartbeatsToIndexedDB(\n app: FirebaseApp,\n heartbeatObject: HeartbeatsInIndexedDB\n): Promise<void> {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(STORE_NAME);\n await objectStore.put(heartbeatObject, computeKey(app));\n await tx.done;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_WRITE, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nfunction computeKey(app: FirebaseApp): string {\n return `${app.name}!${app.options.appId}`;\n}\n","/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentContainer } from '@firebase/component';\nimport {\n base64urlEncodeWithoutPadding,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\nimport {\n readHeartbeatsFromIndexedDB,\n writeHeartbeatsToIndexedDB\n} from './indexeddb';\nimport { FirebaseApp } from './public-types';\nimport {\n HeartbeatsByUserAgent,\n HeartbeatService,\n HeartbeatsInIndexedDB,\n HeartbeatStorage,\n SingleDateHeartbeat\n} from './types';\n\nconst MAX_HEADER_BYTES = 1024;\n// 30 days\nconst STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;\n\nexport class HeartbeatServiceImpl implements HeartbeatService {\n /**\n * The persistence layer for heartbeats\n * Leave public for easier testing.\n */\n _storage: HeartbeatStorageImpl;\n\n /**\n * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate\n * the header string.\n * Stores one record per date. This will be consolidated into the standard\n * format of one record per user agent string before being sent as a header.\n * Populated from indexedDB when the controller is instantiated and should\n * be kept in sync with indexedDB.\n * Leave public for easier testing.\n */\n _heartbeatsCache: HeartbeatsInIndexedDB | null = null;\n\n /**\n * the initialization promise for populating heartbeatCache.\n * If getHeartbeatsHeader() is called before the promise resolves\n * (hearbeatsCache == null), it should wait for this promise\n * Leave public for easier testing.\n */\n _heartbeatsCachePromise: Promise<HeartbeatsInIndexedDB>;\n constructor(private readonly container: ComponentContainer) {\n const app = this.container.getProvider('app').getImmediate();\n this._storage = new HeartbeatStorageImpl(app);\n this._heartbeatsCachePromise = this._storage.read().then(result => {\n this._heartbeatsCache = result;\n return result;\n });\n }\n\n /**\n * Called to report a heartbeat. The function will generate\n * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it\n * to IndexedDB.\n * Note that we only store one heartbeat per day. So if a heartbeat for today is\n * already logged, subsequent calls to this function in the same day will be ignored.\n */\n async triggerHeartbeat(): Promise<void> {\n const platformLogger = this.container\n .getProvider('platform-logger')\n .getImmediate();\n\n // This is the \"Firebase user agent\" string from the platform logger\n // service, not the browser user agent.\n const agent = platformLogger.getPlatformInfoString();\n const date = getUTCDateString();\n if (this._heartbeatsCache?.heartbeats == null) {\n this._heartbeatsCache = await this._heartbeatsCachePromise;\n // If we failed to construct a heartbeats cache, then return immediately.\n if (this._heartbeatsCache?.heartbeats == null) {\n return;\n }\n }\n // Do not store a heartbeat if one is already stored for this day\n // or if a header has already been sent today.\n if (\n this._heartbeatsCache.lastSentHeartbeatDate === date ||\n this._heartbeatsCache.heartbeats.some(\n singleDateHeartbeat => singleDateHeartbeat.date === date\n )\n ) {\n return;\n } else {\n // There is no entry for this date. Create one.\n this._heartbeatsCache.heartbeats.push({ date, agent });\n }\n // Remove entries older than 30 days.\n this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(\n singleDateHeartbeat => {\n const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();\n const now = Date.now();\n return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;\n }\n );\n return this._storage.overwrite(this._heartbeatsCache);\n }\n\n /**\n * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.\n * It also clears all heartbeats from memory as well as in IndexedDB.\n *\n * NOTE: Consuming product SDKs should not send the header if this method\n * returns an empty string.\n */\n async getHeartbeatsHeader(): Promise<string> {\n if (this._heartbeatsCache === null) {\n await this._heartbeatsCachePromise;\n }\n // If it's still null or the array is empty, there is no data to send.\n if (\n this._heartbeatsCache?.heartbeats == null ||\n this._heartbeatsCache.heartbeats.length === 0\n ) {\n return '';\n }\n const date = getUTCDateString();\n // Extract as many heartbeats from the cache as will fit under the size limit.\n const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(\n this._heartbeatsCache.heartbeats\n );\n const headerString = base64urlEncodeWithoutPadding(\n JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })\n );\n // Store last sent date to prevent another being logged/sent for the same day.\n this._heartbeatsCache.lastSentHeartbeatDate = date;\n if (unsentEntries.length > 0) {\n // Store any unsent entries if they exist.\n this._heartbeatsCache.heartbeats = unsentEntries;\n // This seems more likely than emptying the array (below) to lead to some odd state\n // since the cache isn't empty and this will be called again on the next request,\n // and is probably safest if we await it.\n await this._storage.overwrite(this._heartbeatsCache);\n } else {\n this._heartbeatsCache.heartbeats = [];\n // Do not wait for this, to reduce latency.\n void this._storage.overwrite(this._heartbeatsCache);\n }\n return headerString;\n }\n}\n\nfunction getUTCDateString(): string {\n const today = new Date();\n // Returns date format 'YYYY-MM-DD'\n return today.toISOString().substring(0, 10);\n}\n\nexport function extractHeartbeatsForHeader(\n heartbeatsCache: SingleDateHeartbeat[],\n maxSize = MAX_HEADER_BYTES\n): {\n heartbeatsToSend: HeartbeatsByUserAgent[];\n unsentEntries: SingleDateHeartbeat[];\n} {\n // Heartbeats grouped by user agent in the standard format to be sent in\n // the header.\n const heartbeatsToSend: HeartbeatsByUserAgent[] = [];\n // Single date format heartbeats that are not sent.\n let unsentEntries = heartbeatsCache.slice();\n for (const singleDateHeartbeat of heartbeatsCache) {\n // Look for an existing entry with the same user agent.\n const heartbeatEntry = heartbeatsToSend.find(\n hb => hb.agent === singleDateHeartbeat.agent\n );\n if (!heartbeatEntry) {\n // If no entry for this user agent exists, create one.\n heartbeatsToSend.push({\n agent: singleDateHeartbeat.agent,\n dates: [singleDateHeartbeat.date]\n });\n if (countBytes(heartbeatsToSend) > maxSize) {\n // If the header would exceed max size, remove the added heartbeat\n // entry and stop adding to the header.\n heartbeatsToSend.pop();\n break;\n }\n } else {\n heartbeatEntry.dates.push(singleDateHeartbeat.date);\n // If the header would exceed max size, remove the added date\n // and stop adding to the header.\n if (countBytes(heartbeatsToSend) > maxSize) {\n heartbeatEntry.dates.pop();\n break;\n }\n }\n // Pop unsent entry from queue. (Skipped if adding the entry exceeded\n // quota and the loop breaks early.)\n unsentEntries = unsentEntries.slice(1);\n }\n return {\n heartbeatsToSend,\n unsentEntries\n };\n}\n\nexport class HeartbeatStorageImpl implements HeartbeatStorage {\n private _canUseIndexedDBPromise: Promise<boolean>;\n constructor(public app: FirebaseApp) {\n this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();\n }\n async runIndexedDBEnvironmentCheck(): Promise<boolean> {\n if (!isIndexedDBAvailable()) {\n return false;\n } else {\n return validateIndexedDBOpenable()\n .then(() => true)\n .catch(() => false);\n }\n }\n /**\n * Read all heartbeats.\n */\n async read(): Promise<HeartbeatsInIndexedDB> {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return { heartbeats: [] };\n } else {\n const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);\n if (idbHeartbeatObject?.heartbeats) {\n return idbHeartbeatObject;\n } else {\n return { heartbeats: [] };\n }\n }\n }\n // overwrite the storage with the provided heartbeats\n async overwrite(heartbeatsObject: HeartbeatsInIndexedDB): Promise<void> {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: heartbeatsObject.heartbeats\n });\n }\n }\n // add heartbeats\n async add(heartbeatsObject: HeartbeatsInIndexedDB): Promise<void> {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: [\n ...existingHeartbeatsObject.heartbeats,\n ...heartbeatsObject.heartbeats\n ]\n });\n }\n }\n}\n\n/**\n * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped\n * in a platform logging header JSON object, stringified, and converted\n * to base 64.\n */\nexport function countBytes(heartbeatsCache: HeartbeatsByUserAgent[]): number {\n // base64 has a restricted set of characters, all of which should be 1 byte.\n return base64urlEncodeWithoutPadding(\n // heartbeatsCache wrapper properties\n JSON.stringify({ version: 2, heartbeats: heartbeatsCache })\n ).length;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerServiceImpl } from './platformLoggerService';\nimport { name, version } from '../package.json';\nimport { _registerComponent } from './internal';\nimport { registerVersion } from './api';\nimport { HeartbeatServiceImpl } from './heartbeatService';\n\nexport function registerCoreComponents(variant?: string): void {\n _registerComponent(\n new Component(\n 'platform-logger',\n container => new PlatformLoggerServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n _registerComponent(\n new Component(\n 'heartbeat',\n container => new HeartbeatServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n\n // Register `app` package.\n registerVersion(name, version, variant);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n // Register platform SDK identifier (no version).\n registerVersion('fire-js', '');\n}\n","/**\n * Firebase App\n *\n * @remarks This package coordinates the communication between the different Firebase components\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerCoreComponents } from './registerCoreComponents';\n\nexport * from './api';\nexport * from './internal';\nexport * from './public-types';\n\nregisterCoreComponents('__RUNTIME_ENV__');\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '../public-types';\nimport { _FirebaseNamespace, _FirebaseService } from '../types';\nimport {\n deleteApp,\n _addComponent,\n _DEFAULT_ENTRY_NAME,\n _FirebaseAppInternal as FirebaseAppExp\n} from '@firebase/app';\nimport { Component, ComponentType, Name } from '@firebase/component';\nimport { Compat } from '@firebase/util';\n\n/**\n * Global context object for a collection of services using\n * a shared authentication state.\n */\nexport class FirebaseAppLiteImpl\n implements FirebaseApp, Compat<FirebaseAppExp>\n{\n constructor(\n readonly _delegate: FirebaseAppExp,\n private readonly firebase: _FirebaseNamespace\n ) {\n // add itself to container\n _addComponent(\n _delegate,\n new Component('app-compat', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n return this._delegate.automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val) {\n this.automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n return this._delegate.name;\n }\n\n get options(): FirebaseOptions {\n return this._delegate.options;\n }\n\n delete(): Promise<void> {\n this.firebase.INTERNAL.removeApp(this.name);\n return deleteApp(this._delegate);\n }\n\n /**\n * Return a service instance associated with this app (creating it\n * on demand), identified by the passed instanceIdentifier.\n *\n * NOTE: Currently storage is the only one that is leveraging this\n * functionality. They invoke it by calling:\n *\n * ```javascript\n * firebase.app().storage('STORAGE BUCKET ID')\n * ```\n *\n * The service name is passed to this already\n * @internal\n */\n _getService(\n name: string,\n instanceIdentifier: string = _DEFAULT_ENTRY_NAME\n ): _FirebaseService {\n this._delegate.checkDestroyed();\n\n // getImmediate will always succeed because _getService is only called for registered components.\n return this._delegate.container.getProvider(name as Name).getImmediate({\n identifier: instanceIdentifier\n }) as unknown as _FirebaseService;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n INVALID_APP_ARGUMENT = 'invalid-app-argument'\n}\n\nconst ERRORS: ErrorMap<AppError> = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call Firebase App.initializeApp()',\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.'\n};\n\ntype ErrorParams = { [key in AppError]: { appName: string } };\n\nexport const ERROR_FACTORY = new ErrorFactory<AppError, ErrorParams>(\n 'app-compat',\n 'Firebase',\n ERRORS\n);\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from './public-types';\nimport {\n _FirebaseNamespace,\n _FirebaseService,\n FirebaseServiceNamespace\n} from './types';\nimport * as modularAPIs from '@firebase/app';\nimport { _FirebaseAppInternal as _FirebaseAppExp } from '@firebase/app';\nimport { Component, ComponentType, Name } from '@firebase/component';\n\nimport { deepExtend, contains } from '@firebase/util';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport { FirebaseAppLiteImpl } from './lite/firebaseAppLite';\n\n/**\n * Because auth can't share code with other components, we attach the utility functions\n * in an internal namespace to share code.\n * This function return a firebase namespace object without\n * any utility functions, so it can be shared between the regular firebaseNamespace and\n * the lite version.\n */\nexport function createFirebaseNamespaceCore(\n firebaseAppImpl: typeof FirebaseAppImpl | typeof FirebaseAppLiteImpl\n): _FirebaseNamespace {\n const apps: { [name: string]: FirebaseApp } = {};\n // // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // const components = new Map<string, Component<any>>();\n\n // A namespace is a plain JavaScript Object.\n const namespace: _FirebaseNamespace = {\n // Hack to prevent Babel from modifying the object returned\n // as the firebase namespace.\n // @ts-ignore\n __esModule: true,\n initializeApp: initializeAppCompat,\n // @ts-ignore\n app,\n registerVersion: modularAPIs.registerVersion,\n setLogLevel: modularAPIs.setLogLevel,\n onLog: modularAPIs.onLog,\n // @ts-ignore\n apps: null,\n SDK_VERSION: modularAPIs.SDK_VERSION,\n INTERNAL: {\n registerComponent: registerComponentCompat,\n removeApp,\n useAsService,\n modularAPIs\n }\n };\n\n // Inject a circular default export to allow Babel users who were previously\n // using:\n //\n // import firebase from 'firebase';\n // which becomes: var firebase = require('firebase').default;\n //\n // instead of\n //\n // import * as firebase from 'firebase';\n // which becomes: var firebase = require('firebase');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (namespace as any)['default'] = namespace;\n\n // firebase.apps is a read-only getter.\n Object.defineProperty(namespace, 'apps', {\n get: getApps\n });\n\n /**\n * Called by App.delete() - but before any services associated with the App\n * are deleted.\n */\n function removeApp(name: string): void {\n delete apps[name];\n }\n\n /**\n * Get the App object for a given name (or DEFAULT).\n */\n function app(name?: string): FirebaseApp {\n name = name || modularAPIs._DEFAULT_ENTRY_NAME;\n if (!contains(apps, name)) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n return apps[name];\n }\n\n // @ts-ignore\n app['App'] = firebaseAppImpl;\n\n /**\n * Create a new App instance (name must be unique).\n *\n * This function is idempotent. It can be called more than once and return the same instance using the same options and config.\n */\n function initializeAppCompat(\n options: FirebaseOptions,\n rawConfig = {}\n ): FirebaseApp {\n const app = modularAPIs.initializeApp(\n options,\n rawConfig\n ) as _FirebaseAppExp;\n\n if (contains(apps, app.name)) {\n return apps[app.name];\n }\n\n const appCompat = new firebaseAppImpl(app, namespace);\n apps[app.name] = appCompat;\n return appCompat;\n }\n\n /*\n * Return an array of all the non-deleted FirebaseApps.\n */\n function getApps(): FirebaseApp[] {\n // Make a copy so caller cannot mutate the apps list.\n return Object.keys(apps).map(name => apps[name]);\n }\n\n function registerComponentCompat<T extends Name>(\n component: Component<T>\n ): FirebaseServiceNamespace<_FirebaseService> | null {\n const componentName = component.name;\n const componentNameWithoutCompat = componentName.replace('-compat', '');\n if (\n modularAPIs._registerComponent(component) &&\n component.type === ComponentType.PUBLIC\n ) {\n // create service namespace for public components\n // The Service namespace is an accessor function ...\n const serviceNamespace = (\n appArg: FirebaseApp = app()\n ): _FirebaseService => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (typeof (appArg as any)[componentNameWithoutCompat] !== 'function') {\n // Invalid argument.\n // This happens in the following case: firebase.storage('gs:/')\n throw ERROR_FACTORY.create(AppError.INVALID_APP_ARGUMENT, {\n appName: componentName\n });\n }\n\n // Forward service instance lookup to the FirebaseApp.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (appArg as any)[componentNameWithoutCompat]();\n };\n\n // ... and a container for service-level properties.\n if (component.serviceProps !== undefined) {\n deepExtend(serviceNamespace, component.serviceProps);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (namespace as any)[componentNameWithoutCompat] = serviceNamespace;\n\n // Patch the FirebaseAppImpl prototype\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (firebaseAppImpl.prototype as any)[componentNameWithoutCompat] =\n // TODO: The eslint disable can be removed and the 'ignoreRestArgs'\n // option added to the no-explicit-any rule when ESlint releases it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function (...args: any) {\n const serviceFxn = this._getService.bind(this, componentName);\n return serviceFxn.apply(\n this,\n component.multipleInstances ? args : []\n );\n };\n }\n\n return component.type === ComponentType.PUBLIC\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (namespace as any)[componentNameWithoutCompat]\n : null;\n }\n\n // Map the requested service to a registered service name\n // (used to map auth to serverAuth service when needed).\n function useAsService(app: FirebaseApp, name: string): string | null {\n if (name === 'serverAuth') {\n return null;\n }\n\n const useService = name;\n\n return useService;\n }\n\n return namespace;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createFirebaseNamespaceLite } from './lite/firebaseNamespaceLite';\nimport { registerCoreComponents } from './registerCoreComponents';\n\nconst firebase = createFirebaseNamespaceLite();\n\nregisterCoreComponents('lite');\n\n// eslint-disable-next-line import/no-default-export\nexport default firebase;\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseNamespace } from '../public-types';\nimport { FirebaseServiceNamespace, _FirebaseService } from '../types';\nimport { FirebaseAppLiteImpl } from './firebaseAppLite';\nimport { createFirebaseNamespaceCore } from '../firebaseNamespaceCore';\nimport { Component, ComponentType } from '@firebase/component';\n\nexport function createFirebaseNamespaceLite(): FirebaseNamespace {\n const namespace = createFirebaseNamespaceCore(FirebaseAppLiteImpl);\n\n namespace.SDK_VERSION = `${namespace.SDK_VERSION}_LITE`;\n\n const registerComponent = namespace.INTERNAL.registerComponent;\n namespace.INTERNAL.registerComponent = registerComponentForLite;\n\n /**\n * This is a special implementation, so it only works with performance.\n * only allow performance SDK to register.\n */\n function registerComponentForLite(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n component: Component<any>\n ): FirebaseServiceNamespace<_FirebaseService> | null {\n // only allow performance to register with firebase lite\n if (\n component.type === ComponentType.PUBLIC &&\n !component.name.includes('performance') &&\n !component.name.includes('installations')\n ) {\n throw Error(`${name} cannot register with the standalone perf instance`);\n }\n\n return registerComponent(component);\n }\n\n return namespace;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerVersion } from '@firebase/app';\n\nimport { name, version } from '../package.json';\n\nexport function registerCoreComponents(variant?: string): void {\n // Register `app` package.\n registerVersion(name, version, variant);\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport firebase from '@firebase/app-compat';\nimport { name, version } from '../../package.json';\n\nfirebase.registerVersion(name, version, 'app-compat');\n\nexport default firebase;\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make Typescript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<ErrorCode, ErrorParams>(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { AppConfig } from '../interfaces/installation-impl';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise<FirebaseError> {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise<Response>\n): Promise<Response> {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || (self as unknown as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { IdChangeCallbackFn } from '../api';\n\nconst fidChangeCallbacks: Map<string, Set<IdChangeCallbackFn>> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, openDB } from 'idb';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\ninterface InstallationsDB extends DBSchema {\n 'firebase-installations-store': {\n key: string;\n value: InstallationEntry | undefined;\n };\n}\n\nlet dbPromise: Promise<IDBPDatabase<InstallationsDB>> | null = null;\nfunction getDbPromise(): Promise<IDBPDatabase<InstallationsDB>> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise<InstallationEntry | undefined> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key) as Promise<InstallationEntry>;\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set<ValueType extends InstallationEntry>(\n appConfig: AppConfig,\n value: ValueType\n): Promise<ValueType> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = (await objectStore.get(key)) as InstallationEntry;\n await objectStore.put(value, key);\n await tx.done;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise<void> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update<ValueType extends InstallationEntry | undefined>(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise<ValueType> {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = (await store.get(\n key\n )) as InstallationEntry;\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.done;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise<void> {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.done;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createInstallationRequest } from '../functions/create-installation-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise<RegisteredInstallationEntry>;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n installations: FirebaseInstallationsImpl\n): Promise<InstallationEntryWithRegistrationPromise> {\n let registrationPromise: Promise<RegisteredInstallationEntry> | undefined;\n\n const installationEntry = await update(installations.appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n installations,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n installations: FirebaseInstallationsImpl,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n installations,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(installations)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n installations: FirebaseInstallationsImpl,\n installationEntry: InProgressInstallationEntry\n): Promise<RegisteredInstallationEntry> {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n installations,\n installationEntry\n );\n return set(installations.appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(installations.appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n installations: FirebaseInstallationsImpl\n): Promise<RegisteredInstallationEntry> {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(\n installations.appConfig\n );\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(installations.appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const { installationEntry, registrationPromise } =\n await getInstallationEntry(installations);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise<InstallationEntry> {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\n\nexport async function createInstallationRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n { fid }: InProgressInstallationEntry\n): Promise<RegisteredInstallationEntry> {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport {\n FirebaseInstallationsImpl,\n AppConfig\n} from '../interfaces/installation-impl';\n\nexport async function generateAuthTokenRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise<CompletedAuthToken> {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION,\n appId: appConfig.appId\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken =\n extractAuthTokenInfoFromResponse(responseValue);\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateAuthTokenRequest } from '../functions/generate-auth-token-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n installations: FirebaseInstallationsImpl,\n forceRefresh = false\n): Promise<CompletedAuthToken> {\n let tokenPromise: Promise<CompletedAuthToken> | undefined;\n const entry = await update(installations.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n installations: FirebaseInstallationsImpl,\n forceRefresh: boolean\n): Promise<CompletedAuthToken> {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(installations.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(installations.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(installations, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise<RegisteredInstallationEntry> {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n installations: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise<CompletedAuthToken> {\n try {\n const authToken = await generateAuthTokenRequest(\n installations,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(installations.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(installations.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns a Firebase Installations auth token, identifying the current\n * Firebase Installation.\n * @param installations - The `Installations` instance.\n * @param forceRefresh - Force refresh regardless of token expiration.\n *\n * @public\n */\nexport async function getToken(\n installations: Installations,\n forceRefresh = false\n): Promise<string> {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n await completeInstallationRegistration(installationsImpl);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(installationsImpl, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n installations: FirebaseInstallationsImpl\n): Promise<void> {\n const { registrationPromise } = await getInstallationEntry(installations);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array<keyof FirebaseOptions> = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _registerComponent, _getProvider } from '@firebase/app';\nimport {\n Component,\n ComponentType,\n InstanceFactory,\n ComponentContainer\n} from '@firebase/component';\nimport { getId, getToken } from '../api/index';\nimport { _FirebaseInstallationsInternal } from '../interfaces/public-types';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { extractAppConfig } from '../helpers/extract-app-config';\n\nconst INSTALLATIONS_NAME = 'installations';\nconst INSTALLATIONS_NAME_INTERNAL = 'installations-internal';\n\nconst publicFactory: InstanceFactory<'installations'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const heartbeatServiceProvider = _getProvider(app, 'heartbeat');\n\n const installationsImpl: FirebaseInstallationsImpl = {\n app,\n appConfig,\n heartbeatServiceProvider,\n _delete: () => Promise.resolve()\n };\n return installationsImpl;\n};\n\nconst internalFactory: InstanceFactory<'installations-internal'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Internal FIS instance relies on public FIS instance.\n const installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();\n\n const installationsInternal: _FirebaseInstallationsInternal = {\n getId: () => getId(installations),\n getToken: (forceRefresh?: boolean) => getToken(installations, forceRefresh)\n };\n return installationsInternal;\n};\n\nexport function registerInstallations(): void {\n _registerComponent(\n new Component(INSTALLATIONS_NAME, publicFactory, ComponentType.PUBLIC)\n );\n _registerComponent(\n new Component(\n INSTALLATIONS_NAME_INTERNAL,\n internalFactory,\n ComponentType.PRIVATE\n )\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Creates a Firebase Installation if there isn't one for the app and\n * returns the Installation ID.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function getId(installations: Installations): Promise<string> {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n installationsImpl\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(installationsImpl).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n","/**\n * The Firebase Installations Web SDK.\n * This SDK does not work in a Node.js environment.\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerInstallations } from './functions/config';\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nexport * from './api';\nexport * from './interfaces/public-types';\n\nregisterInstallations();\nregisterVersion(name, version);\n// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\nregisterVersion(name, version, '__BUILD_TARGET__');\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../package.json';\n\nexport const SDK_VERSION = version;\n/** The prefix for start User Timing marks used for creating Traces. */\nexport const TRACE_START_MARK_PREFIX = 'FB-PERF-TRACE-START';\n/** The prefix for stop User Timing marks used for creating Traces. */\nexport const TRACE_STOP_MARK_PREFIX = 'FB-PERF-TRACE-STOP';\n/** The prefix for User Timing measure used for creating Traces. */\nexport const TRACE_MEASURE_PREFIX = 'FB-PERF-TRACE-MEASURE';\n/** The prefix for out of the box page load Trace name. */\nexport const OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_';\n\nexport const FIRST_PAINT_COUNTER_NAME = '_fp';\n\nexport const FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp';\n\nexport const FIRST_INPUT_DELAY_COUNTER_NAME = '_fid';\n\nexport const CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config';\n\nexport const CONFIG_EXPIRY_LOCAL_STORAGE_KEY =\n '@firebase/performance/configexpire';\n\nexport const SERVICE = 'performance';\nexport const SERVICE_NAME = 'Performance';\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from '../constants';\n\nexport const enum ErrorCode {\n TRACE_STARTED_BEFORE = 'trace started',\n TRACE_STOPPED_BEFORE = 'trace stopped',\n NONPOSITIVE_TRACE_START_TIME = 'nonpositive trace startTime',\n NONPOSITIVE_TRACE_DURATION = 'nonpositive trace duration',\n NO_WINDOW = 'no window',\n NO_APP_ID = 'no app id',\n NO_PROJECT_ID = 'no project id',\n NO_API_KEY = 'no api key',\n INVALID_CC_LOG = 'invalid cc log',\n FB_NOT_DEFAULT = 'FB not default',\n RC_NOT_OK = 'RC response not ok',\n INVALID_ATTRIBUTE_NAME = 'invalid attribute name',\n INVALID_ATTRIBUTE_VALUE = 'invalid attribute value',\n INVALID_CUSTOM_METRIC_NAME = 'invalid custom metric name',\n INVALID_STRING_MERGER_PARAMETER = 'invalid String merger input',\n ALREADY_INITIALIZED = 'already initialized'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.TRACE_STARTED_BEFORE]: 'Trace {$traceName} was started before.',\n [ErrorCode.TRACE_STOPPED_BEFORE]: 'Trace {$traceName} is not running.',\n [ErrorCode.NONPOSITIVE_TRACE_START_TIME]:\n 'Trace {$traceName} startTime should be positive.',\n [ErrorCode.NONPOSITIVE_TRACE_DURATION]:\n 'Trace {$traceName} duration should be positive.',\n [ErrorCode.NO_WINDOW]: 'Window is not available.',\n [ErrorCode.NO_APP_ID]: 'App id is not available.',\n [ErrorCode.NO_PROJECT_ID]: 'Project id is not available.',\n [ErrorCode.NO_API_KEY]: 'Api key is not available.',\n [ErrorCode.INVALID_CC_LOG]: 'Attempted to queue invalid cc event',\n [ErrorCode.FB_NOT_DEFAULT]:\n 'Performance can only start when Firebase app instance is the default one.',\n [ErrorCode.RC_NOT_OK]: 'RC response is not ok',\n [ErrorCode.INVALID_ATTRIBUTE_NAME]:\n 'Attribute name {$attributeName} is invalid.',\n [ErrorCode.INVALID_ATTRIBUTE_VALUE]:\n 'Attribute value {$attributeValue} is invalid.',\n [ErrorCode.INVALID_CUSTOM_METRIC_NAME]:\n 'Custom metric name {$customMetricName} is invalid',\n [ErrorCode.INVALID_STRING_MERGER_PARAMETER]:\n 'Input for String merger is invalid, contact support team to resolve.',\n [ErrorCode.ALREADY_INITIALIZED]:\n 'initializePerformance() has already been called with ' +\n 'different options. To avoid this error, call initializePerformance() with the ' +\n 'same options as when it was originally called, or call getPerformance() to return the' +\n ' already initialized instance.'\n};\n\ninterface ErrorParams {\n [ErrorCode.TRACE_STARTED_BEFORE]: { traceName: string };\n [ErrorCode.TRACE_STOPPED_BEFORE]: { traceName: string };\n [ErrorCode.NONPOSITIVE_TRACE_START_TIME]: { traceName: string };\n [ErrorCode.NONPOSITIVE_TRACE_DURATION]: { traceName: string };\n [ErrorCode.INVALID_ATTRIBUTE_NAME]: { attributeName: string };\n [ErrorCode.INVALID_ATTRIBUTE_VALUE]: { attributeValue: string };\n [ErrorCode.INVALID_CUSTOM_METRIC_NAME]: { customMetricName: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory<ErrorCode, ErrorParams>(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger, LogLevel } from '@firebase/logger';\nimport { SERVICE_NAME } from '../constants';\n\nexport const consoleLogger = new Logger(SERVICE_NAME);\nconsoleLogger.logLevel = LogLevel.INFO;\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport { isIndexedDBAvailable, areCookiesEnabled } from '@firebase/util';\nimport { consoleLogger } from '../utils/console_logger';\n\ndeclare global {\n interface Window {\n PerformanceObserver: typeof PerformanceObserver;\n perfMetrics?: { onFirstInputDelay(fn: (fid: number) => void): void };\n }\n}\n\nlet apiInstance: Api | undefined;\nlet windowInstance: Window | undefined;\n\nexport type EntryType =\n | 'mark'\n | 'measure'\n | 'paint'\n | 'resource'\n | 'frame'\n | 'navigation';\n\n/**\n * This class holds a reference to various browser related objects injected by\n * set methods.\n */\nexport class Api {\n private readonly performance: Performance;\n /** PreformanceObserver constructor function. */\n private readonly PerformanceObserver: typeof PerformanceObserver;\n private readonly windowLocation: Location;\n readonly onFirstInputDelay?: (fn: (fid: number) => void) => void;\n readonly localStorage?: Storage;\n readonly document: Document;\n readonly navigator: Navigator;\n\n constructor(readonly window?: Window) {\n if (!window) {\n throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW);\n }\n this.performance = window.performance;\n this.PerformanceObserver = window.PerformanceObserver;\n this.windowLocation = window.location;\n this.navigator = window.navigator;\n this.document = window.document;\n if (this.navigator && this.navigator.cookieEnabled) {\n // If user blocks cookies on the browser, accessing localStorage will\n // throw an exception.\n this.localStorage = window.localStorage;\n }\n if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {\n this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;\n }\n }\n\n getUrl(): string {\n // Do not capture the string query part of url.\n return this.windowLocation.href.split('?')[0];\n }\n\n mark(name: string): void {\n if (!this.performance || !this.performance.mark) {\n return;\n }\n this.performance.mark(name);\n }\n\n measure(measureName: string, mark1: string, mark2: string): void {\n if (!this.performance || !this.performance.measure) {\n return;\n }\n this.performance.measure(measureName, mark1, mark2);\n }\n\n getEntriesByType(type: EntryType): PerformanceEntry[] {\n if (!this.performance || !this.performance.getEntriesByType) {\n return [];\n }\n return this.performance.getEntriesByType(type);\n }\n\n getEntriesByName(name: string): PerformanceEntry[] {\n if (!this.performance || !this.performance.getEntriesByName) {\n return [];\n }\n return this.performance.getEntriesByName(name);\n }\n\n getTimeOrigin(): number {\n // Polyfill the time origin with performance.timing.navigationStart.\n return (\n this.performance &&\n (this.performance.timeOrigin || this.performance.timing.navigationStart)\n );\n }\n\n requiredApisAvailable(): boolean {\n if (!fetch || !Promise || !areCookiesEnabled()) {\n consoleLogger.info(\n 'Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.'\n );\n return false;\n }\n\n if (!isIndexedDBAvailable()) {\n consoleLogger.info('IndexedDB is not supported by current browser');\n return false;\n }\n return true;\n }\n\n setupObserver(\n entryType: EntryType,\n callback: (entry: PerformanceEntry) => void\n ): void {\n if (!this.PerformanceObserver) {\n return;\n }\n const observer = new this.PerformanceObserver(list => {\n for (const entry of list.getEntries()) {\n // `entry` is a PerformanceEntry instance.\n callback(entry);\n }\n });\n\n // Start observing the entry types you care about.\n observer.observe({ entryTypes: [entryType] });\n }\n\n static getInstance(): Api {\n if (apiInstance === undefined) {\n apiInstance = new Api(windowInstance);\n }\n return apiInstance;\n }\n}\n\nexport function setupApi(window: Window): void {\n windowInstance = window;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\n\nlet iid: string | undefined;\nlet authToken: string | undefined;\n\nexport function getIidPromise(\n installationsService: _FirebaseInstallationsInternal\n): Promise<string> {\n const iidPromise = installationsService.getId();\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n iidPromise.then((iidVal: string) => {\n iid = iidVal;\n });\n return iidPromise;\n}\n\n// This method should be used after the iid is retrieved by getIidPromise method.\nexport function getIid(): string | undefined {\n return iid;\n}\n\nexport function getAuthTokenPromise(\n installationsService: _FirebaseInstallationsInternal\n): Promise<string> {\n const authTokenPromise = installationsService.getToken();\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n authTokenPromise.then((authTokenVal: string) => {\n authToken = authTokenVal;\n });\n return authTokenPromise;\n}\n\nexport function getAuthenticationToken(): string | undefined {\n return authToken;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { mergeStrings } from '../utils/string_merger';\n\nlet settingsServiceInstance: SettingsService | undefined;\n\nexport class SettingsService {\n // The variable which controls logging of automatic traces and HTTP/S network monitoring.\n instrumentationEnabled = true;\n\n // The variable which controls logging of custom traces.\n dataCollectionEnabled = true;\n\n // Configuration flags set through remote config.\n loggingEnabled = false;\n // Sampling rate between 0 and 1.\n tracesSamplingRate = 1;\n networkRequestsSamplingRate = 1;\n\n // Address of logging service.\n logEndPointUrl =\n 'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto';\n // Performance event transport endpoint URL which should be compatible with proto3.\n // New Address for transport service, not configurable via Remote Config.\n flTransportEndpointUrl = mergeStrings(\n 'hts/frbslgigp.ogepscmv/ieo/eaylg',\n 'tp:/ieaeogn-agolai.o/1frlglgc/o'\n );\n\n transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV');\n\n // Source type for performance event logs.\n logSource = 462;\n\n // Flags which control per session logging of traces and network requests.\n logTraceAfterSampling = false;\n logNetworkAfterSampling = false;\n\n // TTL of config retrieved from remote config in hours.\n configTimeToLive = 12;\n\n getFlTransportFullUrl(): string {\n return this.flTransportEndpointUrl.concat('?key=', this.transportKey);\n }\n\n static getInstance(): SettingsService {\n if (settingsServiceInstance === undefined) {\n settingsServiceInstance = new SettingsService();\n }\n return settingsServiceInstance;\n }\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from './errors';\n\nexport function mergeStrings(part1: string, part2: string): string {\n const sizeDiff = part1.length - part2.length;\n if (sizeDiff < 0 || sizeDiff > 1) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_STRING_MERGER_PARAMETER);\n }\n\n const resultArray = [];\n for (let i = 0; i < part1.length; i++) {\n resultArray.push(part1.charAt(i));\n if (part2.length > i) {\n resultArray.push(part2.charAt(i));\n }\n }\n\n return resultArray.join('');\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Api } from '../services/api_service';\n\n// The values and orders of the following enums should not be changed.\nconst enum ServiceWorkerStatus {\n UNKNOWN = 0,\n UNSUPPORTED = 1,\n CONTROLLED = 2,\n UNCONTROLLED = 3\n}\n\nexport enum VisibilityState {\n UNKNOWN = 0,\n VISIBLE = 1,\n HIDDEN = 2\n}\n\nconst enum EffectiveConnectionType {\n UNKNOWN = 0,\n CONNECTION_SLOW_2G = 1,\n CONNECTION_2G = 2,\n CONNECTION_3G = 3,\n CONNECTION_4G = 4\n}\n\n/**\n * NetworkInformation\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation\n */\ninterface NetworkInformationWithEffectiveType extends NetworkInformation {\n // `effectiveType` is an experimental property and not included in\n // TypeScript's typings for the native NetworkInformation interface\n readonly effectiveType?: 'slow-2g' | '2g' | '3g' | '4g';\n}\n\ninterface NavigatorWithConnection extends Navigator {\n readonly connection: NetworkInformationWithEffectiveType;\n}\n\nconst RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_'];\nconst ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\\\w*$');\nconst MAX_ATTRIBUTE_NAME_LENGTH = 40;\nconst MAX_ATTRIBUTE_VALUE_LENGTH = 100;\n\nexport function getServiceWorkerStatus(): ServiceWorkerStatus {\n const navigator = Api.getInstance().navigator;\n if (navigator?.serviceWorker) {\n if (navigator.serviceWorker.controller) {\n return ServiceWorkerStatus.CONTROLLED;\n } else {\n return ServiceWorkerStatus.UNCONTROLLED;\n }\n } else {\n return ServiceWorkerStatus.UNSUPPORTED;\n }\n}\n\nexport function getVisibilityState(): VisibilityState {\n const document = Api.getInstance().document;\n const visibilityState = document.visibilityState;\n switch (visibilityState) {\n case 'visible':\n return VisibilityState.VISIBLE;\n case 'hidden':\n return VisibilityState.HIDDEN;\n default:\n return VisibilityState.UNKNOWN;\n }\n}\n\nexport function getEffectiveConnectionType(): EffectiveConnectionType {\n const navigator = Api.getInstance().navigator;\n const navigatorConnection = (navigator as NavigatorWithConnection).connection;\n const effectiveType =\n navigatorConnection && navigatorConnection.effectiveType;\n switch (effectiveType) {\n case 'slow-2g':\n return EffectiveConnectionType.CONNECTION_SLOW_2G;\n case '2g':\n return EffectiveConnectionType.CONNECTION_2G;\n case '3g':\n return EffectiveConnectionType.CONNECTION_3G;\n case '4g':\n return EffectiveConnectionType.CONNECTION_4G;\n default:\n return EffectiveConnectionType.UNKNOWN;\n }\n}\n\nexport function isValidCustomAttributeName(name: string): boolean {\n if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) {\n return false;\n }\n const matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(prefix =>\n name.startsWith(prefix)\n );\n return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX);\n}\n\nexport function isValidCustomAttributeValue(value: string): boolean {\n return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_LENGTH;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from './errors';\nimport { FirebaseApp } from '@firebase/app';\n\nexport function getAppId(firebaseApp: FirebaseApp): string {\n const appId = firebaseApp.options?.appId;\n if (!appId) {\n throw ERROR_FACTORY.create(ErrorCode.NO_APP_ID);\n }\n return appId;\n}\n\nexport function getProjectId(firebaseApp: FirebaseApp): string {\n const projectId = firebaseApp.options?.projectId;\n if (!projectId) {\n throw ERROR_FACTORY.create(ErrorCode.NO_PROJECT_ID);\n }\n return projectId;\n}\n\nexport function getApiKey(firebaseApp: FirebaseApp): string {\n const apiKey = firebaseApp.options?.apiKey;\n if (!apiKey) {\n throw ERROR_FACTORY.create(ErrorCode.NO_API_KEY);\n }\n return apiKey;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CONFIG_EXPIRY_LOCAL_STORAGE_KEY,\n CONFIG_LOCAL_STORAGE_KEY,\n SDK_VERSION\n} from '../constants';\nimport { consoleLogger } from '../utils/console_logger';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\n\nimport { Api } from './api_service';\nimport { getAuthTokenPromise } from './iid_service';\nimport { SettingsService } from './settings_service';\nimport { PerformanceController } from '../controllers/perf';\nimport { getProjectId, getApiKey, getAppId } from '../utils/app_utils';\n\nconst REMOTE_CONFIG_SDK_VERSION = '0.0.1';\n\ninterface SecondaryConfig {\n loggingEnabled?: boolean;\n logSource?: number;\n logEndPointUrl?: string;\n transportKey?: string;\n tracesSamplingRate?: number;\n networkRequestsSamplingRate?: number;\n}\n\n// These values will be used if the remote config object is successfully\n// retrieved, but the template does not have these fields.\nconst DEFAULT_CONFIGS: SecondaryConfig = {\n loggingEnabled: true\n};\n\n/* eslint-disable camelcase */\ninterface RemoteConfigTemplate {\n fpr_enabled?: string;\n fpr_log_source?: string;\n fpr_log_endpoint_url?: string;\n fpr_log_transport_key?: string;\n fpr_log_transport_web_percent?: string;\n fpr_vc_network_request_sampling_rate?: string;\n fpr_vc_trace_sampling_rate?: string;\n fpr_vc_session_sampling_rate?: string;\n}\n/* eslint-enable camelcase */\n\ninterface RemoteConfigResponse {\n entries?: RemoteConfigTemplate;\n state?: string;\n}\n\nconst FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH';\n\nexport function getConfig(\n performanceController: PerformanceController,\n iid: string\n): Promise<void> {\n const config = getStoredConfig();\n if (config) {\n processConfig(config);\n return Promise.resolve();\n }\n\n return getRemoteConfig(performanceController, iid)\n .then(processConfig)\n .then(\n config => storeConfig(config),\n /** Do nothing for error, use defaults set in settings service. */\n () => {}\n );\n}\n\nfunction getStoredConfig(): RemoteConfigResponse | undefined {\n const localStorage = Api.getInstance().localStorage;\n if (!localStorage) {\n return;\n }\n const expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY);\n if (!expiryString || !configValid(expiryString)) {\n return;\n }\n\n const configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);\n if (!configStringified) {\n return;\n }\n try {\n const configResponse: RemoteConfigResponse = JSON.parse(configStringified);\n return configResponse;\n } catch {\n return;\n }\n}\n\nfunction storeConfig(config: RemoteConfigResponse | undefined): void {\n const localStorage = Api.getInstance().localStorage;\n if (!config || !localStorage) {\n return;\n }\n\n localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));\n localStorage.setItem(\n CONFIG_EXPIRY_LOCAL_STORAGE_KEY,\n String(\n Date.now() +\n SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000\n )\n );\n}\n\nconst COULD_NOT_GET_CONFIG_MSG =\n 'Could not fetch config, will use default configs';\n\nfunction getRemoteConfig(\n performanceController: PerformanceController,\n iid: string\n): Promise<RemoteConfigResponse | undefined> {\n // Perf needs auth token only to retrieve remote config.\n return getAuthTokenPromise(performanceController.installations)\n .then(authToken => {\n const projectId = getProjectId(performanceController.app);\n const apiKey = getApiKey(performanceController.app);\n const configEndPoint = `https://firebaseremoteconfig.googleapis.com/v1/projects/${projectId}/namespaces/fireperf:fetch?key=${apiKey}`;\n const request = new Request(configEndPoint, {\n method: 'POST',\n headers: { Authorization: `${FIS_AUTH_PREFIX} ${authToken}` },\n /* eslint-disable camelcase */\n body: JSON.stringify({\n app_instance_id: iid,\n app_instance_id_token: authToken,\n app_id: getAppId(performanceController.app),\n app_version: SDK_VERSION,\n sdk_version: REMOTE_CONFIG_SDK_VERSION\n })\n /* eslint-enable camelcase */\n });\n return fetch(request).then(response => {\n if (response.ok) {\n return response.json() as RemoteConfigResponse;\n }\n // In case response is not ok. This will be caught by catch.\n throw ERROR_FACTORY.create(ErrorCode.RC_NOT_OK);\n });\n })\n .catch(() => {\n consoleLogger.info(COULD_NOT_GET_CONFIG_MSG);\n return undefined;\n });\n}\n\n/**\n * Processes config coming either from calling RC or from local storage.\n * This method only runs if call is successful or config in storage\n * is valid.\n */\nfunction processConfig(\n config?: RemoteConfigResponse\n): RemoteConfigResponse | undefined {\n if (!config) {\n return config;\n }\n const settingsServiceInstance = SettingsService.getInstance();\n const entries = config.entries || {};\n if (entries.fpr_enabled !== undefined) {\n // TODO: Change the assignment of loggingEnabled once the received type is\n // known.\n settingsServiceInstance.loggingEnabled =\n String(entries.fpr_enabled) === 'true';\n } else if (DEFAULT_CONFIGS.loggingEnabled !== undefined) {\n // Config retrieved successfully, but there is no fpr_enabled in template.\n // Use secondary configs value.\n settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled;\n }\n if (entries.fpr_log_source) {\n settingsServiceInstance.logSource = Number(entries.fpr_log_source);\n } else if (DEFAULT_CONFIGS.logSource) {\n settingsServiceInstance.logSource = DEFAULT_CONFIGS.logSource;\n }\n\n if (entries.fpr_log_endpoint_url) {\n settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url;\n } else if (DEFAULT_CONFIGS.logEndPointUrl) {\n settingsServiceInstance.logEndPointUrl = DEFAULT_CONFIGS.logEndPointUrl;\n }\n\n // Key from Remote Config has to be non-empty string, otherwsie use local value.\n if (entries.fpr_log_transport_key) {\n settingsServiceInstance.transportKey = entries.fpr_log_transport_key;\n } else if (DEFAULT_CONFIGS.transportKey) {\n settingsServiceInstance.transportKey = DEFAULT_CONFIGS.transportKey;\n }\n\n if (entries.fpr_vc_network_request_sampling_rate !== undefined) {\n settingsServiceInstance.networkRequestsSamplingRate = Number(\n entries.fpr_vc_network_request_sampling_rate\n );\n } else if (DEFAULT_CONFIGS.networkRequestsSamplingRate !== undefined) {\n settingsServiceInstance.networkRequestsSamplingRate =\n DEFAULT_CONFIGS.networkRequestsSamplingRate;\n }\n if (entries.fpr_vc_trace_sampling_rate !== undefined) {\n settingsServiceInstance.tracesSamplingRate = Number(\n entries.fpr_vc_trace_sampling_rate\n );\n } else if (DEFAULT_CONFIGS.tracesSamplingRate !== undefined) {\n settingsServiceInstance.tracesSamplingRate =\n DEFAULT_CONFIGS.tracesSamplingRate;\n }\n // Set the per session trace and network logging flags.\n settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(\n settingsServiceInstance.tracesSamplingRate\n );\n settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(\n settingsServiceInstance.networkRequestsSamplingRate\n );\n return config;\n}\n\nfunction configValid(expiry: string): boolean {\n return Number(expiry) > Date.now();\n}\n\nfunction shouldLogAfterSampling(samplingRate: number): boolean {\n return Math.random() <= samplingRate;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getIidPromise } from './iid_service';\nimport { getConfig } from './remote_config_service';\nimport { Api } from './api_service';\nimport { PerformanceController } from '../controllers/perf';\n\nconst enum InitializationStatus {\n notInitialized = 1,\n initializationPending,\n initialized\n}\n\nlet initializationStatus = InitializationStatus.notInitialized;\n\nlet initializationPromise: Promise<void> | undefined;\n\nexport function getInitializationPromise(\n performanceController: PerformanceController\n): Promise<void> {\n initializationStatus = InitializationStatus.initializationPending;\n\n initializationPromise =\n initializationPromise || initializePerf(performanceController);\n\n return initializationPromise;\n}\n\nexport function isPerfInitialized(): boolean {\n return initializationStatus === InitializationStatus.initialized;\n}\n\nfunction initializePerf(\n performanceController: PerformanceController\n): Promise<void> {\n return getDocumentReadyComplete()\n .then(() => getIidPromise(performanceController.installations))\n .then(iid => getConfig(performanceController, iid))\n .then(\n () => changeInitializationStatus(),\n () => changeInitializationStatus()\n );\n}\n\n/**\n * Returns a promise which resolves whenever the document readystate is complete or\n * immediately if it is called after page load complete.\n */\nfunction getDocumentReadyComplete(): Promise<void> {\n const document = Api.getInstance().document;\n return new Promise(resolve => {\n if (document && document.readyState !== 'complete') {\n const handler = (): void => {\n if (document.readyState === 'complete') {\n document.removeEventListener('readystatechange', handler);\n resolve();\n }\n };\n document.addEventListener('readystatechange', handler);\n } else {\n resolve();\n }\n });\n}\n\nfunction changeInitializationStatus(): void {\n initializationStatus = InitializationStatus.initialized;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SettingsService } from './settings_service';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport { consoleLogger } from '../utils/console_logger';\n\nconst DEFAULT_SEND_INTERVAL_MS = 10 * 1000;\nconst INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;\n// If end point does not work, the call will be tried for these many times.\nconst DEFAULT_REMAINING_TRIES = 3;\nconst MAX_EVENT_COUNT_PER_REQUEST = 1000;\nlet remainingTries = DEFAULT_REMAINING_TRIES;\n\ninterface LogResponseDetails {\n responseAction?: string;\n}\n\ninterface BatchEvent {\n message: string;\n eventTime: number;\n}\n\n/* eslint-disable camelcase */\n// CC/Fl accepted log format.\ninterface TransportBatchLogFormat {\n request_time_ms: string;\n client_info: ClientInfo;\n log_source: number;\n log_event: Log[];\n}\n\ninterface ClientInfo {\n client_type: number;\n js_client_info: {};\n}\n\ninterface Log {\n source_extension_json_proto3: string;\n event_time_ms: string;\n}\n/* eslint-enable camelcase */\n\nlet queue: BatchEvent[] = [];\n\nlet isTransportSetup: boolean = false;\n\nexport function setupTransportService(): void {\n if (!isTransportSetup) {\n processQueue(INITIAL_SEND_TIME_DELAY_MS);\n isTransportSetup = true;\n }\n}\n\n/**\n * Utilized by testing to clean up message queue and un-initialize transport service.\n */\nexport function resetTransportService(): void {\n isTransportSetup = false;\n queue = [];\n}\n\nfunction processQueue(timeOffset: number): void {\n setTimeout(() => {\n // If there is no remainingTries left, stop retrying.\n if (remainingTries === 0) {\n return;\n }\n\n // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again.\n if (!queue.length) {\n return processQueue(DEFAULT_SEND_INTERVAL_MS);\n }\n\n dispatchQueueEvents();\n }, timeOffset);\n}\n\nfunction dispatchQueueEvents(): void {\n // Extract events up to the maximum cap of single logRequest from top of \"official queue\".\n // The staged events will be used for current logRequest attempt, remaining events will be kept\n // for next attempt.\n const staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST);\n\n /* eslint-disable camelcase */\n // We will pass the JSON serialized event to the backend.\n const log_event: Log[] = staged.map(evt => ({\n source_extension_json_proto3: evt.message,\n event_time_ms: String(evt.eventTime)\n }));\n\n const data: TransportBatchLogFormat = {\n request_time_ms: String(Date.now()),\n client_info: {\n client_type: 1, // 1 is JS\n js_client_info: {}\n },\n log_source: SettingsService.getInstance().logSource,\n log_event\n };\n /* eslint-enable camelcase */\n\n sendEventsToFl(data, staged).catch(() => {\n // If the request fails for some reason, add the events that were attempted\n // back to the primary queue to retry later.\n queue = [...staged, ...queue];\n remainingTries--;\n consoleLogger.info(`Tries left: ${remainingTries}.`);\n processQueue(DEFAULT_SEND_INTERVAL_MS);\n });\n}\n\nfunction sendEventsToFl(\n data: TransportBatchLogFormat,\n staged: BatchEvent[]\n): Promise<void> {\n return postToFlEndpoint(data)\n .then(res => {\n if (!res.ok) {\n consoleLogger.info('Call to Firebase backend failed.');\n }\n return res.json();\n })\n .then(res => {\n // Find the next call wait time from the response.\n const transportWait = Number(res.nextRequestWaitMillis);\n let requestOffset = DEFAULT_SEND_INTERVAL_MS;\n if (!isNaN(transportWait)) {\n requestOffset = Math.max(transportWait, requestOffset);\n }\n\n // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.\n // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.\n const logResponseDetails: LogResponseDetails[] = res.logResponseDetails;\n if (\n Array.isArray(logResponseDetails) &&\n logResponseDetails.length > 0 &&\n logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER'\n ) {\n queue = [...staged, ...queue];\n consoleLogger.info(`Retry transport request later.`);\n }\n\n remainingTries = DEFAULT_REMAINING_TRIES;\n // Schedule the next process.\n processQueue(requestOffset);\n });\n}\n\nfunction postToFlEndpoint(data: TransportBatchLogFormat): Promise<Response> {\n const flTransportFullUrl =\n SettingsService.getInstance().getFlTransportFullUrl();\n return fetch(flTransportFullUrl, {\n method: 'POST',\n body: JSON.stringify(data)\n });\n}\n\nfunction addToQueue(evt: BatchEvent): void {\n if (!evt.eventTime || !evt.message) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_CC_LOG);\n }\n // Add the new event to the queue.\n queue = [...queue, evt];\n}\n\n/** Log handler for cc service to send the performance logs to the server. */\nexport function transportHandler(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n serializer: (...args: any[]) => string\n): (...args: unknown[]) => void {\n return (...args) => {\n const message = serializer(...args);\n addToQueue({\n message,\n eventTime: Date.now()\n });\n };\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getIid } from './iid_service';\nimport { NetworkRequest } from '../resources/network_request';\nimport { Trace } from '../resources/trace';\nimport { Api } from './api_service';\nimport { SettingsService } from './settings_service';\nimport {\n getServiceWorkerStatus,\n getVisibilityState,\n VisibilityState,\n getEffectiveConnectionType\n} from '../utils/attributes_utils';\nimport {\n isPerfInitialized,\n getInitializationPromise\n} from './initialization_service';\nimport { transportHandler } from './transport_service';\nimport { SDK_VERSION } from '../constants';\nimport { FirebaseApp } from '@firebase/app';\nimport { getAppId } from '../utils/app_utils';\n\nconst enum ResourceType {\n NetworkRequest,\n Trace\n}\n\n/* eslint-disable camelcase */\ninterface ApplicationInfo {\n google_app_id: string;\n app_instance_id?: string;\n web_app_info: WebAppInfo;\n application_process_state: number;\n}\n\ninterface WebAppInfo {\n sdk_version: string;\n page_url: string;\n service_worker_status: number;\n visibility_state: number;\n effective_connection_type: number;\n}\n\ninterface PerfNetworkLog {\n application_info: ApplicationInfo;\n network_request_metric: NetworkRequestMetric;\n}\n\ninterface PerfTraceLog {\n application_info: ApplicationInfo;\n trace_metric: TraceMetric;\n}\n\ninterface NetworkRequestMetric {\n url: string;\n http_method: number;\n http_response_code: number;\n response_payload_bytes?: number;\n client_start_time_us?: number;\n time_to_response_initiated_us?: number;\n time_to_response_completed_us?: number;\n}\n\ninterface TraceMetric {\n name: string;\n is_auto: boolean;\n client_start_time_us: number;\n duration_us: number;\n counters?: { [key: string]: number };\n custom_attributes?: { [key: string]: string };\n}\n\n/* eslint-enble camelcase */\n\nlet logger: (\n resource: NetworkRequest | Trace,\n resourceType: ResourceType\n) => void | undefined;\n// This method is not called before initialization.\nfunction sendLog(\n resource: NetworkRequest | Trace,\n resourceType: ResourceType\n): void {\n if (!logger) {\n logger = transportHandler(serializer);\n }\n logger(resource, resourceType);\n}\n\nexport function logTrace(trace: Trace): void {\n const settingsService = SettingsService.getInstance();\n // Do not log if trace is auto generated and instrumentation is disabled.\n if (!settingsService.instrumentationEnabled && trace.isAuto) {\n return;\n }\n // Do not log if trace is custom and data collection is disabled.\n if (!settingsService.dataCollectionEnabled && !trace.isAuto) {\n return;\n }\n // Do not log if required apis are not available.\n if (!Api.getInstance().requiredApisAvailable()) {\n return;\n }\n\n // Only log the page load auto traces if page is visible.\n if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {\n return;\n }\n\n if (isPerfInitialized()) {\n sendTraceLog(trace);\n } else {\n // Custom traces can be used before the initialization but logging\n // should wait until after.\n getInitializationPromise(trace.performanceController).then(\n () => sendTraceLog(trace),\n () => sendTraceLog(trace)\n );\n }\n}\n\nfunction sendTraceLog(trace: Trace): void {\n if (!getIid()) {\n return;\n }\n\n const settingsService = SettingsService.getInstance();\n if (\n !settingsService.loggingEnabled ||\n !settingsService.logTraceAfterSampling\n ) {\n return;\n }\n\n setTimeout(() => sendLog(trace, ResourceType.Trace), 0);\n}\n\nexport function logNetworkRequest(networkRequest: NetworkRequest): void {\n const settingsService = SettingsService.getInstance();\n // Do not log network requests if instrumentation is disabled.\n if (!settingsService.instrumentationEnabled) {\n return;\n }\n\n // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.\n // Need to blacklist both old and new endpoints to avoid migration gap.\n const networkRequestUrl = networkRequest.url;\n\n // Blacklist old log endpoint and new transport endpoint.\n // Because Performance SDK doesn't instrument requests sent from SDK itself.\n const logEndpointUrl = settingsService.logEndPointUrl.split('?')[0];\n const flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0];\n if (\n networkRequestUrl === logEndpointUrl ||\n networkRequestUrl === flEndpointUrl\n ) {\n return;\n }\n\n if (\n !settingsService.loggingEnabled ||\n !settingsService.logNetworkAfterSampling\n ) {\n return;\n }\n\n setTimeout(() => sendLog(networkRequest, ResourceType.NetworkRequest), 0);\n}\n\nfunction serializer(\n resource: NetworkRequest | Trace,\n resourceType: ResourceType\n): string {\n if (resourceType === ResourceType.NetworkRequest) {\n return serializeNetworkRequest(resource as NetworkRequest);\n }\n return serializeTrace(resource as Trace);\n}\n\nfunction serializeNetworkRequest(networkRequest: NetworkRequest): string {\n const networkRequestMetric: NetworkRequestMetric = {\n url: networkRequest.url,\n http_method: networkRequest.httpMethod || 0,\n http_response_code: 200,\n response_payload_bytes: networkRequest.responsePayloadBytes,\n client_start_time_us: networkRequest.startTimeUs,\n time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs,\n time_to_response_completed_us: networkRequest.timeToResponseCompletedUs\n };\n const perfMetric: PerfNetworkLog = {\n application_info: getApplicationInfo(\n networkRequest.performanceController.app\n ),\n network_request_metric: networkRequestMetric\n };\n return JSON.stringify(perfMetric);\n}\n\nfunction serializeTrace(trace: Trace): string {\n const traceMetric: TraceMetric = {\n name: trace.name,\n is_auto: trace.isAuto,\n client_start_time_us: trace.startTimeUs,\n duration_us: trace.durationUs\n };\n\n if (Object.keys(trace.counters).length !== 0) {\n traceMetric.counters = trace.counters;\n }\n const customAttributes = trace.getAttributes();\n if (Object.keys(customAttributes).length !== 0) {\n traceMetric.custom_attributes = customAttributes;\n }\n\n const perfMetric: PerfTraceLog = {\n application_info: getApplicationInfo(trace.performanceController.app),\n trace_metric: traceMetric\n };\n return JSON.stringify(perfMetric);\n}\n\nfunction getApplicationInfo(firebaseApp: FirebaseApp): ApplicationInfo {\n return {\n google_app_id: getAppId(firebaseApp),\n app_instance_id: getIid(),\n web_app_info: {\n sdk_version: SDK_VERSION,\n page_url: Api.getInstance().getUrl(),\n service_worker_status: getServiceWorkerStatus(),\n visibility_state: getVisibilityState(),\n effective_connection_type: getEffectiveConnectionType()\n },\n application_process_state: 0\n };\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FIRST_PAINT_COUNTER_NAME,\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n FIRST_INPUT_DELAY_COUNTER_NAME,\n OOB_TRACE_PAGE_LOAD_PREFIX\n} from '../constants';\nimport { consoleLogger } from '../utils/console_logger';\n\nconst MAX_METRIC_NAME_LENGTH = 100;\nconst RESERVED_AUTO_PREFIX = '_';\nconst oobMetrics = [\n FIRST_PAINT_COUNTER_NAME,\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n FIRST_INPUT_DELAY_COUNTER_NAME\n];\n\n/**\n * Returns true if the metric is custom and does not start with reserved prefix, or if\n * the metric is one of out of the box page load trace metrics.\n */\nexport function isValidMetricName(name: string, traceName?: string): boolean {\n if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) {\n return false;\n }\n return (\n (traceName &&\n traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) &&\n oobMetrics.indexOf(name) > -1) ||\n !name.startsWith(RESERVED_AUTO_PREFIX)\n );\n}\n\n/**\n * Converts the provided value to an integer value to be used in case of a metric.\n * @param providedValue Provided number value of the metric that needs to be converted to an integer.\n *\n * @returns Converted integer number to be set for the metric.\n */\nexport function convertMetricValueToInteger(providedValue: number): number {\n const valueAsInteger: number = Math.floor(providedValue);\n if (valueAsInteger < providedValue) {\n consoleLogger.info(\n `Metric value should be an Integer, setting the value as : ${valueAsInteger}.`\n );\n }\n return valueAsInteger;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n TRACE_START_MARK_PREFIX,\n TRACE_STOP_MARK_PREFIX,\n TRACE_MEASURE_PREFIX,\n OOB_TRACE_PAGE_LOAD_PREFIX,\n FIRST_PAINT_COUNTER_NAME,\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n FIRST_INPUT_DELAY_COUNTER_NAME\n} from '../constants';\nimport { Api } from '../services/api_service';\nimport { logTrace } from '../services/perf_logger';\nimport { ERROR_FACTORY, ErrorCode } from '../utils/errors';\nimport {\n isValidCustomAttributeName,\n isValidCustomAttributeValue\n} from '../utils/attributes_utils';\nimport {\n isValidMetricName,\n convertMetricValueToInteger\n} from '../utils/metric_utils';\nimport { PerformanceTrace } from '../public_types';\nimport { PerformanceController } from '../controllers/perf';\n\nconst enum TraceState {\n UNINITIALIZED = 1,\n RUNNING,\n TERMINATED\n}\n\nexport class Trace implements PerformanceTrace {\n private state: TraceState = TraceState.UNINITIALIZED;\n startTimeUs!: number;\n durationUs!: number;\n private customAttributes: { [key: string]: string } = {};\n counters: { [counterName: string]: number } = {};\n private api = Api.getInstance();\n private randomId = Math.floor(Math.random() * 1000000);\n private traceStartMark!: string;\n private traceStopMark!: string;\n private traceMeasure!: string;\n\n /**\n * @param performanceController The performance controller running.\n * @param name The name of the trace.\n * @param isAuto If the trace is auto-instrumented.\n * @param traceMeasureName The name of the measure marker in user timing specification. This field\n * is only set when the trace is built for logging when the user directly uses the user timing\n * api (performance.mark and performance.measure).\n */\n constructor(\n readonly performanceController: PerformanceController,\n readonly name: string,\n readonly isAuto = false,\n traceMeasureName?: string\n ) {\n if (!this.isAuto) {\n this.traceStartMark = `${TRACE_START_MARK_PREFIX}-${this.randomId}-${this.name}`;\n this.traceStopMark = `${TRACE_STOP_MARK_PREFIX}-${this.randomId}-${this.name}`;\n this.traceMeasure =\n traceMeasureName ||\n `${TRACE_MEASURE_PREFIX}-${this.randomId}-${this.name}`;\n\n if (traceMeasureName) {\n // For the case of direct user timing traces, no start stop will happen. The measure object\n // is already available.\n this.calculateTraceMetrics();\n }\n }\n }\n\n /**\n * Starts a trace. The measurement of the duration starts at this point.\n */\n start(): void {\n if (this.state !== TraceState.UNINITIALIZED) {\n throw ERROR_FACTORY.create(ErrorCode.TRACE_STARTED_BEFORE, {\n traceName: this.name\n });\n }\n this.api.mark(this.traceStartMark);\n this.state = TraceState.RUNNING;\n }\n\n /**\n * Stops the trace. The measurement of the duration of the trace stops at this point and trace\n * is logged.\n */\n stop(): void {\n if (this.state !== TraceState.RUNNING) {\n throw ERROR_FACTORY.create(ErrorCode.TRACE_STOPPED_BEFORE, {\n traceName: this.name\n });\n }\n this.state = TraceState.TERMINATED;\n this.api.mark(this.traceStopMark);\n this.api.measure(\n this.traceMeasure,\n this.traceStartMark,\n this.traceStopMark\n );\n this.calculateTraceMetrics();\n logTrace(this);\n }\n\n /**\n * Records a trace with predetermined values. If this method is used a trace is created and logged\n * directly. No need to use start and stop methods.\n * @param startTime Trace start time since epoch in millisec\n * @param duration The duraction of the trace in millisec\n * @param options An object which can optionally hold maps of custom metrics and custom attributes\n */\n record(\n startTime: number,\n duration: number,\n options?: {\n metrics?: { [key: string]: number };\n attributes?: { [key: string]: string };\n }\n ): void {\n if (startTime <= 0) {\n throw ERROR_FACTORY.create(ErrorCode.NONPOSITIVE_TRACE_START_TIME, {\n traceName: this.name\n });\n }\n if (duration <= 0) {\n throw ERROR_FACTORY.create(ErrorCode.NONPOSITIVE_TRACE_DURATION, {\n traceName: this.name\n });\n }\n\n this.durationUs = Math.floor(duration * 1000);\n this.startTimeUs = Math.floor(startTime * 1000);\n if (options && options.attributes) {\n this.customAttributes = { ...options.attributes };\n }\n if (options && options.metrics) {\n for (const metricName of Object.keys(options.metrics)) {\n if (!isNaN(Number(options.metrics[metricName]))) {\n this.counters[metricName] = Math.floor(\n Number(options.metrics[metricName])\n );\n }\n }\n }\n logTrace(this);\n }\n\n /**\n * Increments a custom metric by a certain number or 1 if number not specified. Will create a new\n * custom metric if one with the given name does not exist. The value will be floored down to an\n * integer.\n * @param counter Name of the custom metric\n * @param numAsInteger Increment by value\n */\n incrementMetric(counter: string, numAsInteger = 1): void {\n if (this.counters[counter] === undefined) {\n this.putMetric(counter, numAsInteger);\n } else {\n this.putMetric(counter, this.counters[counter] + numAsInteger);\n }\n }\n\n /**\n * Sets a custom metric to a specified value. Will create a new custom metric if one with the\n * given name does not exist. The value will be floored down to an integer.\n * @param counter Name of the custom metric\n * @param numAsInteger Set custom metric to this value\n */\n putMetric(counter: string, numAsInteger: number): void {\n if (isValidMetricName(counter, this.name)) {\n this.counters[counter] = convertMetricValueToInteger(numAsInteger ?? 0);\n } else {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_CUSTOM_METRIC_NAME, {\n customMetricName: counter\n });\n }\n }\n\n /**\n * Returns the value of the custom metric by that name. If a custom metric with that name does\n * not exist will return zero.\n * @param counter\n */\n getMetric(counter: string): number {\n return this.counters[counter] || 0;\n }\n\n /**\n * Sets a custom attribute of a trace to a certain value.\n * @param attr\n * @param value\n */\n putAttribute(attr: string, value: string): void {\n const isValidName = isValidCustomAttributeName(attr);\n const isValidValue = isValidCustomAttributeValue(value);\n if (isValidName && isValidValue) {\n this.customAttributes[attr] = value;\n return;\n }\n // Throw appropriate error when the attribute name or value is invalid.\n if (!isValidName) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_ATTRIBUTE_NAME, {\n attributeName: attr\n });\n }\n if (!isValidValue) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_ATTRIBUTE_VALUE, {\n attributeValue: value\n });\n }\n }\n\n /**\n * Retrieves the value a custom attribute of a trace is set to.\n * @param attr\n */\n getAttribute(attr: string): string | undefined {\n return this.customAttributes[attr];\n }\n\n removeAttribute(attr: string): void {\n if (this.customAttributes[attr] === undefined) {\n return;\n }\n delete this.customAttributes[attr];\n }\n\n getAttributes(): { [key: string]: string } {\n return { ...this.customAttributes };\n }\n\n private setStartTime(startTime: number): void {\n this.startTimeUs = startTime;\n }\n\n private setDuration(duration: number): void {\n this.durationUs = duration;\n }\n\n /**\n * Calculates and assigns the duration and start time of the trace using the measure performance\n * entry.\n */\n private calculateTraceMetrics(): void {\n const perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure);\n const perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0];\n if (perfMeasureEntry) {\n this.durationUs = Math.floor(perfMeasureEntry.duration * 1000);\n this.startTimeUs = Math.floor(\n (perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000\n );\n }\n }\n\n /**\n * @param navigationTimings A single element array which contains the navigationTIming object of\n * the page load\n * @param paintTimings A array which contains paintTiming object of the page load\n * @param firstInputDelay First input delay in millisec\n */\n static createOobTrace(\n performanceController: PerformanceController,\n navigationTimings: PerformanceNavigationTiming[],\n paintTimings: PerformanceEntry[],\n firstInputDelay?: number\n ): void {\n const route = Api.getInstance().getUrl();\n if (!route) {\n return;\n }\n const trace = new Trace(\n performanceController,\n OOB_TRACE_PAGE_LOAD_PREFIX + route,\n true\n );\n const timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000);\n trace.setStartTime(timeOriginUs);\n\n // navigationTimings includes only one element.\n if (navigationTimings && navigationTimings[0]) {\n trace.setDuration(Math.floor(navigationTimings[0].duration * 1000));\n trace.putMetric(\n 'domInteractive',\n Math.floor(navigationTimings[0].domInteractive * 1000)\n );\n trace.putMetric(\n 'domContentLoadedEventEnd',\n Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000)\n );\n trace.putMetric(\n 'loadEventEnd',\n Math.floor(navigationTimings[0].loadEventEnd * 1000)\n );\n }\n\n const FIRST_PAINT = 'first-paint';\n const FIRST_CONTENTFUL_PAINT = 'first-contentful-paint';\n if (paintTimings) {\n const firstPaint = paintTimings.find(\n paintObject => paintObject.name === FIRST_PAINT\n );\n if (firstPaint && firstPaint.startTime) {\n trace.putMetric(\n FIRST_PAINT_COUNTER_NAME,\n Math.floor(firstPaint.startTime * 1000)\n );\n }\n const firstContentfulPaint = paintTimings.find(\n paintObject => paintObject.name === FIRST_CONTENTFUL_PAINT\n );\n if (firstContentfulPaint && firstContentfulPaint.startTime) {\n trace.putMetric(\n FIRST_CONTENTFUL_PAINT_COUNTER_NAME,\n Math.floor(firstContentfulPaint.startTime * 1000)\n );\n }\n\n if (firstInputDelay) {\n trace.putMetric(\n FIRST_INPUT_DELAY_COUNTER_NAME,\n Math.floor(firstInputDelay * 1000)\n );\n }\n }\n\n logTrace(trace);\n }\n\n static createUserTimingTrace(\n performanceController: PerformanceController,\n measureName: string\n ): void {\n const trace = new Trace(\n performanceController,\n measureName,\n false,\n measureName\n );\n logTrace(trace);\n }\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Api } from '../services/api_service';\nimport { logNetworkRequest } from '../services/perf_logger';\nimport { PerformanceController } from '../controllers/perf';\n\n// The order of values of this enum should not be changed.\nexport const enum HttpMethod {\n HTTP_METHOD_UNKNOWN = 0,\n GET = 1,\n PUT = 2,\n POST = 3,\n DELETE = 4,\n HEAD = 5,\n PATCH = 6,\n OPTIONS = 7,\n TRACE = 8,\n CONNECT = 9\n}\n\n// Durations are in microseconds.\nexport interface NetworkRequest {\n performanceController: PerformanceController;\n url: string;\n httpMethod?: HttpMethod;\n requestPayloadBytes?: number;\n responsePayloadBytes?: number;\n httpResponseCode?: number;\n responseContentType?: string;\n startTimeUs?: number;\n timeToRequestCompletedUs?: number;\n timeToResponseInitiatedUs?: number;\n timeToResponseCompletedUs?: number;\n}\n\nexport function createNetworkRequestEntry(\n performanceController: PerformanceController,\n entry: PerformanceEntry\n): void {\n const performanceEntry = entry as PerformanceResourceTiming;\n if (!performanceEntry || performanceEntry.responseStart === undefined) {\n return;\n }\n const timeOrigin = Api.getInstance().getTimeOrigin();\n const startTimeUs = Math.floor(\n (performanceEntry.startTime + timeOrigin) * 1000\n );\n const timeToResponseInitiatedUs = performanceEntry.responseStart\n ? Math.floor(\n (performanceEntry.responseStart - performanceEntry.startTime) * 1000\n )\n : undefined;\n const timeToResponseCompletedUs = Math.floor(\n (performanceEntry.responseEnd - performanceEntry.startTime) * 1000\n );\n // Remove the query params from logged network request url.\n const url = performanceEntry.name && performanceEntry.name.split('?')[0];\n const networkRequest: NetworkRequest = {\n performanceController,\n url,\n responsePayloadBytes: performanceEntry.transferSize,\n startTimeUs,\n timeToResponseInitiatedUs,\n timeToResponseCompletedUs\n };\n\n logNetworkRequest(networkRequest);\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Api } from './api_service';\nimport { Trace } from '../resources/trace';\nimport { createNetworkRequestEntry } from '../resources/network_request';\nimport { TRACE_MEASURE_PREFIX } from '../constants';\nimport { getIid } from './iid_service';\nimport { PerformanceController } from '../controllers/perf';\n\nconst FID_WAIT_TIME_MS = 5000;\n\nexport function setupOobResources(\n performanceController: PerformanceController\n): void {\n // Do not initialize unless iid is available.\n if (!getIid()) {\n return;\n }\n // The load event might not have fired yet, and that means performance navigation timing\n // object has a duration of 0. The setup should run after all current tasks in js queue.\n setTimeout(() => setupOobTraces(performanceController), 0);\n setTimeout(() => setupNetworkRequests(performanceController), 0);\n setTimeout(() => setupUserTimingTraces(performanceController), 0);\n}\n\nfunction setupNetworkRequests(\n performanceController: PerformanceController\n): void {\n const api = Api.getInstance();\n const resources = api.getEntriesByType('resource');\n for (const resource of resources) {\n createNetworkRequestEntry(performanceController, resource);\n }\n api.setupObserver('resource', entry =>\n createNetworkRequestEntry(performanceController, entry)\n );\n}\n\nfunction setupOobTraces(performanceController: PerformanceController): void {\n const api = Api.getInstance();\n const navigationTimings = api.getEntriesByType(\n 'navigation'\n ) as PerformanceNavigationTiming[];\n const paintTimings = api.getEntriesByType('paint');\n // If First Input Desly polyfill is added to the page, report the fid value.\n // https://github.com/GoogleChromeLabs/first-input-delay\n if (api.onFirstInputDelay) {\n // If the fid call back is not called for certain time, continue without it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let timeoutId: any = setTimeout(() => {\n Trace.createOobTrace(\n performanceController,\n navigationTimings,\n paintTimings\n );\n timeoutId = undefined;\n }, FID_WAIT_TIME_MS);\n api.onFirstInputDelay((fid: number) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n Trace.createOobTrace(\n performanceController,\n navigationTimings,\n paintTimings,\n fid\n );\n }\n });\n } else {\n Trace.createOobTrace(\n performanceController,\n navigationTimings,\n paintTimings\n );\n }\n}\n\nfunction setupUserTimingTraces(\n performanceController: PerformanceController\n): void {\n const api = Api.getInstance();\n // Run through the measure performance entries collected up to this point.\n const measures = api.getEntriesByType('measure');\n for (const measure of measures) {\n createUserTimingTrace(performanceController, measure);\n }\n // Setup an observer to capture the measures from this point on.\n api.setupObserver('measure', entry =>\n createUserTimingTrace(performanceController, entry)\n );\n}\n\nfunction createUserTimingTrace(\n performanceController: PerformanceController,\n measure: PerformanceEntry\n): void {\n const measureName = measure.name;\n // Do not create a trace, if the user timing marks and measures are created by the sdk itself.\n if (\n measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===\n TRACE_MEASURE_PREFIX\n ) {\n return;\n }\n Trace.createUserTimingTrace(performanceController, measureName);\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { setupOobResources } from '../services/oob_resources_service';\nimport { SettingsService } from '../services/settings_service';\nimport { getInitializationPromise } from '../services/initialization_service';\nimport { Api } from '../services/api_service';\nimport { FirebaseApp } from '@firebase/app';\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\nimport { PerformanceSettings, FirebasePerformance } from '../public_types';\nimport { validateIndexedDBOpenable } from '@firebase/util';\nimport { setupTransportService } from '../services/transport_service';\nimport { consoleLogger } from '../utils/console_logger';\n\nexport class PerformanceController implements FirebasePerformance {\n private initialized: boolean = false;\n\n constructor(\n readonly app: FirebaseApp,\n readonly installations: _FirebaseInstallationsInternal\n ) {}\n\n /**\n * This method *must* be called internally as part of creating a\n * PerformanceController instance.\n *\n * Currently it's not possible to pass the settings object through the\n * constructor using Components, so this method exists to be called with the\n * desired settings, to ensure nothing is collected without the user's\n * consent.\n */\n _init(settings?: PerformanceSettings): void {\n if (this.initialized) {\n return;\n }\n\n if (settings?.dataCollectionEnabled !== undefined) {\n this.dataCollectionEnabled = settings.dataCollectionEnabled;\n }\n if (settings?.instrumentationEnabled !== undefined) {\n this.instrumentationEnabled = settings.instrumentationEnabled;\n }\n\n if (Api.getInstance().requiredApisAvailable()) {\n validateIndexedDBOpenable()\n .then(isAvailable => {\n if (isAvailable) {\n setupTransportService();\n getInitializationPromise(this).then(\n () => setupOobResources(this),\n () => setupOobResources(this)\n );\n this.initialized = true;\n }\n })\n .catch(error => {\n consoleLogger.info(`Environment doesn't support IndexedDB: ${error}`);\n });\n } else {\n consoleLogger.info(\n 'Firebase Performance cannot start if the browser does not support ' +\n '\"Fetch\" and \"Promise\", or cookies are disabled.'\n );\n }\n }\n\n set instrumentationEnabled(val: boolean) {\n SettingsService.getInstance().instrumentationEnabled = val;\n }\n get instrumentationEnabled(): boolean {\n return SettingsService.getInstance().instrumentationEnabled;\n }\n\n set dataCollectionEnabled(val: boolean) {\n SettingsService.getInstance().dataCollectionEnabled = val;\n }\n get dataCollectionEnabled(): boolean {\n return SettingsService.getInstance().dataCollectionEnabled;\n }\n}\n","/**\n * The Firebase Performance Monitoring Web SDK.\n * This SDK does not work in a Node.js environment.\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebasePerformance,\n PerformanceSettings,\n PerformanceTrace\n} from './public_types';\nimport { ERROR_FACTORY, ErrorCode } from './utils/errors';\nimport { setupApi } from './services/api_service';\nimport { PerformanceController } from './controllers/perf';\nimport {\n _registerComponent,\n _getProvider,\n registerVersion,\n FirebaseApp,\n getApp\n} from '@firebase/app';\nimport {\n InstanceFactory,\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { name, version } from '../package.json';\nimport { Trace } from './resources/trace';\nimport '@firebase/installations';\nimport { deepEqual, getModularInstance } from '@firebase/util';\n\nconst DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\n/**\n * Returns a {@link FirebasePerformance} instance for the given app.\n * @param app - The {@link @firebase/app#FirebaseApp} to use.\n * @public\n */\nexport function getPerformance(\n app: FirebaseApp = getApp()\n): FirebasePerformance {\n app = getModularInstance(app);\n const provider = _getProvider(app, 'performance');\n const perfInstance = provider.getImmediate() as PerformanceController;\n return perfInstance;\n}\n\n/**\n * Returns a {@link FirebasePerformance} instance for the given app. Can only be called once.\n * @param app - The {@link @firebase/app#FirebaseApp} to use.\n * @param settings - Optional settings for the {@link FirebasePerformance} instance.\n * @public\n */\nexport function initializePerformance(\n app: FirebaseApp,\n settings?: PerformanceSettings\n): FirebasePerformance {\n app = getModularInstance(app);\n const provider = _getProvider(app, 'performance');\n\n // throw if an instance was already created.\n // It could happen if initializePerformance() is called more than once, or getPerformance() is called first.\n if (provider.isInitialized()) {\n const existingInstance = provider.getImmediate();\n const initialSettings = provider.getOptions() as PerformanceSettings;\n if (deepEqual(initialSettings, settings ?? {})) {\n return existingInstance;\n } else {\n throw ERROR_FACTORY.create(ErrorCode.ALREADY_INITIALIZED);\n }\n }\n\n const perfInstance = provider.initialize({\n options: settings\n }) as PerformanceController;\n return perfInstance;\n}\n\n/**\n * Returns a new `PerformanceTrace` instance.\n * @param performance - The {@link FirebasePerformance} instance to use.\n * @param name - The name of the trace.\n * @public\n */\nexport function trace(\n performance: FirebasePerformance,\n name: string\n): PerformanceTrace {\n performance = getModularInstance(performance);\n return new Trace(performance as PerformanceController, name);\n}\n\nconst factory: InstanceFactory<'performance'> = (\n container: ComponentContainer,\n { options: settings }: { options?: PerformanceSettings }\n) => {\n // Dependencies\n const app = container.getProvider('app').getImmediate();\n const installations = container\n .getProvider('installations-internal')\n .getImmediate();\n\n if (app.name !== DEFAULT_ENTRY_NAME) {\n throw ERROR_FACTORY.create(ErrorCode.FB_NOT_DEFAULT);\n }\n if (typeof window === 'undefined') {\n throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW);\n }\n setupApi(window);\n const perfInstance = new PerformanceController(app, installations);\n perfInstance._init(settings);\n\n return perfInstance;\n};\n\nfunction registerPerformance(): void {\n _registerComponent(\n new Component('performance', factory, ComponentType.PUBLIC)\n );\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\nregisterPerformance();\n\nexport { FirebasePerformance, PerformanceSettings, PerformanceTrace };\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n trace,\n FirebasePerformance,\n // The PerformanceTrace type has not changed between modular and non-modular packages.\n PerformanceTrace\n} from '@firebase/performance';\nimport { FirebasePerformance as FirebasePerformanceCompat } from '@firebase/performance-types';\nimport { FirebaseApp, _FirebaseService } from '@firebase/app-compat';\n\nexport class PerformanceCompatImpl\n implements FirebasePerformanceCompat, _FirebaseService\n{\n constructor(\n public app: FirebaseApp,\n readonly _delegate: FirebasePerformance\n ) {}\n\n get instrumentationEnabled(): boolean {\n return this._delegate.instrumentationEnabled;\n }\n\n set instrumentationEnabled(val: boolean) {\n this._delegate.instrumentationEnabled = val;\n }\n\n get dataCollectionEnabled(): boolean {\n return this._delegate.dataCollectionEnabled;\n }\n\n set dataCollectionEnabled(val: boolean) {\n this._delegate.dataCollectionEnabled = val;\n }\n\n trace(traceName: string): PerformanceTrace {\n return trace(this._delegate, traceName);\n }\n}\n","/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat<T> {\n _delegate: T;\n}\n\nexport function getModularInstance<ExpService>(\n service: Compat<ExpService> | ExpService\n): ExpService {\n if (service && (service as Compat<ExpService>)._delegate) {\n return (service as Compat<ExpService>)._delegate;\n } else {\n return service as ExpService;\n }\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport firebase, { _FirebaseNamespace } from '@firebase/app-compat';\nimport {\n Component,\n ComponentContainer,\n ComponentType\n} from '@firebase/component';\nimport { PerformanceCompatImpl } from './performance';\nimport { name as packageName, version } from '../package.json';\nimport { FirebasePerformance as FirebasePerformanceCompat } from '@firebase/performance-types';\n\nfunction registerPerformanceCompat(firebaseInstance: _FirebaseNamespace): void {\n firebaseInstance.INTERNAL.registerComponent(\n new Component(\n 'performance-compat',\n performanceFactory,\n ComponentType.PUBLIC\n )\n );\n\n firebaseInstance.registerVersion(packageName, version);\n}\n\nfunction performanceFactory(\n container: ComponentContainer\n): PerformanceCompatImpl {\n const app = container.getProvider('app-compat').getImmediate();\n // The following call will always succeed.\n const performance = container.getProvider('performance').getImmediate();\n\n return new PerformanceCompatImpl(app, performance);\n}\n\nregisterPerformanceCompat(firebase as _FirebaseNamespace);\n\ndeclare module '@firebase/app-compat' {\n interface FirebaseNamespace {\n performance: {\n (app?: FirebaseApp): FirebasePerformanceCompat;\n };\n }\n interface FirebaseApp {\n performance(): FirebasePerformanceCompat;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport firebase from './app';\nimport './performance';\nimport { name, version } from '../package.json';\n\nfirebase.registerVersion(name, version, 'compat-lite');\n\nexport default firebase;\n"],"names":["stringToByteArray","str","out","p","i","length","c","charCodeAt","base64","byteToCharMap_","charToByteMap_","byteToCharMapWebSafe_","charToByteMapWebSafe_","ENCODED_VALS_BASE","ENCODED_VALS","this","ENCODED_VALS_WEBSAFE","HAS_NATIVE_SUPPORT","atob","encodeByteArray","input","webSafe","Array","isArray","Error","init_","byteToCharMap","output","byte1","haveByte2","byte2","haveByte3","byte3","outByte1","outByte2","outByte3","outByte4","push","join","encodeString","btoa","decodeString","bytes","pos","c1","String","fromCharCode","c2","u","c3","byteArrayToString","decodeStringToByteArray","charToByteMap","charAt","byte4","DecodeBase64StringError","constructor","name","base64urlEncodeWithoutPadding","utf8Bytes","base64Encode","replace","deepExtend","target","source","Object","Date","getTime","undefined","prop","hasOwnProperty","getDefaultsFromGlobal","self","window","global","getGlobal","__FIREBASE_DEFAULTS__","getDefaultsFromCookie","document","match","cookie","e","decoded","console","error","base64Decode","JSON","parse","getDefaults","process","env","defaultsJsonString","getDefaultsFromEnvVariable","info","getDefaultAppConfig","_a","config","Deferred","reject","resolve","promise","Promise","wrapCallback","callback","value","catch","isIndexedDBAvailable","indexedDB","validateIndexedDBOpenable","preExist","DB_CHECK_NAME","request","open","onsuccess","result","close","deleteDatabase","onupgradeneeded","onerror","message","FirebaseError","code","customData","super","setPrototypeOf","prototype","captureStackTrace","ErrorFactory","create","service","serviceName","errors","data","fullCode","template","PATTERN","_","key","replaceTemplate","fullMessage","contains","obj","call","deepEqual","a","b","aKeys","keys","bKeys","k","includes","aProp","bProp","isObject","thing","Component","instanceFactory","type","multipleInstances","serviceProps","instantiationMode","onInstanceCreated","setInstantiationMode","mode","setMultipleInstances","setServiceProps","props","setInstanceCreatedCallback","DEFAULT_ENTRY_NAME","Provider","container","component","instances","Map","instancesDeferred","instancesOptions","onInitCallbacks","get","identifier","normalizedIdentifier","normalizeInstanceIdentifier","has","deferred","set","isInitialized","shouldAutoInitialize","instance","getOrInitializeService","instanceIdentifier","getImmediate","options","optional","getComponent","setComponent","isComponentEager","instanceDeferred","entries","clearInstance","delete","async","services","from","values","all","filter","map","INTERNAL","_delete","isComponentSet","getOptions","initialize","opts","onInit","existingCallbacks","Set","add","existingInstance","invokeOnInitCallbacks","callbacks","ComponentContainer","providers","addComponent","provider","getProvider","addOrOverwriteComponent","getProviders","LogLevel","levelStringToEnum","debug","DEBUG","verbose","VERBOSE","INFO","warn","WARN","ERROR","silent","SILENT","defaultLogLevel","ConsoleMethod","defaultLogHandler","logType","args","logLevel","now","toISOString","method","Logger","_logLevel","_logHandler","_userLogHandler","val","TypeError","setLogLevel","logHandler","userLogHandler","log","idbProxyableTypes","cursorAdvanceMethods","cursorRequestMap","WeakMap","transactionDoneMap","transactionStoreNamesMap","transformCache","reverseTransformCache","idbProxyTraps","receiver","IDBTransaction","objectStoreNames","objectStore","wrap","wrapFunction","func","IDBDatabase","transaction","IDBCursor","advance","continue","continuePrimaryKey","apply","unwrap","storeNames","tx","sort","transformCachableValue","done","unlisten","removeEventListener","complete","DOMException","addEventListener","cacheDonePromiseForTransaction","object","IDBObjectStore","IDBIndex","some","Proxy","IDBRequest","success","then","promisifyRequest","newValue","openDB","version","blocked","upgrade","blocking","terminated","openPromise","event","oldVersion","newVersion","db","readMethods","writeMethods","cachedMethods","getMethod","targetFuncName","useIndex","isWrite","storeName","store","index","shift","oldTraps","PlatformLoggerServiceImpl","getPlatformInfoString","isVersionServiceProvider","library","logString","logger","PLATFORM_LOG_STRING","name$o","appName","firebase","_apps","_components","_addComponent","app","_registerComponent","componentName","_getProvider","heartbeatController","triggerHeartbeat","ERROR_FACTORY","FirebaseAppImpl","_isDeleted","_options","assign","_config","_name","_automaticDataCollectionEnabled","automaticDataCollectionEnabled","_container","checkDestroyed","isDeleted","SDK_VERSION","initializeApp","rawConfig","existingApp","newApp","deleteApp","registerVersion","libraryKeyOrName","variant","libraryMismatch","versionMismatch","warning","onLog","logCallback","customLogLevel","level","arg","toString","stringify","ignored","toLowerCase","setUserLogHandler","forEach","inst","STORE_NAME","dbPromise","getDbPromise","createObjectStore","originalErrorMessage","writeHeartbeatsToIndexedDB","heartbeatObject","put","computeKey","idbGetError","appId","HeartbeatServiceImpl","_heartbeatsCache","_storage","HeartbeatStorageImpl","_heartbeatsCachePromise","read","agent","date","getUTCDateString","heartbeats","_b","lastSentHeartbeatDate","singleDateHeartbeat","hbTimestamp","valueOf","overwrite","heartbeatsToSend","unsentEntries","heartbeatsCache","maxSize","slice","heartbeatEntry","find","hb","dates","countBytes","pop","extractHeartbeatsForHeader","headerString","substring","_canUseIndexedDBPromise","runIndexedDBEnvironmentCheck","idbHeartbeatObject","readHeartbeatsFromIndexedDB","heartbeatsObject","existingHeartbeatsObject","clear","FirebaseAppLiteImpl","_delegate","removeApp","_getService","_DEFAULT_ENTRY_NAME","createFirebaseNamespaceCore","firebaseAppImpl","apps","namespace","__esModule","modularAPIs.initializeApp","appCompat","modularAPIs.registerVersion","modularAPIs.setLogLevel","modularAPIs.onLog","modularAPIs.SDK_VERSION","registerComponent","componentNameWithoutCompat","modularAPIs._registerComponent","serviceNamespace","appArg","bind","useAsService","modularAPIs","modularAPIs._DEFAULT_ENTRY_NAME","defineProperty","createFirebaseNamespaceLite","registerCoreComponents","PENDING_TIMEOUT_MS","PACKAGE_VERSION","INTERNAL_AUTH_VERSION","TOKEN_EXPIRATION_BUFFER","isServerError","getInstallationsEndpoint","projectId","extractAuthTokenInfoFromResponse","response","token","requestStatus","expiresIn","responseExpiresIn","Number","creationTime","getErrorFromResponse","requestName","errorData","json","serverCode","serverMessage","serverStatus","status","getHeaders","apiKey","Headers","Accept","getHeadersWithAuth","appConfig","refreshToken","headers","append","getAuthorizationHeader","retryIfServerError","fn","sleep","ms","setTimeout","VALID_FID_PATTERN","generateFid","fidByteArray","Uint8Array","crypto","msCrypto","getRandomValues","fid","array","substr","encode","test","getKey","fidChangeCallbacks","fidChanged","callFidChangeCallbacks","channel","broadcastChannel","BroadcastChannel","onmessage","getBroadcastChannel","postMessage","size","broadcastFidChange","OBJECT_STORE_NAME","oldValue","remove","update","updateFn","getInstallationEntry","installations","registrationPromise","installationEntry","oldEntry","clearTimedOutRequest","registrationStatus","updateOrCreateInstallationEntry","entryWithPromise","navigator","onLine","inProgressEntry","registrationTime","registeredInstallationEntry","heartbeatServiceProvider","endpoint","heartbeatService","heartbeatsHeader","getHeartbeatsHeader","body","authVersion","sdkVersion","fetch","ok","responseValue","authToken","createInstallationRequest","registerInstallation","waitUntilFidRegistration","triggerRegistrationIfNecessary","entry","updateInstallationRequest","generateAuthTokenRequest","getGenerateAuthTokenEndpoint","installation","refreshAuthToken","forceRefresh","tokenPromise","isEntryRegistered","oldAuthToken","isAuthTokenExpired","isAuthTokenValid","updateAuthTokenRequest","waitUntilAuthTokenRequest","inProgressAuthToken","requestTime","makeAuthTokenRequestInProgressEntry","updatedInstallationEntry","fetchAuthTokenFromServer","getToken","installationsImpl","completeInstallationRegistration","getMissingValueError","valueName","INSTALLATIONS_NAME","internalFactory","getId","configKeys","keyName","extractAppConfig","TRACE_MEASURE_PREFIX","OOB_TRACE_PAGE_LOAD_PREFIX","FIRST_CONTENTFUL_PAINT_COUNTER_NAME","FIRST_INPUT_DELAY_COUNTER_NAME","CONFIG_LOCAL_STORAGE_KEY","CONFIG_EXPIRY_LOCAL_STORAGE_KEY","SERVICE_NAME","consoleLogger","apiInstance","windowInstance","iid","settingsServiceInstance","Api","performance","PerformanceObserver","windowLocation","location","cookieEnabled","localStorage","perfMetrics","onFirstInputDelay","getUrl","href","split","mark","measure","measureName","mark1","mark2","getEntriesByType","getEntriesByName","getTimeOrigin","timeOrigin","timing","navigationStart","requiredApisAvailable","setupObserver","entryType","list","getEntries","observe","entryTypes","static","getIid","mergeStrings","part1","part2","sizeDiff","resultArray","SettingsService","instrumentationEnabled","dataCollectionEnabled","loggingEnabled","tracesSamplingRate","networkRequestsSamplingRate","logEndPointUrl","flTransportEndpointUrl","transportKey","logSource","logTraceAfterSampling","logNetworkAfterSampling","configTimeToLive","getFlTransportFullUrl","concat","VisibilityState","RESERVED_ATTRIBUTE_PREFIXES","ATTRIBUTE_FORMAT_REGEX","RegExp","getServiceWorkerStatus","getInstance","serviceWorker","controller","getVisibilityState","visibilityState","VISIBLE","HIDDEN","UNKNOWN","getEffectiveConnectionType","navigatorConnection","connection","effectiveType","getAppId","firebaseApp","REMOTE_CONFIG_SDK_VERSION","DEFAULT_CONFIGS","FIS_AUTH_PREFIX","getConfig","performanceController","expiryString","getItem","expiry","configStringified","getStoredConfig","processConfig","installationsService","authTokenPromise","authTokenVal","getAuthTokenPromise","getProjectId","getApiKey","Request","Authorization","app_instance_id","app_instance_id_token","app_id","app_version","sdk_version","COULD_NOT_GET_CONFIG_MSG","getRemoteConfig","setItem","storeConfig","fpr_enabled","fpr_log_source","fpr_log_endpoint_url","fpr_log_transport_key","fpr_vc_network_request_sampling_rate","fpr_vc_trace_sampling_rate","shouldLogAfterSampling","samplingRate","Math","random","initializationPromise","initializationStatus","getInitializationPromise","readyState","handler","getDocumentReadyComplete","iidPromise","iidVal","getIidPromise","changeInitializationStatus","initializePerf","DEFAULT_SEND_INTERVAL_MS","remainingTries","queue","isTransportSetup","processQueue","timeOffset","staged","splice","log_event","evt","source_extension_json_proto3","event_time_ms","eventTime","flTransportFullUrl","postToFlEndpoint","res","transportWait","nextRequestWaitMillis","requestOffset","isNaN","max","logResponseDetails","responseAction","sendEventsToFl","request_time_ms","client_info","client_type","js_client_info","log_source","dispatchQueueEvents","transportHandler","serializer","addToQueue","sendLog","resource","resourceType","logTrace","trace","settingsService","isAuto","sendTraceLog","networkRequest","networkRequestMetric","url","http_method","httpMethod","http_response_code","response_payload_bytes","responsePayloadBytes","client_start_time_us","startTimeUs","time_to_response_initiated_us","timeToResponseInitiatedUs","time_to_response_completed_us","timeToResponseCompletedUs","perfMetric","application_info","getApplicationInfo","network_request_metric","serializeNetworkRequest","traceMetric","is_auto","duration_us","durationUs","counters","customAttributes","getAttributes","custom_attributes","trace_metric","serializeTrace","google_app_id","web_app_info","page_url","service_worker_status","visibility_state","effective_connection_type","application_process_state","oobMetrics","Trace","traceMeasureName","state","api","randomId","floor","traceStartMark","traceStopMark","traceMeasure","calculateTraceMetrics","start","traceName","stop","record","startTime","duration","attributes","metrics","metricName","incrementMetric","counter","numAsInteger","putMetric","startsWith","indexOf","isValidMetricName","customMetricName","providedValue","valueAsInteger","convertMetricValueToInteger","getMetric","putAttribute","attr","isValidName","prefix","isValidCustomAttributeName","isValidValue","isValidCustomAttributeValue","attributeName","attributeValue","getAttribute","removeAttribute","setStartTime","setDuration","perfMeasureEntries","perfMeasureEntry","navigationTimings","paintTimings","firstInputDelay","route","timeOriginUs","domInteractive","domContentLoadedEventEnd","loadEventEnd","firstPaint","paintObject","firstContentfulPaint","createNetworkRequestEntry","performanceEntry","responseStart","responseEnd","networkRequestUrl","logEndpointUrl","flEndpointUrl","logNetworkRequest","transferSize","setupOobResources","timeoutId","createOobTrace","clearTimeout","setupOobTraces","resources","setupNetworkRequests","measures","createUserTimingTrace","setupUserTimingTraces","PerformanceController","initialized","_init","settings","isAvailable","setupApi","perfInstance","PerformanceCompatImpl","performanceFactory","firebaseInstance"],"mappings":"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"}