// node_modules/@firebase/util/dist/postinstall.mjs
var getDefaultsFromPostinstall = () => void 0;
// node_modules/@firebase/util/dist/index.esm.js
var stringToByteArray$1 = function(str) {
const out = [];
let p = 0;
for (let i = 0; i < str.length; i++) {
let c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = c >> 6 | 192;
out[p++] = c & 63 | 128;
} else if ((c & 64512) === 55296 && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) === 56320) {
c = 65536 + ((c & 1023) << 10) + (str.charCodeAt(++i) & 1023);
out[p++] = c >> 18 | 240;
out[p++] = c >> 12 & 63 | 128;
out[p++] = c >> 6 & 63 | 128;
out[p++] = c & 63 | 128;
} else {
out[p++] = c >> 12 | 224;
out[p++] = c >> 6 & 63 | 128;
out[p++] = c & 63 | 128;
}
}
return out;
};
var byteArrayToString = function(bytes) {
const out = [];
let pos = 0, c = 0;
while (pos < bytes.length) {
const c1 = bytes[pos++];
if (c1 < 128) {
out[c++] = String.fromCharCode(c1);
} else if (c1 > 191 && c1 < 224) {
const c2 = bytes[pos++];
out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
} else if (c1 > 239 && c1 < 365) {
const c2 = bytes[pos++];
const c3 = bytes[pos++];
const c4 = bytes[pos++];
const u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 65536;
out[c++] = String.fromCharCode(55296 + (u >> 10));
out[c++] = String.fromCharCode(56320 + (u & 1023));
} else {
const c2 = bytes[pos++];
const c3 = bytes[pos++];
out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
}
}
return out.join("");
};
var base64 = {
/**
* Maps bytes to characters.
*/
byteToCharMap_: null,
/**
* Maps characters to bytes.
*/
charToByteMap_: null,
/**
* Maps bytes to websafe characters.
* @private
*/
byteToCharMapWebSafe_: null,
/**
* Maps websafe characters to bytes.
* @private
*/
charToByteMapWebSafe_: null,
/**
* Our default alphabet, shared between
* ENCODED_VALS and ENCODED_VALS_WEBSAFE
*/
ENCODED_VALS_BASE: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
/**
* Our default alphabet. Value 64 (=) is special; it means "nothing."
*/
get ENCODED_VALS() {
return this.ENCODED_VALS_BASE + "+/=";
},
/**
* Our websafe alphabet.
*/
get ENCODED_VALS_WEBSAFE() {
return this.ENCODED_VALS_BASE + "-_.";
},
/**
* Whether this browser supports the atob and btoa functions. This extension
* started at Mozilla but is now implemented by many browsers. We use the
* ASSUME_* variables to avoid pulling in the full useragent detection library
* but still allowing the standard per-browser compilations.
*
*/
HAS_NATIVE_SUPPORT: typeof atob === "function",
/**
* Base64-encode an array of bytes.
*
* @param input An array of bytes (numbers with
* value in [0, 255]) to encode.
* @param webSafe Boolean indicating we should use the
* alternative alphabet.
* @return The base64 encoded string.
*/
encodeByteArray(input, webSafe) {
if (!Array.isArray(input)) {
throw Error("encodeByteArray takes an array as a parameter");
}
this.init_();
const byteToCharMap = webSafe ? this.byteToCharMapWebSafe_ : this.byteToCharMap_;
const output = [];
for (let i = 0; i < input.length; i += 3) {
const byte1 = input[i];
const haveByte2 = i + 1 < input.length;
const byte2 = haveByte2 ? input[i + 1] : 0;
const haveByte3 = i + 2 < input.length;
const byte3 = haveByte3 ? input[i + 2] : 0;
const outByte1 = byte1 >> 2;
const outByte2 = (byte1 & 3) << 4 | byte2 >> 4;
let outByte3 = (byte2 & 15) << 2 | byte3 >> 6;
let outByte4 = byte3 & 63;
if (!haveByte3) {
outByte4 = 64;
if (!haveByte2) {
outByte3 = 64;
}
}
output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);
}
return output.join("");
},
/**
* Base64-encode a string.
*
* @param input A string to encode.
* @param webSafe If true, we should use the
* alternative alphabet.
* @return The base64 encoded string.
*/
encodeString(input, webSafe) {
if (this.HAS_NATIVE_SUPPORT && !webSafe) {
return btoa(input);
}
return this.encodeByteArray(stringToByteArray$1(input), webSafe);
},
/**
* Base64-decode a string.
*
* @param input to decode.
* @param webSafe True if we should use the
* alternative alphabet.
* @return string representing the decoded value.
*/
decodeString(input, webSafe) {
if (this.HAS_NATIVE_SUPPORT && !webSafe) {
return atob(input);
}
return byteArrayToString(this.decodeStringToByteArray(input, webSafe));
},
/**
* Base64-decode a string.
*
* In base-64 decoding, groups of four characters are converted into three
* bytes. If the encoder did not apply padding, the input length may not
* be a multiple of 4.
*
* In this case, the last group will have fewer than 4 characters, and
* padding will be inferred. If the group has one or two characters, it decodes
* to one byte. If the group has three characters, it decodes to two bytes.
*
* @param input Input to decode.
* @param webSafe True if we should use the web-safe alphabet.
* @return bytes representing the decoded value.
*/
decodeStringToByteArray(input, webSafe) {
this.init_();
const charToByteMap = webSafe ? this.charToByteMapWebSafe_ : this.charToByteMap_;
const output = [];
for (let i = 0; i < input.length; ) {
const byte1 = charToByteMap[input.charAt(i++)];
const haveByte2 = i < input.length;
const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;
++i;
const haveByte3 = i < input.length;
const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;
++i;
const haveByte4 = i < input.length;
const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;
++i;
if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {
throw new DecodeBase64StringError();
}
const outByte1 = byte1 << 2 | byte2 >> 4;
output.push(outByte1);
if (byte3 !== 64) {
const outByte2 = byte2 << 4 & 240 | byte3 >> 2;
output.push(outByte2);
if (byte4 !== 64) {
const outByte3 = byte3 << 6 & 192 | byte4;
output.push(outByte3);
}
}
}
return output;
},
/**
* Lazy static initialization function. Called before
* accessing any of the static map variables.
* @private
*/
init_() {
if (!this.byteToCharMap_) {
this.byteToCharMap_ = {};
this.charToByteMap_ = {};
this.byteToCharMapWebSafe_ = {};
this.charToByteMapWebSafe_ = {};
for (let i = 0; i < this.ENCODED_VALS.length; i++) {
this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);
this.charToByteMap_[this.byteToCharMap_[i]] = i;
this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);
this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;
if (i >= this.ENCODED_VALS_BASE.length) {
this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;
this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;
}
}
}
}
};
var DecodeBase64StringError = class extends Error {
constructor() {
super(...arguments);
this.name = "DecodeBase64StringError";
}
};
var base64Encode = function(str) {
const utf8Bytes = stringToByteArray$1(str);
return base64.encodeByteArray(utf8Bytes, true);
};
var base64urlEncodeWithoutPadding = function(str) {
return base64Encode(str).replace(/\./g, "");
};
var base64Decode = function(str) {
try {
return base64.decodeString(str, true);
} catch (e) {
console.error("base64Decode failed: ", e);
}
return null;
};
function getGlobal() {
if (typeof self !== "undefined") {
return self;
}
if (typeof window !== "undefined") {
return window;
}
if (typeof global !== "undefined") {
return global;
}
throw new Error("Unable to locate global object.");
}
var getDefaultsFromGlobal = () => getGlobal().__FIREBASE_DEFAULTS__;
var getDefaultsFromEnvVariable = () => {
if (typeof process === "undefined" || typeof process.env === "undefined") {
return;
}
const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__;
if (defaultsJsonString) {
return JSON.parse(defaultsJsonString);
}
};
var getDefaultsFromCookie = () => {
if (typeof document === "undefined") {
return;
}
let match;
try {
match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/);
} catch (e) {
return;
}
const decoded = match && base64Decode(match[1]);
return decoded && JSON.parse(decoded);
};
var getDefaults = () => {
try {
return getDefaultsFromPostinstall() || getDefaultsFromGlobal() || getDefaultsFromEnvVariable() || getDefaultsFromCookie();
} catch (e) {
console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`);
return;
}
};
var getDefaultEmulatorHost = (productName) => getDefaults()?.emulatorHosts?.[productName];
var getDefaultEmulatorHostnameAndPort = (productName) => {
const host = getDefaultEmulatorHost(productName);
if (!host) {
return void 0;
}
const separatorIndex = host.lastIndexOf(":");
if (separatorIndex <= 0 || separatorIndex + 1 === host.length) {
throw new Error(`Invalid host ${host} with no separate hostname and port!`);
}
const port = parseInt(host.substring(separatorIndex + 1), 10);
if (host[0] === "[") {
return [host.substring(1, separatorIndex - 1), port];
} else {
return [host.substring(0, separatorIndex), port];
}
};
var getDefaultAppConfig = () => getDefaults()?.config;
var getExperimentalSetting = (name2) => getDefaults()?.[`_${name2}`];
var Deferred = class {
constructor() {
this.reject = () => {
};
this.resolve = () => {
};
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
/**
* Our API internals are not promisified and cannot because our callback APIs have subtle expectations around
* invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback
* and returns a node-style callback which will resolve or reject the Deferred's promise.
*/
wrapCallback(callback) {
return (error, value) => {
if (error) {
this.reject(error);
} else {
this.resolve(value);
}
if (typeof callback === "function") {
this.promise.catch(() => {
});
if (callback.length === 1) {
callback(error);
} else {
callback(error, value);
}
}
};
}
};
function isCloudWorkstation(url) {
try {
const host = url.startsWith("http://") || url.startsWith("https://") ? new URL(url).hostname : url;
return host.endsWith(".cloudworkstations.dev");
} catch {
return false;
}
}
async function pingServer(endpoint) {
const result = await fetch(endpoint, {
credentials: "include"
});
return result.ok;
}
function createMockUserToken(token, projectId) {
if (token.uid) {
throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.');
}
const header = {
alg: "none",
type: "JWT"
};
const project = projectId || "demo-project";
const iat = token.iat || 0;
const sub = token.sub || token.user_id;
if (!sub) {
throw new Error("mockUserToken must contain 'sub' or 'user_id' field!");
}
const payload = {
// Set all required fields to decent defaults
iss: `https://securetoken.google.com/${project}`,
aud: project,
iat,
exp: iat + 3600,
auth_time: iat,
sub,
user_id: sub,
firebase: {
sign_in_provider: "custom",
identities: {}
},
// Override with user options
...token
};
const signature = "";
return [
base64urlEncodeWithoutPadding(JSON.stringify(header)),
base64urlEncodeWithoutPadding(JSON.stringify(payload)),
signature
].join(".");
}
var emulatorStatus = {};
function getEmulatorSummary() {
const summary = {
prod: [],
emulator: []
};
for (const key of Object.keys(emulatorStatus)) {
if (emulatorStatus[key]) {
summary.emulator.push(key);
} else {
summary.prod.push(key);
}
}
return summary;
}
function getOrCreateEl(id) {
let parentDiv = document.getElementById(id);
let created = false;
if (!parentDiv) {
parentDiv = document.createElement("div");
parentDiv.setAttribute("id", id);
created = true;
}
return { created, element: parentDiv };
}
var previouslyDismissed = false;
function updateEmulatorBanner(name2, isRunningEmulator) {
if (typeof window === "undefined" || typeof document === "undefined" || !isCloudWorkstation(window.location.host) || emulatorStatus[name2] === isRunningEmulator || emulatorStatus[name2] || // If already set to use emulator, can't go back to prod.
previouslyDismissed) {
return;
}
emulatorStatus[name2] = isRunningEmulator;
function prefixedId(id) {
return `__firebase__banner__${id}`;
}
const bannerId = "__firebase__banner";
const summary = getEmulatorSummary();
const showError = summary.prod.length > 0;
function tearDown() {
const element = document.getElementById(bannerId);
if (element) {
element.remove();
}
}
function setupBannerStyles(bannerEl) {
bannerEl.style.display = "flex";
bannerEl.style.background = "#7faaf0";
bannerEl.style.position = "fixed";
bannerEl.style.bottom = "5px";
bannerEl.style.left = "5px";
bannerEl.style.padding = ".5em";
bannerEl.style.borderRadius = "5px";
bannerEl.style.alignItems = "center";
}
function setupIconStyles(prependIcon, iconId) {
prependIcon.setAttribute("width", "24");
prependIcon.setAttribute("id", iconId);
prependIcon.setAttribute("height", "24");
prependIcon.setAttribute("viewBox", "0 0 24 24");
prependIcon.setAttribute("fill", "none");
prependIcon.style.marginLeft = "-6px";
}
function setupCloseBtn() {
const closeBtn = document.createElement("span");
closeBtn.style.cursor = "pointer";
closeBtn.style.marginLeft = "16px";
closeBtn.style.fontSize = "24px";
closeBtn.innerHTML = " ×";
closeBtn.onclick = () => {
previouslyDismissed = true;
tearDown();
};
return closeBtn;
}
function setupLinkStyles(learnMoreLink, learnMoreId) {
learnMoreLink.setAttribute("id", learnMoreId);
learnMoreLink.innerText = "Learn more";
learnMoreLink.href = "https://firebase.google.com/docs/studio/preview-apps#preview-backend";
learnMoreLink.setAttribute("target", "__blank");
learnMoreLink.style.paddingLeft = "5px";
learnMoreLink.style.textDecoration = "underline";
}
function setupDom() {
const banner = getOrCreateEl(bannerId);
const firebaseTextId = prefixedId("text");
const firebaseText = document.getElementById(firebaseTextId) || document.createElement("span");
const learnMoreId = prefixedId("learnmore");
const learnMoreLink = document.getElementById(learnMoreId) || document.createElement("a");
const prependIconId = prefixedId("preprendIcon");
const prependIcon = document.getElementById(prependIconId) || document.createElementNS("http://www.w3.org/2000/svg", "svg");
if (banner.created) {
const bannerEl = banner.element;
setupBannerStyles(bannerEl);
setupLinkStyles(learnMoreLink, learnMoreId);
const closeBtn = setupCloseBtn();
setupIconStyles(prependIcon, prependIconId);
bannerEl.append(prependIcon, firebaseText, learnMoreLink, closeBtn);
document.body.appendChild(bannerEl);
}
if (showError) {
firebaseText.innerText = `Preview backend disconnected.`;
prependIcon.innerHTML = `
`;
} else {
prependIcon.innerHTML = `
`;
firebaseText.innerText = "Preview backend running in this workspace.";
}
firebaseText.setAttribute("id", firebaseTextId);
}
if (document.readyState === "loading") {
window.addEventListener("DOMContentLoaded", setupDom);
} else {
setupDom();
}
}
function getUA() {
if (typeof navigator !== "undefined" && typeof navigator["userAgent"] === "string") {
return navigator["userAgent"];
} else {
return "";
}
}
function isMobileCordova() {
return typeof window !== "undefined" && // @ts-ignore Setting up an broadly applicable index signature for Window
// just to deal with this case would probably be a bad idea.
!!(window["cordova"] || window["phonegap"] || window["PhoneGap"]) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA());
}
function isNode() {
const forceEnvironment = getDefaults()?.forceEnvironment;
if (forceEnvironment === "node") {
return true;
} else if (forceEnvironment === "browser") {
return false;
}
try {
return Object.prototype.toString.call(global.process) === "[object process]";
} catch (e) {
return false;
}
}
function isBrowser() {
return typeof window !== "undefined" || isWebWorker();
}
function isWebWorker() {
return typeof WorkerGlobalScope !== "undefined" && typeof self !== "undefined" && self instanceof WorkerGlobalScope;
}
function isCloudflareWorker() {
return typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers";
}
function isBrowserExtension() {
const runtime = typeof chrome === "object" ? chrome.runtime : typeof browser === "object" ? browser.runtime : void 0;
return typeof runtime === "object" && runtime.id !== void 0;
}
function isReactNative() {
return typeof navigator === "object" && navigator["product"] === "ReactNative";
}
function isIE() {
const ua = getUA();
return ua.indexOf("MSIE ") >= 0 || ua.indexOf("Trident/") >= 0;
}
function isSafari() {
return !isNode() && !!navigator.userAgent && navigator.userAgent.includes("Safari") && !navigator.userAgent.includes("Chrome");
}
function isSafariOrWebkit() {
return !isNode() && !!navigator.userAgent && (navigator.userAgent.includes("Safari") || navigator.userAgent.includes("WebKit")) && !navigator.userAgent.includes("Chrome");
}
function isIndexedDBAvailable() {
try {
return typeof indexedDB === "object";
} catch (e) {
return false;
}
}
function validateIndexedDBOpenable() {
return new Promise((resolve, reject) => {
try {
let preExist = true;
const DB_CHECK_NAME = "validate-browser-context-for-indexeddb-analytics-module";
const request = self.indexedDB.open(DB_CHECK_NAME);
request.onsuccess = () => {
request.result.close();
if (!preExist) {
self.indexedDB.deleteDatabase(DB_CHECK_NAME);
}
resolve(true);
};
request.onupgradeneeded = () => {
preExist = false;
};
request.onerror = () => {
reject(request.error?.message || "");
};
} catch (error) {
reject(error);
}
});
}
var ERROR_NAME = "FirebaseError";
var FirebaseError = class _FirebaseError extends Error {
constructor(code, message, customData) {
super(message);
this.code = code;
this.customData = customData;
this.name = ERROR_NAME;
Object.setPrototypeOf(this, _FirebaseError.prototype);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, ErrorFactory.prototype.create);
}
}
};
var ErrorFactory = class {
constructor(service, serviceName, errors) {
this.service = service;
this.serviceName = serviceName;
this.errors = errors;
}
create(code, ...data) {
const customData = data[0] || {};
const fullCode = `${this.service}/${code}`;
const template = this.errors[code];
const message = template ? replaceTemplate(template, customData) : "Error";
const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;
const error = new FirebaseError(fullCode, fullMessage, customData);
return error;
}
};
function replaceTemplate(template, data) {
return template.replace(PATTERN, (_, key) => {
const value = data[key];
return value != null ? String(value) : `<${key}?>`;
});
}
var PATTERN = /\{\$([^}]+)}/g;
function isEmpty(obj) {
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
return false;
}
}
return true;
}
function deepEqual(a, b) {
if (a === b) {
return true;
}
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
for (const k of aKeys) {
if (!bKeys.includes(k)) {
return false;
}
const aProp = a[k];
const bProp = b[k];
if (isObject(aProp) && isObject(bProp)) {
if (!deepEqual(aProp, bProp)) {
return false;
}
} else if (aProp !== bProp) {
return false;
}
}
for (const k of bKeys) {
if (!aKeys.includes(k)) {
return false;
}
}
return true;
}
function isObject(thing) {
return thing !== null && typeof thing === "object";
}
function querystring(querystringParams) {
const params = [];
for (const [key, value] of Object.entries(querystringParams)) {
if (Array.isArray(value)) {
value.forEach((arrayVal) => {
params.push(encodeURIComponent(key) + "=" + encodeURIComponent(arrayVal));
});
} else {
params.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
}
}
return params.length ? "&" + params.join("&") : "";
}
function querystringDecode(querystring2) {
const obj = {};
const tokens = querystring2.replace(/^\?/, "").split("&");
tokens.forEach((token) => {
if (token) {
const [key, value] = token.split("=");
obj[decodeURIComponent(key)] = decodeURIComponent(value);
}
});
return obj;
}
function extractQuerystring(url) {
const queryStart = url.indexOf("?");
if (!queryStart) {
return "";
}
const fragmentStart = url.indexOf("#", queryStart);
return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : void 0);
}
function createSubscribe(executor, onNoObservers) {
const proxy = new ObserverProxy(executor, onNoObservers);
return proxy.subscribe.bind(proxy);
}
var ObserverProxy = class {
/**
* @param executor Function which can make calls to a single Observer
* as a proxy.
* @param onNoObservers Callback when count of Observers goes to zero.
*/
constructor(executor, onNoObservers) {
this.observers = [];
this.unsubscribes = [];
this.observerCount = 0;
this.task = Promise.resolve();
this.finalized = false;
this.onNoObservers = onNoObservers;
this.task.then(() => {
executor(this);
}).catch((e) => {
this.error(e);
});
}
next(value) {
this.forEachObserver((observer) => {
observer.next(value);
});
}
error(error) {
this.forEachObserver((observer) => {
observer.error(error);
});
this.close(error);
}
complete() {
this.forEachObserver((observer) => {
observer.complete();
});
this.close();
}
/**
* Subscribe function that can be used to add an Observer to the fan-out list.
*
* - We require that no event is sent to a subscriber synchronously to their
* call to subscribe().
*/
subscribe(nextOrObserver, error, complete) {
let observer;
if (nextOrObserver === void 0 && error === void 0 && complete === void 0) {
throw new Error("Missing Observer.");
}
if (implementsAnyMethods(nextOrObserver, [
"next",
"error",
"complete"
])) {
observer = nextOrObserver;
} else {
observer = {
next: nextOrObserver,
error,
complete
};
}
if (observer.next === void 0) {
observer.next = noop;
}
if (observer.error === void 0) {
observer.error = noop;
}
if (observer.complete === void 0) {
observer.complete = noop;
}
const unsub = this.unsubscribeOne.bind(this, this.observers.length);
if (this.finalized) {
this.task.then(() => {
try {
if (this.finalError) {
observer.error(this.finalError);
} else {
observer.complete();
}
} catch (e) {
}
return;
});
}
this.observers.push(observer);
return unsub;
}
// Unsubscribe is synchronous - we guarantee that no events are sent to
// any unsubscribed Observer.
unsubscribeOne(i) {
if (this.observers === void 0 || this.observers[i] === void 0) {
return;
}
delete this.observers[i];
this.observerCount -= 1;
if (this.observerCount === 0 && this.onNoObservers !== void 0) {
this.onNoObservers(this);
}
}
forEachObserver(fn) {
if (this.finalized) {
return;
}
for (let i = 0; i < this.observers.length; i++) {
this.sendOne(i, fn);
}
}
// Call the Observer via one of it's callback function. We are careful to
// confirm that the observe has not been unsubscribed since this asynchronous
// function had been queued.
sendOne(i, fn) {
this.task.then(() => {
if (this.observers !== void 0 && this.observers[i] !== void 0) {
try {
fn(this.observers[i]);
} catch (e) {
if (typeof console !== "undefined" && console.error) {
console.error(e);
}
}
}
});
}
close(err) {
if (this.finalized) {
return;
}
this.finalized = true;
if (err !== void 0) {
this.finalError = err;
}
this.task.then(() => {
this.observers = void 0;
this.onNoObservers = void 0;
});
}
};
function implementsAnyMethods(obj, methods) {
if (typeof obj !== "object" || obj === null) {
return false;
}
for (const method of methods) {
if (method in obj && typeof obj[method] === "function") {
return true;
}
}
return false;
}
function noop() {
}
var MAX_VALUE_MILLIS = 4 * 60 * 60 * 1e3;
function getModularInstance(service) {
if (service && service._delegate) {
return service._delegate;
} else {
return service;
}
}
// node_modules/@firebase/component/dist/esm/index.esm.js
var Component = class {
/**
*
* @param name The public service name, e.g. app, auth, firestore, database
* @param instanceFactory Service factory responsible for creating the public interface
* @param type whether the service provided by the component is public or private
*/
constructor(name2, instanceFactory, type) {
this.name = name2;
this.instanceFactory = instanceFactory;
this.type = type;
this.multipleInstances = false;
this.serviceProps = {};
this.instantiationMode = "LAZY";
this.onInstanceCreated = null;
}
setInstantiationMode(mode) {
this.instantiationMode = mode;
return this;
}
setMultipleInstances(multipleInstances) {
this.multipleInstances = multipleInstances;
return this;
}
setServiceProps(props) {
this.serviceProps = props;
return this;
}
setInstanceCreatedCallback(callback) {
this.onInstanceCreated = callback;
return this;
}
};
var DEFAULT_ENTRY_NAME = "[DEFAULT]";
var Provider = class {
constructor(name2, container) {
this.name = name2;
this.container = container;
this.component = null;
this.instances = /* @__PURE__ */ new Map();
this.instancesDeferred = /* @__PURE__ */ new Map();
this.instancesOptions = /* @__PURE__ */ new Map();
this.onInitCallbacks = /* @__PURE__ */ new Map();
}
/**
* @param identifier A provider can provide multiple instances of a service
* if this.component.multipleInstances is true.
*/
get(identifier) {
const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);
if (!this.instancesDeferred.has(normalizedIdentifier)) {
const deferred = new Deferred();
this.instancesDeferred.set(normalizedIdentifier, deferred);
if (this.isInitialized(normalizedIdentifier) || this.shouldAutoInitialize()) {
try {
const instance = this.getOrInitializeService({
instanceIdentifier: normalizedIdentifier
});
if (instance) {
deferred.resolve(instance);
}
} catch (e) {
}
}
}
return this.instancesDeferred.get(normalizedIdentifier).promise;
}
getImmediate(options) {
const normalizedIdentifier = this.normalizeInstanceIdentifier(options?.identifier);
const optional = options?.optional ?? false;
if (this.isInitialized(normalizedIdentifier) || this.shouldAutoInitialize()) {
try {
return this.getOrInitializeService({
instanceIdentifier: normalizedIdentifier
});
} catch (e) {
if (optional) {
return null;
} else {
throw e;
}
}
} else {
if (optional) {
return null;
} else {
throw Error(`Service ${this.name} is not available`);
}
}
}
getComponent() {
return this.component;
}
setComponent(component) {
if (component.name !== this.name) {
throw Error(`Mismatching Component ${component.name} for Provider ${this.name}.`);
}
if (this.component) {
throw Error(`Component for ${this.name} has already been provided`);
}
this.component = component;
if (!this.shouldAutoInitialize()) {
return;
}
if (isComponentEager(component)) {
try {
this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });
} catch (e) {
}
}
for (const [instanceIdentifier, instanceDeferred] of this.instancesDeferred.entries()) {
const normalizedIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier);
try {
const instance = this.getOrInitializeService({
instanceIdentifier: normalizedIdentifier
});
instanceDeferred.resolve(instance);
} catch (e) {
}
}
}
clearInstance(identifier = DEFAULT_ENTRY_NAME) {
this.instancesDeferred.delete(identifier);
this.instancesOptions.delete(identifier);
this.instances.delete(identifier);
}
// app.delete() will call this method on every provider to delete the services
// TODO: should we mark the provider as deleted?
async delete() {
const services = Array.from(this.instances.values());
await Promise.all([
...services.filter((service) => "INTERNAL" in service).map((service) => service.INTERNAL.delete()),
...services.filter((service) => "_delete" in service).map((service) => service._delete())
]);
}
isComponentSet() {
return this.component != null;
}
isInitialized(identifier = DEFAULT_ENTRY_NAME) {
return this.instances.has(identifier);
}
getOptions(identifier = DEFAULT_ENTRY_NAME) {
return this.instancesOptions.get(identifier) || {};
}
initialize(opts = {}) {
const { options = {} } = opts;
const normalizedIdentifier = this.normalizeInstanceIdentifier(opts.instanceIdentifier);
if (this.isInitialized(normalizedIdentifier)) {
throw Error(`${this.name}(${normalizedIdentifier}) has already been initialized`);
}
if (!this.isComponentSet()) {
throw Error(`Component ${this.name} has not been registered yet`);
}
const instance = this.getOrInitializeService({
instanceIdentifier: normalizedIdentifier,
options
});
for (const [instanceIdentifier, instanceDeferred] of this.instancesDeferred.entries()) {
const normalizedDeferredIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier);
if (normalizedIdentifier === normalizedDeferredIdentifier) {
instanceDeferred.resolve(instance);
}
}
return instance;
}
/**
*
* @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().
* The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.
*
* @param identifier An optional instance identifier
* @returns a function to unregister the callback
*/
onInit(callback, identifier) {
const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);
const existingCallbacks = this.onInitCallbacks.get(normalizedIdentifier) ?? /* @__PURE__ */ new Set();
existingCallbacks.add(callback);
this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);
const existingInstance = this.instances.get(normalizedIdentifier);
if (existingInstance) {
callback(existingInstance, normalizedIdentifier);
}
return () => {
existingCallbacks.delete(callback);
};
}
/**
* Invoke onInit callbacks synchronously
* @param instance the service instance`
*/
invokeOnInitCallbacks(instance, identifier) {
const callbacks = this.onInitCallbacks.get(identifier);
if (!callbacks) {
return;
}
for (const callback of callbacks) {
try {
callback(instance, identifier);
} catch {
}
}
}
getOrInitializeService({ instanceIdentifier, options = {} }) {
let instance = this.instances.get(instanceIdentifier);
if (!instance && this.component) {
instance = this.component.instanceFactory(this.container, {
instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),
options
});
this.instances.set(instanceIdentifier, instance);
this.instancesOptions.set(instanceIdentifier, options);
this.invokeOnInitCallbacks(instance, instanceIdentifier);
if (this.component.onInstanceCreated) {
try {
this.component.onInstanceCreated(this.container, instanceIdentifier, instance);
} catch {
}
}
}
return instance || null;
}
normalizeInstanceIdentifier(identifier = DEFAULT_ENTRY_NAME) {
if (this.component) {
return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;
} else {
return identifier;
}
}
shouldAutoInitialize() {
return !!this.component && this.component.instantiationMode !== "EXPLICIT";
}
};
function normalizeIdentifierForFactory(identifier) {
return identifier === DEFAULT_ENTRY_NAME ? void 0 : identifier;
}
function isComponentEager(component) {
return component.instantiationMode === "EAGER";
}
var ComponentContainer = class {
constructor(name2) {
this.name = name2;
this.providers = /* @__PURE__ */ new Map();
}
/**
*
* @param component Component being added
* @param overwrite When a component with the same name has already been registered,
* if overwrite is true: overwrite the existing component with the new component and create a new
* provider with the new component. It can be useful in tests where you want to use different mocks
* for different tests.
* if overwrite is false: throw an exception
*/
addComponent(component) {
const provider = this.getProvider(component.name);
if (provider.isComponentSet()) {
throw new Error(`Component ${component.name} has already been registered with ${this.name}`);
}
provider.setComponent(component);
}
addOrOverwriteComponent(component) {
const provider = this.getProvider(component.name);
if (provider.isComponentSet()) {
this.providers.delete(component.name);
}
this.addComponent(component);
}
/**
* getProvider provides a type safe interface where it can only be called with a field name
* present in NameServiceMapping interface.
*
* Firebase SDKs providing services should extend NameServiceMapping interface to register
* themselves.
*/
getProvider(name2) {
if (this.providers.has(name2)) {
return this.providers.get(name2);
}
const provider = new Provider(name2, this);
this.providers.set(name2, provider);
return provider;
}
getProviders() {
return Array.from(this.providers.values());
}
};
// node_modules/@firebase/logger/dist/esm/index.esm.js
var instances = [];
var LogLevel;
(function(LogLevel2) {
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
LogLevel2[LogLevel2["VERBOSE"] = 1] = "VERBOSE";
LogLevel2[LogLevel2["INFO"] = 2] = "INFO";
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
LogLevel2[LogLevel2["SILENT"] = 5] = "SILENT";
})(LogLevel || (LogLevel = {}));
var levelStringToEnum = {
"debug": LogLevel.DEBUG,
"verbose": LogLevel.VERBOSE,
"info": LogLevel.INFO,
"warn": LogLevel.WARN,
"error": LogLevel.ERROR,
"silent": LogLevel.SILENT
};
var defaultLogLevel = LogLevel.INFO;
var ConsoleMethod = {
[LogLevel.DEBUG]: "log",
[LogLevel.VERBOSE]: "log",
[LogLevel.INFO]: "info",
[LogLevel.WARN]: "warn",
[LogLevel.ERROR]: "error"
};
var defaultLogHandler = (instance, logType, ...args) => {
if (logType < instance.logLevel) {
return;
}
const now = (/* @__PURE__ */ new Date()).toISOString();
const method = ConsoleMethod[logType];
if (method) {
console[method](`[${now}] ${instance.name}:`, ...args);
} else {
throw new Error(`Attempted to log a message with an invalid logType (value: ${logType})`);
}
};
var Logger = class {
/**
* Gives you an instance of a Logger to capture messages according to
* Firebase's logging scheme.
*
* @param name The name that the logs will be associated with
*/
constructor(name2) {
this.name = name2;
this._logLevel = defaultLogLevel;
this._logHandler = defaultLogHandler;
this._userLogHandler = null;
instances.push(this);
}
get logLevel() {
return this._logLevel;
}
set logLevel(val) {
if (!(val in LogLevel)) {
throw new TypeError(`Invalid value "${val}" assigned to \`logLevel\``);
}
this._logLevel = val;
}
// Workaround for setter/getter having to be the same type.
setLogLevel(val) {
this._logLevel = typeof val === "string" ? levelStringToEnum[val] : val;
}
get logHandler() {
return this._logHandler;
}
set logHandler(val) {
if (typeof val !== "function") {
throw new TypeError("Value assigned to `logHandler` must be a function");
}
this._logHandler = val;
}
get userLogHandler() {
return this._userLogHandler;
}
set userLogHandler(val) {
this._userLogHandler = val;
}
/**
* The functions below are all based on the `console` interface
*/
debug(...args) {
this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);
this._logHandler(this, LogLevel.DEBUG, ...args);
}
log(...args) {
this._userLogHandler && this._userLogHandler(this, LogLevel.VERBOSE, ...args);
this._logHandler(this, LogLevel.VERBOSE, ...args);
}
info(...args) {
this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);
this._logHandler(this, LogLevel.INFO, ...args);
}
warn(...args) {
this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);
this._logHandler(this, LogLevel.WARN, ...args);
}
error(...args) {
this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);
this._logHandler(this, LogLevel.ERROR, ...args);
}
};
function setLogLevel(level) {
instances.forEach((inst) => {
inst.setLogLevel(level);
});
}
function setUserLogHandler(logCallback, options) {
for (const instance of instances) {
let customLogLevel = null;
if (options && options.level) {
customLogLevel = levelStringToEnum[options.level];
}
if (logCallback === null) {
instance.userLogHandler = null;
} else {
instance.userLogHandler = (instance2, level, ...args) => {
const message = args.map((arg) => {
if (arg == null) {
return null;
} else if (typeof arg === "string") {
return arg;
} else if (typeof arg === "number" || typeof arg === "boolean") {
return arg.toString();
} else if (arg instanceof Error) {
return arg.message;
} else {
try {
return JSON.stringify(arg);
} catch (ignored) {
return null;
}
}
}).filter((arg) => arg).join(" ");
if (level >= (customLogLevel ?? instance2.logLevel)) {
logCallback({
level: LogLevel[level].toLowerCase(),
message,
args,
type: instance2.name
});
}
};
}
}
}
// node_modules/idb/build/wrap-idb-value.js
var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
var idbProxyableTypes;
var cursorAdvanceMethods;
function getIdbProxyableTypes() {
return idbProxyableTypes || (idbProxyableTypes = [
IDBDatabase,
IDBObjectStore,
IDBIndex,
IDBCursor,
IDBTransaction
]);
}
function getCursorAdvanceMethods() {
return cursorAdvanceMethods || (cursorAdvanceMethods = [
IDBCursor.prototype.advance,
IDBCursor.prototype.continue,
IDBCursor.prototype.continuePrimaryKey
]);
}
var cursorRequestMap = /* @__PURE__ */ new WeakMap();
var transactionDoneMap = /* @__PURE__ */ new WeakMap();
var transactionStoreNamesMap = /* @__PURE__ */ new WeakMap();
var transformCache = /* @__PURE__ */ new WeakMap();
var reverseTransformCache = /* @__PURE__ */ new WeakMap();
function promisifyRequest(request) {
const promise = new Promise((resolve, reject) => {
const unlisten = () => {
request.removeEventListener("success", success);
request.removeEventListener("error", error);
};
const success = () => {
resolve(wrap(request.result));
unlisten();
};
const error = () => {
reject(request.error);
unlisten();
};
request.addEventListener("success", success);
request.addEventListener("error", error);
});
promise.then((value) => {
if (value instanceof IDBCursor) {
cursorRequestMap.set(value, request);
}
}).catch(() => {
});
reverseTransformCache.set(promise, request);
return promise;
}
function cacheDonePromiseForTransaction(tx) {
if (transactionDoneMap.has(tx))
return;
const done = new Promise((resolve, reject) => {
const unlisten = () => {
tx.removeEventListener("complete", complete);
tx.removeEventListener("error", error);
tx.removeEventListener("abort", error);
};
const complete = () => {
resolve();
unlisten();
};
const error = () => {
reject(tx.error || new DOMException("AbortError", "AbortError"));
unlisten();
};
tx.addEventListener("complete", complete);
tx.addEventListener("error", error);
tx.addEventListener("abort", error);
});
transactionDoneMap.set(tx, done);
}
var idbProxyTraps = {
get(target, prop, receiver) {
if (target instanceof IDBTransaction) {
if (prop === "done")
return transactionDoneMap.get(target);
if (prop === "objectStoreNames") {
return target.objectStoreNames || transactionStoreNamesMap.get(target);
}
if (prop === "store") {
return receiver.objectStoreNames[1] ? void 0 : receiver.objectStore(receiver.objectStoreNames[0]);
}
}
return wrap(target[prop]);
},
set(target, prop, value) {
target[prop] = value;
return true;
},
has(target, prop) {
if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) {
return true;
}
return prop in target;
}
};
function replaceTraps(callback) {
idbProxyTraps = callback(idbProxyTraps);
}
function wrapFunction(func) {
if (func === IDBDatabase.prototype.transaction && !("objectStoreNames" in IDBTransaction.prototype)) {
return function(storeNames, ...args) {
const tx = func.call(unwrap(this), storeNames, ...args);
transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);
return wrap(tx);
};
}
if (getCursorAdvanceMethods().includes(func)) {
return function(...args) {
func.apply(unwrap(this), args);
return wrap(cursorRequestMap.get(this));
};
}
return function(...args) {
return wrap(func.apply(unwrap(this), args));
};
}
function transformCachableValue(value) {
if (typeof value === "function")
return wrapFunction(value);
if (value instanceof IDBTransaction)
cacheDonePromiseForTransaction(value);
if (instanceOfAny(value, getIdbProxyableTypes()))
return new Proxy(value, idbProxyTraps);
return value;
}
function wrap(value) {
if (value instanceof IDBRequest)
return promisifyRequest(value);
if (transformCache.has(value))
return transformCache.get(value);
const newValue = transformCachableValue(value);
if (newValue !== value) {
transformCache.set(value, newValue);
reverseTransformCache.set(newValue, value);
}
return newValue;
}
var unwrap = (value) => reverseTransformCache.get(value);
// node_modules/idb/build/index.js
function openDB(name2, version2, { blocked, upgrade, blocking, terminated } = {}) {
const request = indexedDB.open(name2, version2);
const openPromise = wrap(request);
if (upgrade) {
request.addEventListener("upgradeneeded", (event) => {
upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
});
}
if (blocked) {
request.addEventListener("blocked", (event) => blocked(
// Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
event.oldVersion,
event.newVersion,
event
));
}
openPromise.then((db) => {
if (terminated)
db.addEventListener("close", () => terminated());
if (blocking) {
db.addEventListener("versionchange", (event) => blocking(event.oldVersion, event.newVersion, event));
}
}).catch(() => {
});
return openPromise;
}
var readMethods = ["get", "getKey", "getAll", "getAllKeys", "count"];
var writeMethods = ["put", "add", "delete", "clear"];
var cachedMethods = /* @__PURE__ */ new Map();
function getMethod(target, prop) {
if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) {
return;
}
if (cachedMethods.get(prop))
return cachedMethods.get(prop);
const targetFuncName = prop.replace(/FromIndex$/, "");
const useIndex = prop !== targetFuncName;
const isWrite = writeMethods.includes(targetFuncName);
if (
// Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))
) {
return;
}
const method = async function(storeName, ...args) {
const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly");
let target2 = tx.store;
if (useIndex)
target2 = target2.index(args.shift());
return (await Promise.all([
target2[targetFuncName](...args),
isWrite && tx.done
]))[0];
};
cachedMethods.set(prop, method);
return method;
}
replaceTraps((oldTraps) => ({
...oldTraps,
get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
}));
// node_modules/@firebase/app/dist/esm/index.esm.js
var PlatformLoggerServiceImpl = class {
constructor(container) {
this.container = container;
}
// In initial implementation, this will be called by installations on
// auth token refresh, and installations will send this string.
getPlatformInfoString() {
const providers = this.container.getProviders();
return providers.map((provider) => {
if (isVersionServiceProvider(provider)) {
const service = provider.getImmediate();
return `${service.library}/${service.version}`;
} else {
return null;
}
}).filter((logString) => logString).join(" ");
}
};
function isVersionServiceProvider(provider) {
const component = provider.getComponent();
return component?.type === "VERSION";
}
var name$q = "@firebase/app";
var version$1 = "0.14.9";
var logger = new Logger("@firebase/app");
var name$p = "@firebase/app-compat";
var name$o = "@firebase/analytics-compat";
var name$n = "@firebase/analytics";
var name$m = "@firebase/app-check-compat";
var name$l = "@firebase/app-check";
var name$k = "@firebase/auth";
var name$j = "@firebase/auth-compat";
var name$i = "@firebase/database";
var name$h = "@firebase/data-connect";
var name$g = "@firebase/database-compat";
var name$f = "@firebase/functions";
var name$e = "@firebase/functions-compat";
var name$d = "@firebase/installations";
var name$c = "@firebase/installations-compat";
var name$b = "@firebase/messaging";
var name$a = "@firebase/messaging-compat";
var name$9 = "@firebase/performance";
var name$8 = "@firebase/performance-compat";
var name$7 = "@firebase/remote-config";
var name$6 = "@firebase/remote-config-compat";
var name$5 = "@firebase/storage";
var name$4 = "@firebase/storage-compat";
var name$3 = "@firebase/firestore";
var name$2 = "@firebase/ai";
var name$1 = "@firebase/firestore-compat";
var name = "firebase";
var version = "12.10.0";
var DEFAULT_ENTRY_NAME2 = "[DEFAULT]";
var PLATFORM_LOG_STRING = {
[name$q]: "fire-core",
[name$p]: "fire-core-compat",
[name$n]: "fire-analytics",
[name$o]: "fire-analytics-compat",
[name$l]: "fire-app-check",
[name$m]: "fire-app-check-compat",
[name$k]: "fire-auth",
[name$j]: "fire-auth-compat",
[name$i]: "fire-rtdb",
[name$h]: "fire-data-connect",
[name$g]: "fire-rtdb-compat",
[name$f]: "fire-fn",
[name$e]: "fire-fn-compat",
[name$d]: "fire-iid",
[name$c]: "fire-iid-compat",
[name$b]: "fire-fcm",
[name$a]: "fire-fcm-compat",
[name$9]: "fire-perf",
[name$8]: "fire-perf-compat",
[name$7]: "fire-rc",
[name$6]: "fire-rc-compat",
[name$5]: "fire-gcs",
[name$4]: "fire-gcs-compat",
[name$3]: "fire-fst",
[name$1]: "fire-fst-compat",
[name$2]: "fire-vertex",
"fire-js": "fire-js",
// Platform identifier for JS SDK.
[name]: "fire-js-all"
};
var _apps = /* @__PURE__ */ new Map();
var _serverApps = /* @__PURE__ */ new Map();
var _components = /* @__PURE__ */ new Map();
function _addComponent(app, component) {
try {
app.container.addComponent(component);
} catch (e) {
logger.debug(`Component ${component.name} failed to register with FirebaseApp ${app.name}`, e);
}
}
function _addOrOverwriteComponent(app, component) {
app.container.addOrOverwriteComponent(component);
}
function _registerComponent(component) {
const componentName = component.name;
if (_components.has(componentName)) {
logger.debug(`There were multiple attempts to register component ${componentName}.`);
return false;
}
_components.set(componentName, component);
for (const app of _apps.values()) {
_addComponent(app, component);
}
for (const serverApp of _serverApps.values()) {
_addComponent(serverApp, component);
}
return true;
}
function _getProvider(app, name2) {
const heartbeatController = app.container.getProvider("heartbeat").getImmediate({ optional: true });
if (heartbeatController) {
void heartbeatController.triggerHeartbeat();
}
return app.container.getProvider(name2);
}
function _removeServiceInstance(app, name2, instanceIdentifier = DEFAULT_ENTRY_NAME2) {
_getProvider(app, name2).clearInstance(instanceIdentifier);
}
function _isFirebaseApp(obj) {
return obj.options !== void 0;
}
function _isFirebaseServerAppSettings(obj) {
if (_isFirebaseApp(obj)) {
return false;
}
return "authIdToken" in obj || "appCheckToken" in obj || "releaseOnDeref" in obj || "automaticDataCollectionEnabled" in obj;
}
function _isFirebaseServerApp(obj) {
if (obj === null || obj === void 0) {
return false;
}
return obj.settings !== void 0;
}
function _clearComponents() {
_components.clear();
}
var ERRORS = {
[
"no-app"
/* AppError.NO_APP */
]: "No Firebase App '{$appName}' has been created - call initializeApp() first",
[
"bad-app-name"
/* AppError.BAD_APP_NAME */
]: "Illegal App name: '{$appName}'",
[
"duplicate-app"
/* AppError.DUPLICATE_APP */
]: "Firebase App named '{$appName}' already exists with different options or config",
[
"app-deleted"
/* AppError.APP_DELETED */
]: "Firebase App named '{$appName}' already deleted",
[
"server-app-deleted"
/* AppError.SERVER_APP_DELETED */
]: "Firebase Server App has been deleted",
[
"no-options"
/* AppError.NO_OPTIONS */
]: "Need to provide options, when not being deployed to hosting via source.",
[
"invalid-app-argument"
/* AppError.INVALID_APP_ARGUMENT */
]: "firebase.{$appName}() takes either no argument or a Firebase App instance.",
[
"invalid-log-argument"
/* AppError.INVALID_LOG_ARGUMENT */
]: "First argument to `onLog` must be null or a function.",
[
"idb-open"
/* AppError.IDB_OPEN */
]: "Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.",
[
"idb-get"
/* AppError.IDB_GET */
]: "Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.",
[
"idb-set"
/* AppError.IDB_WRITE */
]: "Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.",
[
"idb-delete"
/* AppError.IDB_DELETE */
]: "Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.",
[
"finalization-registry-not-supported"
/* AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED */
]: "FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.",
[
"invalid-server-app-environment"
/* AppError.INVALID_SERVER_APP_ENVIRONMENT */
]: "FirebaseServerApp is not for use in browser environments."
};
var ERROR_FACTORY = new ErrorFactory("app", "Firebase", ERRORS);
var FirebaseAppImpl = class {
constructor(options, config, container) {
this._isDeleted = false;
this._options = { ...options };
this._config = { ...config };
this._name = config.name;
this._automaticDataCollectionEnabled = config.automaticDataCollectionEnabled;
this._container = container;
this.container.addComponent(new Component(
"app",
() => this,
"PUBLIC"
/* ComponentType.PUBLIC */
));
}
get automaticDataCollectionEnabled() {
this.checkDestroyed();
return this._automaticDataCollectionEnabled;
}
set automaticDataCollectionEnabled(val) {
this.checkDestroyed();
this._automaticDataCollectionEnabled = val;
}
get name() {
this.checkDestroyed();
return this._name;
}
get options() {
this.checkDestroyed();
return this._options;
}
get config() {
this.checkDestroyed();
return this._config;
}
get container() {
return this._container;
}
get isDeleted() {
return this._isDeleted;
}
set isDeleted(val) {
this._isDeleted = val;
}
/**
* This function will throw an Error if the App has already been deleted -
* use before performing API actions on the App.
*/
checkDestroyed() {
if (this.isDeleted) {
throw ERROR_FACTORY.create("app-deleted", { appName: this._name });
}
}
};
function validateTokenTTL(base64Token, tokenName) {
const secondPart = base64Decode(base64Token.split(".")[1]);
if (secondPart === null) {
console.error(`FirebaseServerApp ${tokenName} is invalid: second part could not be parsed.`);
return;
}
const expClaim = JSON.parse(secondPart).exp;
if (expClaim === void 0) {
console.error(`FirebaseServerApp ${tokenName} is invalid: expiration claim could not be parsed`);
return;
}
const exp = JSON.parse(secondPart).exp * 1e3;
const now = (/* @__PURE__ */ new Date()).getTime();
const diff = exp - now;
if (diff <= 0) {
console.error(`FirebaseServerApp ${tokenName} is invalid: the token has expired.`);
}
}
var FirebaseServerAppImpl = class extends FirebaseAppImpl {
constructor(options, serverConfig, name2, container) {
const automaticDataCollectionEnabled = serverConfig.automaticDataCollectionEnabled !== void 0 ? serverConfig.automaticDataCollectionEnabled : true;
const config = {
name: name2,
automaticDataCollectionEnabled
};
if (options.apiKey !== void 0) {
super(options, config, container);
} else {
const appImpl = options;
super(appImpl.options, config, container);
}
this._serverConfig = {
automaticDataCollectionEnabled,
...serverConfig
};
if (this._serverConfig.authIdToken) {
validateTokenTTL(this._serverConfig.authIdToken, "authIdToken");
}
if (this._serverConfig.appCheckToken) {
validateTokenTTL(this._serverConfig.appCheckToken, "appCheckToken");
}
this._finalizationRegistry = null;
if (typeof FinalizationRegistry !== "undefined") {
this._finalizationRegistry = new FinalizationRegistry(() => {
this.automaticCleanup();
});
}
this._refCount = 0;
this.incRefCount(this._serverConfig.releaseOnDeref);
this._serverConfig.releaseOnDeref = void 0;
serverConfig.releaseOnDeref = void 0;
registerVersion(name$q, version$1, "serverapp");
}
toJSON() {
return void 0;
}
get refCount() {
return this._refCount;
}
// Increment the reference count of this server app. If an object is provided, register it
// with the finalization registry.
incRefCount(obj) {
if (this.isDeleted) {
return;
}
this._refCount++;
if (obj !== void 0 && this._finalizationRegistry !== null) {
this._finalizationRegistry.register(obj, this);
}
}
// Decrement the reference count.
decRefCount() {
if (this.isDeleted) {
return 0;
}
return --this._refCount;
}
// Invoked by the FinalizationRegistry callback to note that this app should go through its
// reference counts and delete itself if no reference count remain. The coordinating logic that
// handles this is in deleteApp(...).
automaticCleanup() {
void deleteApp(this);
}
get settings() {
this.checkDestroyed();
return this._serverConfig;
}
/**
* This function will throw an Error if the App has already been deleted -
* use before performing API actions on the App.
*/
checkDestroyed() {
if (this.isDeleted) {
throw ERROR_FACTORY.create(
"server-app-deleted"
/* AppError.SERVER_APP_DELETED */
);
}
}
};
var SDK_VERSION = version;
function initializeApp(_options, rawConfig = {}) {
let options = _options;
if (typeof rawConfig !== "object") {
const name3 = rawConfig;
rawConfig = { name: name3 };
}
const config = {
name: DEFAULT_ENTRY_NAME2,
automaticDataCollectionEnabled: true,
...rawConfig
};
const name2 = config.name;
if (typeof name2 !== "string" || !name2) {
throw ERROR_FACTORY.create("bad-app-name", {
appName: String(name2)
});
}
options || (options = getDefaultAppConfig());
if (!options) {
throw ERROR_FACTORY.create(
"no-options"
/* AppError.NO_OPTIONS */
);
}
const existingApp = _apps.get(name2);
if (existingApp) {
if (deepEqual(options, existingApp.options) && deepEqual(config, existingApp.config)) {
return existingApp;
} else {
throw ERROR_FACTORY.create("duplicate-app", { appName: name2 });
}
}
const container = new ComponentContainer(name2);
for (const component of _components.values()) {
container.addComponent(component);
}
const newApp = new FirebaseAppImpl(options, config, container);
_apps.set(name2, newApp);
return newApp;
}
function initializeServerApp(_options, _serverAppConfig = {}) {
if (isBrowser() && !isWebWorker()) {
throw ERROR_FACTORY.create(
"invalid-server-app-environment"
/* AppError.INVALID_SERVER_APP_ENVIRONMENT */
);
}
let firebaseOptions;
let serverAppSettings = _serverAppConfig || {};
if (_options) {
if (_isFirebaseApp(_options)) {
firebaseOptions = _options.options;
} else if (_isFirebaseServerAppSettings(_options)) {
serverAppSettings = _options;
} else {
firebaseOptions = _options;
}
}
if (serverAppSettings.automaticDataCollectionEnabled === void 0) {
serverAppSettings.automaticDataCollectionEnabled = true;
}
firebaseOptions || (firebaseOptions = getDefaultAppConfig());
if (!firebaseOptions) {
throw ERROR_FACTORY.create(
"no-options"
/* AppError.NO_OPTIONS */
);
}
const nameObj = {
...serverAppSettings,
...firebaseOptions
};
if (nameObj.releaseOnDeref !== void 0) {
delete nameObj.releaseOnDeref;
}
const hashCode = (s) => {
return [...s].reduce((hash, c) => Math.imul(31, hash) + c.charCodeAt(0) | 0, 0);
};
if (serverAppSettings.releaseOnDeref !== void 0) {
if (typeof FinalizationRegistry === "undefined") {
throw ERROR_FACTORY.create("finalization-registry-not-supported", {});
}
}
const nameString = "" + hashCode(JSON.stringify(nameObj));
const existingApp = _serverApps.get(nameString);
if (existingApp) {
existingApp.incRefCount(serverAppSettings.releaseOnDeref);
return existingApp;
}
const container = new ComponentContainer(nameString);
for (const component of _components.values()) {
container.addComponent(component);
}
const newApp = new FirebaseServerAppImpl(firebaseOptions, serverAppSettings, nameString, container);
_serverApps.set(nameString, newApp);
return newApp;
}
function getApp(name2 = DEFAULT_ENTRY_NAME2) {
const app = _apps.get(name2);
if (!app && name2 === DEFAULT_ENTRY_NAME2 && getDefaultAppConfig()) {
return initializeApp();
}
if (!app) {
throw ERROR_FACTORY.create("no-app", { appName: name2 });
}
return app;
}
function getApps() {
return Array.from(_apps.values());
}
async function deleteApp(app) {
let cleanupProviders = false;
const name2 = app.name;
if (_apps.has(name2)) {
cleanupProviders = true;
_apps.delete(name2);
} else if (_serverApps.has(name2)) {
const firebaseServerApp = app;
if (firebaseServerApp.decRefCount() <= 0) {
_serverApps.delete(name2);
cleanupProviders = true;
}
}
if (cleanupProviders) {
await Promise.all(app.container.getProviders().map((provider) => provider.delete()));
app.isDeleted = true;
}
}
function registerVersion(libraryKeyOrName, version2, variant) {
let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;
if (variant) {
library += `-${variant}`;
}
const libraryMismatch = library.match(/\s|\//);
const versionMismatch = version2.match(/\s|\//);
if (libraryMismatch || versionMismatch) {
const warning = [
`Unable to register library "${library}" with version "${version2}":`
];
if (libraryMismatch) {
warning.push(`library name "${library}" contains illegal characters (whitespace or "/")`);
}
if (libraryMismatch && versionMismatch) {
warning.push("and");
}
if (versionMismatch) {
warning.push(`version name "${version2}" contains illegal characters (whitespace or "/")`);
}
logger.warn(warning.join(" "));
return;
}
_registerComponent(new Component(
`${library}-version`,
() => ({ library, version: version2 }),
"VERSION"
/* ComponentType.VERSION */
));
}
function onLog(logCallback, options) {
if (logCallback !== null && typeof logCallback !== "function") {
throw ERROR_FACTORY.create(
"invalid-log-argument"
/* AppError.INVALID_LOG_ARGUMENT */
);
}
setUserLogHandler(logCallback, options);
}
function setLogLevel2(logLevel) {
setLogLevel(logLevel);
}
var DB_NAME = "firebase-heartbeat-database";
var DB_VERSION = 1;
var STORE_NAME = "firebase-heartbeat-store";
var dbPromise = null;
function getDbPromise() {
if (!dbPromise) {
dbPromise = openDB(DB_NAME, DB_VERSION, {
upgrade: (db, oldVersion) => {
switch (oldVersion) {
case 0:
try {
db.createObjectStore(STORE_NAME);
} catch (e) {
console.warn(e);
}
}
}
}).catch((e) => {
throw ERROR_FACTORY.create("idb-open", {
originalErrorMessage: e.message
});
});
}
return dbPromise;
}
async function readHeartbeatsFromIndexedDB(app) {
try {
const db = await getDbPromise();
const tx = db.transaction(STORE_NAME);
const result = await tx.objectStore(STORE_NAME).get(computeKey(app));
await tx.done;
return result;
} catch (e) {
if (e instanceof FirebaseError) {
logger.warn(e.message);
} else {
const idbGetError = ERROR_FACTORY.create("idb-get", {
originalErrorMessage: e?.message
});
logger.warn(idbGetError.message);
}
}
}
async function writeHeartbeatsToIndexedDB(app, heartbeatObject) {
try {
const db = await getDbPromise();
const tx = db.transaction(STORE_NAME, "readwrite");
const objectStore = tx.objectStore(STORE_NAME);
await objectStore.put(heartbeatObject, computeKey(app));
await tx.done;
} catch (e) {
if (e instanceof FirebaseError) {
logger.warn(e.message);
} else {
const idbGetError = ERROR_FACTORY.create("idb-set", {
originalErrorMessage: e?.message
});
logger.warn(idbGetError.message);
}
}
}
function computeKey(app) {
return `${app.name}!${app.options.appId}`;
}
var MAX_HEADER_BYTES = 1024;
var MAX_NUM_STORED_HEARTBEATS = 30;
var HeartbeatServiceImpl = class {
constructor(container) {
this.container = container;
this._heartbeatsCache = null;
const app = this.container.getProvider("app").getImmediate();
this._storage = new HeartbeatStorageImpl(app);
this._heartbeatsCachePromise = this._storage.read().then((result) => {
this._heartbeatsCache = result;
return result;
});
}
/**
* Called to report a heartbeat. The function will generate
* a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it
* to IndexedDB.
* Note that we only store one heartbeat per day. So if a heartbeat for today is
* already logged, subsequent calls to this function in the same day will be ignored.
*/
async triggerHeartbeat() {
try {
const platformLogger = this.container.getProvider("platform-logger").getImmediate();
const agent = platformLogger.getPlatformInfoString();
const date = getUTCDateString();
if (this._heartbeatsCache?.heartbeats == null) {
this._heartbeatsCache = await this._heartbeatsCachePromise;
if (this._heartbeatsCache?.heartbeats == null) {
return;
}
}
if (this._heartbeatsCache.lastSentHeartbeatDate === date || this._heartbeatsCache.heartbeats.some((singleDateHeartbeat) => singleDateHeartbeat.date === date)) {
return;
} else {
this._heartbeatsCache.heartbeats.push({ date, agent });
if (this._heartbeatsCache.heartbeats.length > MAX_NUM_STORED_HEARTBEATS) {
const earliestHeartbeatIdx = getEarliestHeartbeatIdx(this._heartbeatsCache.heartbeats);
this._heartbeatsCache.heartbeats.splice(earliestHeartbeatIdx, 1);
}
}
return this._storage.overwrite(this._heartbeatsCache);
} catch (e) {
logger.warn(e);
}
}
/**
* Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.
* It also clears all heartbeats from memory as well as in IndexedDB.
*
* NOTE: Consuming product SDKs should not send the header if this method
* returns an empty string.
*/
async getHeartbeatsHeader() {
try {
if (this._heartbeatsCache === null) {
await this._heartbeatsCachePromise;
}
if (this._heartbeatsCache?.heartbeats == null || this._heartbeatsCache.heartbeats.length === 0) {
return "";
}
const date = getUTCDateString();
const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats);
const headerString = base64urlEncodeWithoutPadding(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
this._heartbeatsCache.lastSentHeartbeatDate = date;
if (unsentEntries.length > 0) {
this._heartbeatsCache.heartbeats = unsentEntries;
await this._storage.overwrite(this._heartbeatsCache);
} else {
this._heartbeatsCache.heartbeats = [];
void this._storage.overwrite(this._heartbeatsCache);
}
return headerString;
} catch (e) {
logger.warn(e);
return "";
}
}
};
function getUTCDateString() {
const today = /* @__PURE__ */ new Date();
return today.toISOString().substring(0, 10);
}
function extractHeartbeatsForHeader(heartbeatsCache, maxSize = MAX_HEADER_BYTES) {
const heartbeatsToSend = [];
let unsentEntries = heartbeatsCache.slice();
for (const singleDateHeartbeat of heartbeatsCache) {
const heartbeatEntry = heartbeatsToSend.find((hb) => hb.agent === singleDateHeartbeat.agent);
if (!heartbeatEntry) {
heartbeatsToSend.push({
agent: singleDateHeartbeat.agent,
dates: [singleDateHeartbeat.date]
});
if (countBytes(heartbeatsToSend) > maxSize) {
heartbeatsToSend.pop();
break;
}
} else {
heartbeatEntry.dates.push(singleDateHeartbeat.date);
if (countBytes(heartbeatsToSend) > maxSize) {
heartbeatEntry.dates.pop();
break;
}
}
unsentEntries = unsentEntries.slice(1);
}
return {
heartbeatsToSend,
unsentEntries
};
}
var HeartbeatStorageImpl = class {
constructor(app) {
this.app = app;
this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();
}
async runIndexedDBEnvironmentCheck() {
if (!isIndexedDBAvailable()) {
return false;
} else {
return validateIndexedDBOpenable().then(() => true).catch(() => false);
}
}
/**
* Read all heartbeats.
*/
async read() {
const canUseIndexedDB = await this._canUseIndexedDBPromise;
if (!canUseIndexedDB) {
return { heartbeats: [] };
} else {
const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);
if (idbHeartbeatObject?.heartbeats) {
return idbHeartbeatObject;
} else {
return { heartbeats: [] };
}
}
}
// overwrite the storage with the provided heartbeats
async overwrite(heartbeatsObject) {
const canUseIndexedDB = await this._canUseIndexedDBPromise;
if (!canUseIndexedDB) {
return;
} else {
const existingHeartbeatsObject = await this.read();
return writeHeartbeatsToIndexedDB(this.app, {
lastSentHeartbeatDate: heartbeatsObject.lastSentHeartbeatDate ?? existingHeartbeatsObject.lastSentHeartbeatDate,
heartbeats: heartbeatsObject.heartbeats
});
}
}
// add heartbeats
async add(heartbeatsObject) {
const canUseIndexedDB = await this._canUseIndexedDBPromise;
if (!canUseIndexedDB) {
return;
} else {
const existingHeartbeatsObject = await this.read();
return writeHeartbeatsToIndexedDB(this.app, {
lastSentHeartbeatDate: heartbeatsObject.lastSentHeartbeatDate ?? existingHeartbeatsObject.lastSentHeartbeatDate,
heartbeats: [
...existingHeartbeatsObject.heartbeats,
...heartbeatsObject.heartbeats
]
});
}
}
};
function countBytes(heartbeatsCache) {
return base64urlEncodeWithoutPadding(
// heartbeatsCache wrapper properties
JSON.stringify({ version: 2, heartbeats: heartbeatsCache })
).length;
}
function getEarliestHeartbeatIdx(heartbeats) {
if (heartbeats.length === 0) {
return -1;
}
let earliestHeartbeatIdx = 0;
let earliestHeartbeatDate = heartbeats[0].date;
for (let i = 1; i < heartbeats.length; i++) {
if (heartbeats[i].date < earliestHeartbeatDate) {
earliestHeartbeatDate = heartbeats[i].date;
earliestHeartbeatIdx = i;
}
}
return earliestHeartbeatIdx;
}
function registerCoreComponents(variant) {
_registerComponent(new Component(
"platform-logger",
(container) => new PlatformLoggerServiceImpl(container),
"PRIVATE"
/* ComponentType.PRIVATE */
));
_registerComponent(new Component(
"heartbeat",
(container) => new HeartbeatServiceImpl(container),
"PRIVATE"
/* ComponentType.PRIVATE */
));
registerVersion(name$q, version$1, variant);
registerVersion(name$q, version$1, "esm2020");
registerVersion("fire-js", "");
}
registerCoreComponents("");
export {
base64Decode,
getGlobal,
getDefaultEmulatorHost,
getDefaultEmulatorHostnameAndPort,
getExperimentalSetting,
isCloudWorkstation,
pingServer,
createMockUserToken,
updateEmulatorBanner,
getUA,
isMobileCordova,
isCloudflareWorker,
isBrowserExtension,
isReactNative,
isIE,
isSafari,
isSafariOrWebkit,
isIndexedDBAvailable,
FirebaseError,
ErrorFactory,
isEmpty,
deepEqual,
querystring,
querystringDecode,
extractQuerystring,
createSubscribe,
getModularInstance,
Component,
LogLevel,
Logger,
DEFAULT_ENTRY_NAME2 as DEFAULT_ENTRY_NAME,
_apps,
_serverApps,
_components,
_addComponent,
_addOrOverwriteComponent,
_registerComponent,
_getProvider,
_removeServiceInstance,
_isFirebaseApp,
_isFirebaseServerAppSettings,
_isFirebaseServerApp,
_clearComponents,
SDK_VERSION,
initializeApp,
initializeServerApp,
getApp,
getApps,
deleteApp,
registerVersion,
onLog,
setLogLevel2 as setLogLevel
};
//# sourceMappingURL=chunk-2ZX2ZIUA.js.map