From 434aa8343fdcbb4d5002f934979913c099489bee Mon Sep 17 00:00:00 2001 From: altaf-creator Date: Sun, 16 Nov 2025 19:08:29 +0800 Subject: sdk, del --- .../@firebase/analytics/dist/index.cjs.js | 1287 -------------------- 1 file changed, 1287 deletions(-) delete mode 100644 frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js (limited to 'frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js') diff --git a/frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js b/frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js deleted file mode 100644 index 0d6cdfe..0000000 --- a/frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js +++ /dev/null @@ -1,1287 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var app = require('@firebase/app'); -var logger$1 = require('@firebase/logger'); -var util = require('@firebase/util'); -var component = require('@firebase/component'); -require('@firebase/installations'); - -/** - * @license - * Copyright 2019 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Type constant for Firebase Analytics. - */ -const ANALYTICS_TYPE = 'analytics'; -// Key to attach FID to in gtag params. -const GA_FID_KEY = 'firebase_id'; -const ORIGIN_KEY = 'origin'; -const FETCH_TIMEOUT_MILLIS = 60 * 1000; -const DYNAMIC_CONFIG_URL = 'https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig'; -const GTAG_URL = 'https://www.googletagmanager.com/gtag/js'; - -/** - * @license - * Copyright 2019 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const logger = new logger$1.Logger('@firebase/analytics'); - -/** - * @license - * Copyright 2019 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const ERRORS = { - ["already-exists" /* AnalyticsError.ALREADY_EXISTS */]: 'A Firebase Analytics instance with the appId {$id} ' + - ' already exists. ' + - 'Only one Firebase Analytics instance can be created for each appId.', - ["already-initialized" /* AnalyticsError.ALREADY_INITIALIZED */]: 'initializeAnalytics() cannot be called again with different options than those ' + - 'it was initially called with. It can be called again with the same options to ' + - 'return the existing instance, or getAnalytics() can be used ' + - 'to get a reference to the already-initialized instance.', - ["already-initialized-settings" /* AnalyticsError.ALREADY_INITIALIZED_SETTINGS */]: 'Firebase Analytics has already been initialized.' + - 'settings() must be called before initializing any Analytics instance' + - 'or it will have no effect.', - ["interop-component-reg-failed" /* AnalyticsError.INTEROP_COMPONENT_REG_FAILED */]: 'Firebase Analytics Interop Component failed to instantiate: {$reason}', - ["invalid-analytics-context" /* AnalyticsError.INVALID_ANALYTICS_CONTEXT */]: 'Firebase Analytics is not supported in this environment. ' + - 'Wrap initialization of analytics in analytics.isSupported() ' + - 'to prevent initialization in unsupported environments. Details: {$errorInfo}', - ["indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */]: 'IndexedDB unavailable or restricted in this environment. ' + - 'Wrap initialization of analytics in analytics.isSupported() ' + - 'to prevent initialization in unsupported environments. Details: {$errorInfo}', - ["fetch-throttle" /* AnalyticsError.FETCH_THROTTLE */]: 'The config fetch request timed out while in an exponential backoff state.' + - ' Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.', - ["config-fetch-failed" /* AnalyticsError.CONFIG_FETCH_FAILED */]: 'Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}', - ["no-api-key" /* AnalyticsError.NO_API_KEY */]: 'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field to' + - 'contain a valid API key.', - ["no-app-id" /* AnalyticsError.NO_APP_ID */]: 'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field to' + - 'contain a valid app ID.', - ["no-client-id" /* AnalyticsError.NO_CLIENT_ID */]: 'The "client_id" field is empty.', - ["invalid-gtag-resource" /* AnalyticsError.INVALID_GTAG_RESOURCE */]: 'Trusted Types detected an invalid gtag resource: {$gtagURL}.' -}; -const ERROR_FACTORY = new util.ErrorFactory('analytics', 'Analytics', ERRORS); - -/** - * @license - * Copyright 2019 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Verifies and creates a TrustedScriptURL. - */ -function createGtagTrustedTypesScriptURL(url) { - if (!url.startsWith(GTAG_URL)) { - const err = ERROR_FACTORY.create("invalid-gtag-resource" /* AnalyticsError.INVALID_GTAG_RESOURCE */, { - gtagURL: url - }); - logger.warn(err.message); - return ''; - } - return url; -} -/** - * Makeshift polyfill for Promise.allSettled(). Resolves when all promises - * have either resolved or rejected. - * - * @param promises Array of promises to wait for. - */ -function promiseAllSettled(promises) { - return Promise.all(promises.map(promise => promise.catch(e => e))); -} -/** - * Creates a TrustedTypePolicy object that implements the rules passed as policyOptions. - * - * @param policyName A string containing the name of the policy - * @param policyOptions Object containing implementations of instance methods for TrustedTypesPolicy, see {@link https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy#instance_methods - * | the TrustedTypePolicy reference documentation}. - */ -function createTrustedTypesPolicy(policyName, policyOptions) { - // Create a TrustedTypes policy that we can use for updating src - // properties - let trustedTypesPolicy; - if (window.trustedTypes) { - trustedTypesPolicy = window.trustedTypes.createPolicy(policyName, policyOptions); - } - return trustedTypesPolicy; -} -/** - * Inserts gtag script tag into the page to asynchronously download gtag. - * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). - */ -function insertScriptTag(dataLayerName, measurementId) { - const trustedTypesPolicy = createTrustedTypesPolicy('firebase-js-sdk-policy', { - createScriptURL: createGtagTrustedTypesScriptURL - }); - const script = document.createElement('script'); - // We are not providing an analyticsId in the URL because it would trigger a `page_view` - // without fid. We will initialize ga-id using gtag (config) command together with fid. - const gtagScriptURL = `${GTAG_URL}?l=${dataLayerName}&id=${measurementId}`; - script.src = trustedTypesPolicy - ? trustedTypesPolicy?.createScriptURL(gtagScriptURL) - : gtagScriptURL; - script.async = true; - document.head.appendChild(script); -} -/** - * Get reference to, or create, global datalayer. - * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). - */ -function getOrCreateDataLayer(dataLayerName) { - // Check for existing dataLayer and create if needed. - let dataLayer = []; - if (Array.isArray(window[dataLayerName])) { - dataLayer = window[dataLayerName]; - } - else { - window[dataLayerName] = dataLayer; - } - return dataLayer; -} -/** - * Wrapped gtag logic when gtag is called with 'config' command. - * - * @param gtagCore Basic gtag function that just appends to dataLayer. - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. - * @param measurementId GA Measurement ID to set config for. - * @param gtagParams Gtag config params to set. - */ -async function gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams) { - // If config is already fetched, we know the appId and can use it to look up what FID promise we - /// are waiting for, and wait only on that one. - const correspondingAppId = measurementIdToAppId[measurementId]; - try { - if (correspondingAppId) { - await initializationPromisesMap[correspondingAppId]; - } - else { - // If config is not fetched yet, wait for all configs (we don't know which one we need) and - // find the appId (if any) corresponding to this measurementId. If there is one, wait on - // that appId's initialization promise. If there is none, promise resolves and gtag - // call goes through. - const dynamicConfigResults = await promiseAllSettled(dynamicConfigPromisesList); - const foundConfig = dynamicConfigResults.find(config => config.measurementId === measurementId); - if (foundConfig) { - await initializationPromisesMap[foundConfig.appId]; - } - } - } - catch (e) { - logger.error(e); - } - gtagCore("config" /* GtagCommand.CONFIG */, measurementId, gtagParams); -} -/** - * Wrapped gtag logic when gtag is called with 'event' command. - * - * @param gtagCore Basic gtag function that just appends to dataLayer. - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementId GA Measurement ID to log event to. - * @param gtagParams Params to log with this event. - */ -async function gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams) { - try { - let initializationPromisesToWaitFor = []; - // If there's a 'send_to' param, check if any ID specified matches - // an initializeIds() promise we are waiting for. - if (gtagParams && gtagParams['send_to']) { - let gaSendToList = gtagParams['send_to']; - // Make it an array if is isn't, so it can be dealt with the same way. - if (!Array.isArray(gaSendToList)) { - gaSendToList = [gaSendToList]; - } - // Checking 'send_to' fields requires having all measurement ID results back from - // the dynamic config fetch. - const dynamicConfigResults = await promiseAllSettled(dynamicConfigPromisesList); - for (const sendToId of gaSendToList) { - // Any fetched dynamic measurement ID that matches this 'send_to' ID - const foundConfig = dynamicConfigResults.find(config => config.measurementId === sendToId); - const initializationPromise = foundConfig && initializationPromisesMap[foundConfig.appId]; - if (initializationPromise) { - initializationPromisesToWaitFor.push(initializationPromise); - } - else { - // Found an item in 'send_to' that is not associated - // directly with an FID, possibly a group. Empty this array, - // exit the loop early, and let it get populated below. - initializationPromisesToWaitFor = []; - break; - } - } - } - // This will be unpopulated if there was no 'send_to' field , or - // if not all entries in the 'send_to' field could be mapped to - // a FID. In these cases, wait on all pending initialization promises. - if (initializationPromisesToWaitFor.length === 0) { - /* eslint-disable-next-line @typescript-eslint/no-floating-promises */ - initializationPromisesToWaitFor = Object.values(initializationPromisesMap); - } - // Run core gtag function with args after all relevant initialization - // promises have been resolved. - await Promise.all(initializationPromisesToWaitFor); - // Workaround for http://b/141370449 - third argument cannot be undefined. - gtagCore("event" /* GtagCommand.EVENT */, measurementId, gtagParams || {}); - } - catch (e) { - logger.error(e); - } -} -/** - * Wraps a standard gtag function with extra code to wait for completion of - * relevant initialization promises before sending requests. - * - * @param gtagCore Basic gtag function that just appends to dataLayer. - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. - */ -function wrapGtag(gtagCore, -/** - * Allows wrapped gtag calls to wait on whichever initialization promises are required, - * depending on the contents of the gtag params' `send_to` field, if any. - */ -initializationPromisesMap, -/** - * Wrapped gtag calls sometimes require all dynamic config fetches to have returned - * before determining what initialization promises (which include FIDs) to wait for. - */ -dynamicConfigPromisesList, -/** - * Wrapped gtag config calls can narrow down which initialization promise (with FID) - * to wait for if the measurementId is already fetched, by getting the corresponding appId, - * which is the key for the initialization promises map. - */ -measurementIdToAppId) { - /** - * Wrapper around gtag that ensures FID is sent with gtag calls. - * @param command Gtag command type. - * @param idOrNameOrParams Measurement ID if command is EVENT/CONFIG, params if command is SET. - * @param gtagParams Params if event is EVENT/CONFIG. - */ - async function gtagWrapper(command, ...args) { - try { - // If event, check that relevant initialization promises have completed. - if (command === "event" /* GtagCommand.EVENT */) { - const [measurementId, gtagParams] = args; - // If EVENT, second arg must be measurementId. - await gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams); - } - else if (command === "config" /* GtagCommand.CONFIG */) { - const [measurementId, gtagParams] = args; - // If CONFIG, second arg must be measurementId. - await gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams); - } - else if (command === "consent" /* GtagCommand.CONSENT */) { - const [consentAction, gtagParams] = args; - // consentAction can be one of 'default' or 'update'. - gtagCore("consent" /* GtagCommand.CONSENT */, consentAction, gtagParams); - } - else if (command === "get" /* GtagCommand.GET */) { - const [measurementId, fieldName, callback] = args; - gtagCore("get" /* GtagCommand.GET */, measurementId, fieldName, callback); - } - else if (command === "set" /* GtagCommand.SET */) { - const [customParams] = args; - // If SET, second arg must be params. - gtagCore("set" /* GtagCommand.SET */, customParams); - } - else { - gtagCore(command, ...args); - } - } - catch (e) { - logger.error(e); - } - } - return gtagWrapper; -} -/** - * Creates global gtag function or wraps existing one if found. - * This wrapped function attaches Firebase instance ID (FID) to gtag 'config' and - * 'event' calls that belong to the GAID associated with this Firebase instance. - * - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. - * @param dataLayerName Name of global GA datalayer array. - * @param gtagFunctionName Name of global gtag function ("gtag" if not user-specified). - */ -function wrapOrCreateGtag(initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, dataLayerName, gtagFunctionName) { - // Create a basic core gtag function - let gtagCore = function (..._args) { - // Must push IArguments object, not an array. - window[dataLayerName].push(arguments); - }; - // Replace it with existing one if found - if (window[gtagFunctionName] && - typeof window[gtagFunctionName] === 'function') { - // @ts-ignore - gtagCore = window[gtagFunctionName]; - } - window[gtagFunctionName] = wrapGtag(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId); - return { - gtagCore, - wrappedGtag: window[gtagFunctionName] - }; -} -/** - * Returns the script tag in the DOM matching both the gtag url pattern - * and the provided data layer name. - */ -function findGtagScriptOnPage(dataLayerName) { - const scriptTags = window.document.getElementsByTagName('script'); - for (const tag of Object.values(scriptTags)) { - if (tag.src && - tag.src.includes(GTAG_URL) && - tag.src.includes(dataLayerName)) { - return tag; - } - } - return null; -} - -/** - * @license - * Copyright 2020 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Backoff factor for 503 errors, which we want to be conservative about - * to avoid overloading servers. Each retry interval will be - * BASE_INTERVAL_MILLIS * LONG_RETRY_FACTOR ^ retryCount, so the second one - * will be ~30 seconds (with fuzzing). - */ -const LONG_RETRY_FACTOR = 30; -/** - * Base wait interval to multiplied by backoffFactor^backoffCount. - */ -const BASE_INTERVAL_MILLIS = 1000; -/** - * Stubbable retry data storage class. - */ -class RetryData { - constructor(throttleMetadata = {}, intervalMillis = BASE_INTERVAL_MILLIS) { - this.throttleMetadata = throttleMetadata; - this.intervalMillis = intervalMillis; - } - getThrottleMetadata(appId) { - return this.throttleMetadata[appId]; - } - setThrottleMetadata(appId, metadata) { - this.throttleMetadata[appId] = metadata; - } - deleteThrottleMetadata(appId) { - delete this.throttleMetadata[appId]; - } -} -const defaultRetryData = new RetryData(); -/** - * Set GET request headers. - * @param apiKey App API key. - */ -function getHeaders(apiKey) { - return new Headers({ - Accept: 'application/json', - 'x-goog-api-key': apiKey - }); -} -/** - * Fetches dynamic config from backend. - * @param app Firebase app to fetch config for. - */ -async function fetchDynamicConfig(appFields) { - const { appId, apiKey } = appFields; - const request = { - method: 'GET', - headers: getHeaders(apiKey) - }; - const appUrl = DYNAMIC_CONFIG_URL.replace('{app-id}', appId); - const response = await fetch(appUrl, request); - if (response.status !== 200 && response.status !== 304) { - let errorMessage = ''; - try { - // Try to get any error message text from server response. - const jsonResponse = (await response.json()); - if (jsonResponse.error?.message) { - errorMessage = jsonResponse.error.message; - } - } - catch (_ignored) { } - throw ERROR_FACTORY.create("config-fetch-failed" /* AnalyticsError.CONFIG_FETCH_FAILED */, { - httpStatus: response.status, - responseMessage: errorMessage - }); - } - return response.json(); -} -/** - * Fetches dynamic config from backend, retrying if failed. - * @param app Firebase app to fetch config for. - */ -async function fetchDynamicConfigWithRetry(app, -// retryData and timeoutMillis are parameterized to allow passing a different value for testing. -retryData = defaultRetryData, timeoutMillis) { - const { appId, apiKey, measurementId } = app.options; - if (!appId) { - throw ERROR_FACTORY.create("no-app-id" /* AnalyticsError.NO_APP_ID */); - } - if (!apiKey) { - if (measurementId) { - return { - measurementId, - appId - }; - } - throw ERROR_FACTORY.create("no-api-key" /* AnalyticsError.NO_API_KEY */); - } - const throttleMetadata = retryData.getThrottleMetadata(appId) || { - backoffCount: 0, - throttleEndTimeMillis: Date.now() - }; - const signal = new AnalyticsAbortSignal(); - setTimeout(async () => { - // Note a very low delay, eg < 10ms, can elapse before listeners are initialized. - signal.abort(); - }, timeoutMillis !== undefined ? timeoutMillis : FETCH_TIMEOUT_MILLIS); - return attemptFetchDynamicConfigWithRetry({ appId, apiKey, measurementId }, throttleMetadata, signal, retryData); -} -/** - * Runs one retry attempt. - * @param appFields Necessary app config fields. - * @param throttleMetadata Ongoing metadata to determine throttling times. - * @param signal Abort signal. - */ -async function attemptFetchDynamicConfigWithRetry(appFields, { throttleEndTimeMillis, backoffCount }, signal, retryData = defaultRetryData // for testing -) { - const { appId, measurementId } = appFields; - // Starts with a (potentially zero) timeout to support resumption from stored state. - // Ensures the throttle end time is honored if the last attempt timed out. - // Note the SDK will never make a request if the fetch timeout expires at this point. - try { - await setAbortableTimeout(signal, throttleEndTimeMillis); - } - catch (e) { - if (measurementId) { - logger.warn(`Timed out fetching this Firebase app's measurement ID from the server.` + - ` Falling back to the measurement ID ${measurementId}` + - ` provided in the "measurementId" field in the local Firebase config. [${e?.message}]`); - return { appId, measurementId }; - } - throw e; - } - try { - const response = await fetchDynamicConfig(appFields); - // Note the SDK only clears throttle state if response is success or non-retriable. - retryData.deleteThrottleMetadata(appId); - return response; - } - catch (e) { - const error = e; - if (!isRetriableError(error)) { - retryData.deleteThrottleMetadata(appId); - if (measurementId) { - logger.warn(`Failed to fetch this Firebase app's measurement ID from the server.` + - ` Falling back to the measurement ID ${measurementId}` + - ` provided in the "measurementId" field in the local Firebase config. [${error?.message}]`); - return { appId, measurementId }; - } - else { - throw e; - } - } - const backoffMillis = Number(error?.customData?.httpStatus) === 503 - ? util.calculateBackoffMillis(backoffCount, retryData.intervalMillis, LONG_RETRY_FACTOR) - : util.calculateBackoffMillis(backoffCount, retryData.intervalMillis); - // Increments backoff state. - const throttleMetadata = { - throttleEndTimeMillis: Date.now() + backoffMillis, - backoffCount: backoffCount + 1 - }; - // Persists state. - retryData.setThrottleMetadata(appId, throttleMetadata); - logger.debug(`Calling attemptFetch again in ${backoffMillis} millis`); - return attemptFetchDynamicConfigWithRetry(appFields, throttleMetadata, signal, retryData); - } -} -/** - * Supports waiting on a backoff by: - * - * - * - *

Visible for testing. - */ -function setAbortableTimeout(signal, throttleEndTimeMillis) { - return new Promise((resolve, reject) => { - // Derives backoff from given end time, normalizing negative numbers to zero. - const backoffMillis = Math.max(throttleEndTimeMillis - Date.now(), 0); - const timeout = setTimeout(resolve, backoffMillis); - // Adds listener, rather than sets onabort, because signal is a shared object. - signal.addEventListener(() => { - clearTimeout(timeout); - // If the request completes before this timeout, the rejection has no effect. - reject(ERROR_FACTORY.create("fetch-throttle" /* AnalyticsError.FETCH_THROTTLE */, { - throttleEndTimeMillis - })); - }); - }); -} -/** - * Returns true if the {@link Error} indicates a fetch request may succeed later. - */ -function isRetriableError(e) { - if (!(e instanceof util.FirebaseError) || !e.customData) { - return false; - } - // Uses string index defined by ErrorData, which FirebaseError implements. - const httpStatus = Number(e.customData['httpStatus']); - return (httpStatus === 429 || - httpStatus === 500 || - httpStatus === 503 || - httpStatus === 504); -} -/** - * Shims a minimal AbortSignal (copied from Remote Config). - * - *

AbortController's AbortSignal conveniently decouples fetch timeout logic from other aspects - * of networking, such as retries. Firebase doesn't use AbortController enough to justify a - * polyfill recommendation, like we do with the Fetch API, but this minimal shim can easily be - * swapped out if/when we do. - */ -class AnalyticsAbortSignal { - constructor() { - this.listeners = []; - } - addEventListener(listener) { - this.listeners.push(listener); - } - abort() { - this.listeners.forEach(listener => listener()); - } -} - -/** - * @license - * Copyright 2019 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Event parameters to set on 'gtag' during initialization. - */ -let defaultEventParametersForInit; -/** - * Logs an analytics event through the Firebase SDK. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param eventName Google Analytics event name, choose from standard list or use a custom string. - * @param eventParams Analytics event parameters. - */ -async function logEvent$1(gtagFunction, initializationPromise, eventName, eventParams, options) { - if (options && options.global) { - gtagFunction("event" /* GtagCommand.EVENT */, eventName, eventParams); - return; - } - else { - const measurementId = await initializationPromise; - const params = { - ...eventParams, - 'send_to': measurementId - }; - gtagFunction("event" /* GtagCommand.EVENT */, eventName, params); - } -} -/** - * Set screen_name parameter for this Google Analytics ID. - * - * @deprecated Use {@link logEvent} with `eventName` as 'screen_view' and add relevant `eventParams`. - * See {@link https://firebase.google.com/docs/analytics/screenviews | Track Screenviews}. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param screenName Screen name string to set. - */ -async function setCurrentScreen$1(gtagFunction, initializationPromise, screenName, options) { - if (options && options.global) { - gtagFunction("set" /* GtagCommand.SET */, { 'screen_name': screenName }); - return Promise.resolve(); - } - else { - const measurementId = await initializationPromise; - gtagFunction("config" /* GtagCommand.CONFIG */, measurementId, { - update: true, - 'screen_name': screenName - }); - } -} -/** - * Set user_id parameter for this Google Analytics ID. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param id User ID string to set - */ -async function setUserId$1(gtagFunction, initializationPromise, id, options) { - if (options && options.global) { - gtagFunction("set" /* GtagCommand.SET */, { 'user_id': id }); - return Promise.resolve(); - } - else { - const measurementId = await initializationPromise; - gtagFunction("config" /* GtagCommand.CONFIG */, measurementId, { - update: true, - 'user_id': id - }); - } -} -/** - * Set all other user properties other than user_id and screen_name. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param properties Map of user properties to set - */ -async function setUserProperties$1(gtagFunction, initializationPromise, properties, options) { - if (options && options.global) { - const flatProperties = {}; - for (const key of Object.keys(properties)) { - // use dot notation for merge behavior in gtag.js - flatProperties[`user_properties.${key}`] = properties[key]; - } - gtagFunction("set" /* GtagCommand.SET */, flatProperties); - return Promise.resolve(); - } - else { - const measurementId = await initializationPromise; - gtagFunction("config" /* GtagCommand.CONFIG */, measurementId, { - update: true, - 'user_properties': properties - }); - } -} -/** - * Retrieves a unique Google Analytics identifier for the web client. - * See {@link https://developers.google.com/analytics/devguides/collection/ga4/reference/config#client_id | client_id}. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - */ -async function internalGetGoogleAnalyticsClientId(gtagFunction, initializationPromise) { - const measurementId = await initializationPromise; - return new Promise((resolve, reject) => { - gtagFunction("get" /* GtagCommand.GET */, measurementId, 'client_id', (clientId) => { - if (!clientId) { - reject(ERROR_FACTORY.create("no-client-id" /* AnalyticsError.NO_CLIENT_ID */)); - } - resolve(clientId); - }); - }); -} -/** - * Set whether collection is enabled for this ID. - * - * @param enabled If true, collection is enabled for this ID. - */ -async function setAnalyticsCollectionEnabled$1(initializationPromise, enabled) { - const measurementId = await initializationPromise; - window[`ga-disable-${measurementId}`] = !enabled; -} -/** - * Consent parameters to default to during 'gtag' initialization. - */ -let defaultConsentSettingsForInit; -/** - * Sets the variable {@link defaultConsentSettingsForInit} for use in the initialization of - * analytics. - * - * @param consentSettings Maps the applicable end user consent state for gtag.js. - */ -function _setConsentDefaultForInit(consentSettings) { - defaultConsentSettingsForInit = consentSettings; -} -/** - * Sets the variable `defaultEventParametersForInit` for use in the initialization of - * analytics. - * - * @param customParams Any custom params the user may pass to gtag.js. - */ -function _setDefaultEventParametersForInit(customParams) { - defaultEventParametersForInit = customParams; -} - -/** - * @license - * Copyright 2020 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -async function validateIndexedDB() { - if (!util.isIndexedDBAvailable()) { - logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */, { - errorInfo: 'IndexedDB is not available in this environment.' - }).message); - return false; - } - else { - try { - await util.validateIndexedDBOpenable(); - } - catch (e) { - logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */, { - errorInfo: e?.toString() - }).message); - return false; - } - } - return true; -} -/** - * Initialize the analytics instance in gtag.js by calling config command with fid. - * - * NOTE: We combine analytics initialization and setting fid together because we want fid to be - * part of the `page_view` event that's sent during the initialization - * @param app Firebase app - * @param gtagCore The gtag function that's not wrapped. - * @param dynamicConfigPromisesList Array of all dynamic config promises. - * @param measurementIdToAppId Maps measurementID to appID. - * @param installations _FirebaseInstallationsInternal instance. - * - * @returns Measurement ID. - */ -async function _initializeAnalytics(app, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCore, dataLayerName, options) { - const dynamicConfigPromise = fetchDynamicConfigWithRetry(app); - // Once fetched, map measurementIds to appId, for ease of lookup in wrapped gtag function. - dynamicConfigPromise - .then(config => { - measurementIdToAppId[config.measurementId] = config.appId; - if (app.options.measurementId && - config.measurementId !== app.options.measurementId) { - logger.warn(`The measurement ID in the local Firebase config (${app.options.measurementId})` + - ` does not match the measurement ID fetched from the server (${config.measurementId}).` + - ` To ensure analytics events are always sent to the correct Analytics property,` + - ` update the` + - ` measurement ID field in the local config or remove it from the local config.`); - } - }) - .catch(e => logger.error(e)); - // Add to list to track state of all dynamic config promises. - dynamicConfigPromisesList.push(dynamicConfigPromise); - const fidPromise = validateIndexedDB().then(envIsValid => { - if (envIsValid) { - return installations.getId(); - } - else { - return undefined; - } - }); - const [dynamicConfig, fid] = await Promise.all([ - dynamicConfigPromise, - fidPromise - ]); - // Detect if user has already put the gtag