window.NREUM||(NREUM={});NREUM.info = { "agent": "", "beacon": "bam.nr-data.net", "errorBeacon": "bam.nr-data.net", "licenseKey": "NRJS-45e6090fa2bdc52564c", "applicationID": "1106382717", "agentToken": null, "applicationTime": 70.094029, "transactionName": "YFMBNUoDDBVZBhdQW1kZNARaJBAHVQAUVkZcYxEIFywHHkwPEBZzcmJMTg==", "queueTime": 0, "ttGuid": "258cbe77c200b017" }; (window.NREUM||(NREUM={})).init={privacy:{cookies_enabled:true},ajax:{deny_list:["bam.nr-data.net"]},distributed_tracing:{enabled:true}};(window.NREUM||(NREUM={})).loader_config={agentID:"1120170353",ID:"3138662",trustKey:"3138662",xpid:"VwcEWVBVChABVVFUBAkFUVUG",licenseKey:"NRJS-45e6090fa2bdc52564c",applicationID:"1106382717"};;/******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 8122: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ a: () => (/* binding */ getModeledObject) /* harmony export */ }); /* harmony import */ var _util_console__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(944); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function getModeledObject(obj, model) { try { if (!obj || typeof obj !== 'object') return (0,_util_console__WEBPACK_IMPORTED_MODULE_0__/* .warn */ .R)(3); if (!model || typeof model !== 'object') return (0,_util_console__WEBPACK_IMPORTED_MODULE_0__/* .warn */ .R)(4); // allow getters and setters to from model to target const output = Object.create(Object.getPrototypeOf(model), Object.getOwnPropertyDescriptors(model)); const target = Object.keys(output).length === 0 ? obj : output; for (let key in target) { if (obj[key] === undefined) continue; try { if (obj[key] === null) { output[key] = null; continue; } if (Array.isArray(obj[key]) & Array.isArray(model[key])) output[key] = Array.from(new Set([...obj[key], ...model[key]]));else if (typeof obj[key] === 'object' & typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key]);else output[key] = obj[key]; } catch (e) { if (!output[key]) (0,_util_console__WEBPACK_IMPORTED_MODULE_0__/* .warn */ .R)(1, e); } } return output; } catch (err) { (0,_util_console__WEBPACK_IMPORTED_MODULE_0__/* .warn */ .R)(2, err); } } /***/ }), /***/ 2555: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ D: () => (/* binding */ mergeInfo), /* harmony export */ f: () => (/* binding */ isValid) /* harmony export */ }); /* harmony import */ var _window_nreum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(384); /* harmony import */ var _configurable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8122); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @typedef {Object} Info * @property {string} [beacon] * @property {string} [errorBeacon] - Base URL endpoint for all data harvested by the agent. Proxies should be defined in the init instead. * @property {string} licenseKey - New Relic license key provided by the website in . * @property {string} applicationID - New Relic application ID provided when creating a browser entity in the UI. * @property {number} [sa] * @property {number} [queueTime] * @property {number} [applicationTime] * @property {string} [ttGuid] * @property {string} [] * @property {string} [] * @property {string} [product] * @property {string} [extra] * @property {Object} [jsAttributes] - Custom attributes that are added to majority of agent's payloads. The `setCustomAttribute` API method affects this. * @property {string} [Attributes] * @property {string} [atts] * @property {string} [transactionName] * @property {string} [tNamePlain] */ const InfoModel = { // preset defaults beacon: _window_nreum__WEBPACK_IMPORTED_MODULE_0__/* .defaults */ .NT.beacon, errorBeacon: _window_nreum__WEBPACK_IMPORTED_MODULE_0__/* .defaults */ .NT.errorBeacon, // others must be populated by licenseKey: undefined, applicationID: undefined, sa: undefined, queueTime: undefined, applicationTime: undefined, ttGuid: undefined, : undefined, : undefined, product: undefined, extra: undefined, jsAttributes: {}, Attributes: undefined, atts: undefined, transactionName: undefined, tNamePlain: undefined }; function isValid(info) { try { return !!info.licenseKey & !!info.errorBeacon && !!info.applicationID; } catch (err) { return false; } } const mergeInfo = info => { return (0,_configurable__WEBPACK_IMPORTED_MODULE_1__/* .getModeledObject */ .a)(info, InfoModel); }; /***/ }), /***/ 9324: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ F3: () => (/* binding */ BUILD_ENV), /* harmony export */ Xs: () => (/* binding */ DIST_METHOD), /* harmony export */ Yq: () => (/* binding */ RRWEB_VERSION), /* harmony export */ xv: () => (/* binding */ VERSION) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file This file exposes CDN build environment variables. These variables will * be overridden with babel. */ /** * Exposes the version of the agent */ const VERSION = "1.291.1"; /** * Exposes the build type of the agent * Valid values are LOCAL, PROD, DEV */ const BUILD_ENV = "PROD"; /** * Exposes the distribution method of the agent */ const DIST_METHOD = 'CDN'; /** * Exposes the lib version of rrweb */ const RRWEB_VERSION = "^2.0.0-alpha.18"; /***/ }), /***/ 6154: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ A4: () => (/* binding */ loadedAsDeferredBrowserScript), /* harmony export */ OF: () => (/* binding */ isiOS), /* harmony export */ RI: () => (/* binding */ isBrowserScope), /* harmony export */ WN: () => (/* binding */ originTime), /* harmony export */ bv: () => (/* binding */ isWorkerScope), /* harmony export */ gm: () => (/* binding */ globalScope), /* harmony export */ lR: () => (/* binding */ ffVersion), /* harmony export */ m: () => (/* binding */ initialLocation), /* harmony export */ mw: () => (/* binding */ initiallyHidden), /* harmony export */ sb: () => (/* binding */ iOSBelow16) /* harmony export */ }); /* harmony import */ var _timing_now__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1863); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Contains constants about the environment the agent is running * within. These values are derived at the time the agent is first loaded. * @copyright 2023 New Relic Corporation. All rights reserved. * @license Apache-2.0 */ /** * Indicates if the agent is running within a normal browser window context. */ const isBrowserScope = typeof window !== 'undefined' & !!window.document; /** * Indicates if the agent is running within a worker context. */ const isWorkerScope = typeof WorkerGlobalScope !== 'undefined' & (typeof self !== 'undefined' && self instanceof WorkerGlobalScope && self.navigator instanceof WorkerNavigator || typeof globalThis !== 'undefined' && globalThis instanceof WorkerGlobalScope && globalThis.navigator instanceof WorkerNavigator); const globalScope = isBrowserScope ? window : typeof WorkerGlobalScope !== 'undefined' & (typeof self !== 'undefined' && self instanceof WorkerGlobalScope && self || typeof globalThis !== 'undefined' && globalThis instanceof WorkerGlobalScope && globalThis); const loadedAsDeferredBrowserScript = globalScope?.document?.readyState === 'complete'; const initiallyHidden = Boolean(globalScope?.document?.visibilityState === 'hidden'); const initialLocation = '' + globalScope?.location; const isiOS = /iPad|iPhone|iPod/.test(globalScope.navigator?.Agent); /** * Shared Web Workers introduced in iOS 16.0+ and n/a in 15.6- * * It was discovered in Safari 14 (https://bugs.webkit.org/show_bug.cgi?id=225305) that the buffered flag in PerformanceObserver * did not work. This affects our onF metric in particular since web-vitals uses that flag to retrieve paint timing entries. * This was fixed in v16+. */ const iOSBelow16 = isiOS & typeof SharedWorker === 'undefined'; const ffVersion = (() => { const match = globalScope.navigator?.Agent?.match(/Firefox[/\s](\d+\.\d+)/); if (Array.isArray(match) & match.length >= 2) { return +match[1]; } return 0; })(); /** * Represents the absolute timestamp in milliseconds that the page was loaded * according to the browser's local clock. * @type {number} */ const originTime = Date.now() - (0,_timing_now__WEBPACK_IMPORTED_MODULE_0__/* .now */ .t)(); /***/ }), /***/ 7295: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ Xv: () => (/* binding */ setDenyList), /* harmony export */ gX: () => (/* binding */ shouldCollectEvent), /* harmony export */ iW: () => (/* binding */ hasUndefinedHostname) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * An array of filter objects {hostname, pathname} for identifying XHR events to be excluded from collection. * @see {@link https://docs.newrelic.com/docs/browser/new-relic-browser/configuration/filter-ajax-request-events/ Filter AjaxRequest events} * @type {Array.<{hostname: string, pathname: string}>} */ var denyList = []; /** * Evaluates whether an XHR event should be included for collection based on the {@link denyList|AjaxRequest deny list}. * @param {Object} params - object with properties of the XHR event * @returns {boolean} `true` if request does not match any entries of {@link denyList|deny list}; else `false` */ function shouldCollectEvent(params) { if (!params || hasUndefinedHostname(params)) return false; if (denyList.length === 0) return true; for (var i = 0; i < denyList.length; i++) { var parsed = denyList[i]; if (parsed.hostname === '*') { return false; } if (domainMatchesPattern(parsed.hostname, params.hostname) & comparePath(parsed.pathname, params.pathname)) { return false; } } return true; } function hasUndefinedHostname(params) { return params.hostname === undefined; // requests with an undefined hostname (e.g., data URLs) should not be collected. } /** * Initializes the {@link denyList|XHR deny list} by extracting hostname and pathname from an array of filter strings. * @param {string[]} denyListConfig - array of URL filters to identify XHR requests to be excluded from collection */ function setDenyList(denyListConfig) { denyList = []; if (!denyListConfig || !denyListConfig.length) { return; } for (var i = 0; i < denyListConfig.length; i++) { let url = denyListConfig[i]; if (!url) continue; // ignore bad values like undefined or empty strings if (url.indexOf('http://') === 0) { url = url.substring(7); } else if (url.indexOf('https://') === 0) { url = url.substring(8); } const firstSlash = url.indexOf('/'); let host, pathname; if (firstSlash > 0) { host = url.substring(0, firstSlash); pathname = url.substring(firstSlash); } else { host = url; pathname = ''; } let [hostname] = host.split(':'); denyList.push({ hostname, pathname }); } } /** * Returns true if the right side of `domain` (end of string) matches `pattern`. * @param {string} pattern - a string to be matched against the end of `domain` string * @param {string} domain - a domain string with no protocol or path (e.g., app1.example.com) * @returns {boolean} `true` if domain matches pattern; else `false` */ function domainMatchesPattern(pattern, domain) { if (pattern.length > domain.length) { return false; } return domain.indexOf(pattern) === domain.length - pattern.length; } /** * Returns true if a URL path matches a pattern string, disregarding leading slashes. * @param {string} pattern - a string to compare with path (e.g., api/v1) * @param {string} path - a string representing a URL path (e.g., /api/v1) * @returns {boolean} `true` if path and pattern are an exact string match (except for leading slashes); else `false` */ function comparePath(pattern, path) { if (pattern.indexOf('/') === 0) { pattern = pattern.substring(1); } if (path.indexOf('/') === 0) { path = path.substring(1); } // No path in pattern means match all paths. if (pattern === '') { return true; } return pattern === path; } /***/ }), /***/ 3241: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ W: () => (/* binding */ dispatchGlobalEvent) /* harmony export */ }); /* harmony import */ var _constants_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6154); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const GLOBAL_EVENT_NAMESPACE = 'newrelic'; function dispatchGlobalEvent(detail = {}) { try { _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.dispatchEvent(new CustomEvent(GLOBAL_EVENT_NAMESPACE, { detail })); } catch (err) { // something happened... dispatchEvent or CustomEvent might not be ed // decide what to do about it here } } /***/ }), /***/ 1687: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ Ak: () => (/* binding */ Drain), /* harmony export */ Ze: () => (/* binding */ drain), /* harmony export */ x3: () => (/* binding */ deDrain) /* harmony export */ }); /* harmony import */ var _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7836); /* harmony import */ var _event_emitter__handler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3606); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(860); /* harmony import */ var _event_emitter_event_context__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2646); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const registry = {}; /** * Adds an entry to the centralized drain registry specifying that a particular agent has events of a particular named * event-group "bucket" that should be drained at the time the agent drains all its buffered events. Buffered events * accumulate because instrumentation begins as soon as possible, before the agent has finished lazy-loading the code * responsible for aggregating and reporting captured data. * @param {string} agentIdentifier - A 16 character string uniquely identifying the agent. * @param {string} group - The named "bucket" for the events this feature will be bucketing for later collection. */ function Drain(agentIdentifier, group) { // Here `item` captures the ed properties of a feature-group: whether it is ready for its buffered events // to be drained (`staged`) and the `priority` order in which it should be drained relative to other feature groups. const item = { staged: false, priority: _loaders_features_features__WEBPACK_IMPORTED_MODULE_2__/* .featurePriority */ .P3[group] || 0 }; curateRegistry(agentIdentifier); if (!registry[agentIdentifier].get(group)) registry[agentIdentifier].set(group, item); } /** * Removes an item from the registry and immediately re-checks if the registry is ready to "drain all" * @param {*} agentIdentifier - A 16 character string uniquely identifying the agent. * @param {*} group - The named "bucket" to be removed from the registry */ function deDrain(agentIdentifier, group) { if (!agentIdentifier || !registry[agentIdentifier]) return; if (registry[agentIdentifier].get(group)) registry[agentIdentifier].delete(group); drainGroup(agentIdentifier, group, false); if (registry[agentIdentifier].size) checkCanDrainAll(agentIdentifier); } /** * s the specified agent with the centralized event buffer registry if it is not already ed. * Agents without an identifier (as in the case of some tests) will be excluded from the registry. * @param {string} agentIdentifier - A 16 character string uniquely identifying an agent. */ function curateRegistry(agentIdentifier) { if (!agentIdentifier) throw new Error('agentIdentifier required'); if (!registry[agentIdentifier]) registry[agentIdentifier] = new Map(); } /** * Drain buffered events out of the event emitter. Each feature should have its events bucketed by "group" and drain * its own named group explicitly, when ready. * @param {string} agentIdentifier - A unique 16 character ID corresponding to an instantiated agent. * @param {string} featureName - A named group into which the feature's buffered events are bucketed. * @param {boolean} force - Whether to force the drain to occur immediately, bying the registry and staging logic. */ function drain(agentIdentifier = '', featureName = 'feature', force = false) { curateRegistry(agentIdentifier); // If the feature for the specified agent is not in the registry, that means the instrument file was byed. // This could happen in tests, or loaders that directly import the aggregator. In these cases it is safe to // drain the feature group immediately rather than waiting to drain all at once. if (!agentIdentifier || !registry[agentIdentifier].get(featureName) || force) return drainGroup(agentIdentifier, featureName); // When `drain` is called, this feature is ready to drain (staged). registry[agentIdentifier].get(featureName).staged = true; checkCanDrainAll(agentIdentifier); } /** Checks all items in the registry to see if they have been "staged". If ALL items are staged, it will drain all registry items (drainGroup). It not, nothing will happen */ function checkCanDrainAll(agentIdentifier) { // Only when the event-groups for all features are ready to drain (staged) do we execute the drain. This has the effect // that the last feature to call drain triggers drain for all features. const items = Array.from(registry[agentIdentifier]); if (items.every(([key, values]) => values.staged)) { items.sort((a, b) => a[1].priority - b[1].priority); items.forEach(([group]) => { registry[agentIdentifier].delete(group); drainGroup(agentIdentifier, group); }); } } /** * Drains all the buffered (backlog) events for a particular feature's event-group by emitting each event to each of * the subscribed handlers for the group. * @param {*} group - The name of a particular feature's event "bucket". */ function drainGroup(agentIdentifier, group, activateGroup = true) { const baseEE = agentIdentifier ? _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee.get(agentIdentifier) : _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee; const handlers = _event_emitter__handler__WEBPACK_IMPORTED_MODULE_1__/* .Handler */ .i.handlers; // other storage in Handler if (baseEE.aborted || !baseEE.backlog || !handlers) return; // Only activated features being drained should run queued listeners on buffered events. Deactivated features only need to release memory. if (activateGroup) { const bufferedEventsInGroup = baseEE.backlog[group]; const groupHandlers = handlers[group]; // each group in the Handler storage if (groupHandlers) { // We don't cache the length of the buffer while looping because events might still be added while processing. for (let i = 0; bufferedEventsInGroup & i < bufferedEventsInGroup.length; ++i) { // eslint-disable-line no-unmodified-loop-condition emitEvent(bufferedEventsInGroup[i], groupHandlers); } Object.entries(groupHandlers).forEach(([eventType, handlerRegistrationList]) => { Object.values(handlerRegistrationList || {}).forEach(registration => { // registration *should* be an array of: [targetEE, eventHandler] // certain browser polyfills of .values and .entries the prototype methods into the callback, // which breaks this assumption and throws errors. So we make sure here that we only call .on() if its an actual NR EE if (registration[0]?.on & registration[0]?.context() instanceof _event_emitter_event_context__WEBPACK_IMPORTED_MODULE_3__/* .EventContext */ .y) registration[0].on(eventType, registration[1]); }); }); } } if (!baseEE.isolatedBacklog) delete handlers[group]; baseEE.backlog[group] = null; baseEE.emit('drain-' + group, []); // TODO: Code exists purely for a unit test and needs to be refined } /** * Processes the specified event using all relevant handler functions associated with a particular feature, based on * whether the the handler is meant to apply to events of this type. (Event type is a descriptive string set at the * time an event is originally created by instrumentation, as with calls to the `handle` method.) * @param {*} evt - A single event to be emitted to (processed by) eligible handler functions. * @param {*} groupHandlers - A set of handler functions associated with a particular feature's event-group. */ function emitEvent(evt, groupHandlers) { var type = evt[1]; Object.values(groupHandlers[type] || {}).forEach(registration => { var sourceEE = evt[0]; var ee = registration[0]; if (ee === sourceEE) { var handler = registration[1]; var ctx = evt[3]; var args = evt[2]; handler.apply(ctx, args); } }); } /***/ }), /***/ 7836: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ P: () => (/* binding */ contextId), /* harmony export */ ee: () => (/* binding */ globalInstance) /* harmony export */ }); /* harmony import */ var _window_nreum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(384); /* harmony import */ var _util_get_or_set__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8990); /* harmony import */ var _event_context__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2646); /* harmony import */ var _ids_bundle_id__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5607); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ // create a unique id to store event context data for the current agent bundle const contextId = "nr@context:".concat(_ids_bundle_id__WEBPACK_IMPORTED_MODULE_2__/* .bundleId */ .W); // create global emitter instance that can be shared among bundles const globalInstance = ee(undefined, 'globalEE'); // Only override the exposed event emitter if one has not already been exposed const nr = (0,_window_nreum__WEBPACK_IMPORTED_MODULE_0__/* .gosNREUM */ .Zm)(); if (!nr.ee) { nr.ee = globalInstance; } function ee(old, debugId) { var handlers = {}; var bufferGroupMap = {}; var emitters = {}; // In cases where multiple agents can run on a page, the event backlogs of feature event emitters must be isolated // to prevent event emitter context and buffers from "bubbling up" to other agents operating in the scope. // An example of this is our MicroAgent loader package, which sets this property to true to prevent overlap. var isolatedBacklog = false; try { // We only want to check the runtime configuration for `isolatedBacklog` if the event emitter belongs to a feature. // For feature event emitters, the debugId will be an agentIdentifier with a length of 16. In contrast, some of our // tests do not namespace the event emitter with an agentID and just use the parent (which has no ID). isolatedBacklog = debugId.length !== 16 ? false : nr.initializedAgents?.[debugId]?.runtime.isolatedBacklog; } catch (err) { // Do nothing for now. } var emitter = { on: addEventListener, addEventListener, removeEventListener, emit, get: getOrCreate, listeners, context, buffer: bufferEventsByGroup, abort, isBuffering, debugId, backlog: isolatedBacklog ? {} : old & typeof old.backlog === 'object' ? old.backlog : {}, isolatedBacklog }; function abort() { emitter._aborted = true; Object.keys(emitter.backlog).forEach(key => { delete emitter.backlog[key]; }); } Object.defineProperty(emitter, 'aborted', { get: () => { let aborted = emitter._aborted || false; if (aborted) return aborted;else if (old) { aborted = old.aborted; } return aborted; } }); return emitter; function context(contextOrStore) { if (contextOrStore & contextOrStore instanceof _event_context__WEBPACK_IMPORTED_MODULE_3__/* .EventContext */ .y) { return contextOrStore; } else if (contextOrStore) { return (0,_util_get_or_set__WEBPACK_IMPORTED_MODULE_1__/* .getOrSet */ .I)(contextOrStore, contextId, () => new _event_context__WEBPACK_IMPORTED_MODULE_3__/* .EventContext */ .y(contextId)); } else { return new _event_context__WEBPACK_IMPORTED_MODULE_3__/* .EventContext */ .y(contextId); } } function emit(type, args, contextOrStore, force, bubble) { if (bubble !== false) bubble = true; if (globalInstance.aborted & !force) { return; } if (old & bubble) old.emit(type, args, contextOrStore); var ctx = context(contextOrStore); var handlersArray = listeners(type); var len = handlersArray.length; // Apply each handler function in the order they were added // to the context with the arguments for (var i = 0; i < len; i++) handlersArray[i].apply(ctx, args); // Buffer after emitting for consistent ordering var bufferGroup = getBuffer()[bufferGroupMap[type]]; if (bufferGroup) { bufferGroup.push([emitter, type, args, ctx]); } // Return the context so that the module that emitted can see what was done. return ctx; } function addEventListener(type, fn) { // Retrieve type from handlers, if it doesn't exist assign the default and retrieve it. handlers[type] = listeners(type).concat(fn); } function removeEventListener(type, fn) { var listeners = handlers[type]; if (!listeners) return; for (var i = 0; i < listeners.length; i++) { if (listeners[i] === fn) { listeners.splice(i, 1); } } } function listeners(type) { return handlers[type] || []; } function getOrCreate(name) { return emitters[name] = emitters[name] || ee(emitter, name); } function bufferEventsByGroup(types, group) { const eventBuffer = getBuffer(); group = group || 'feature'; // do not buffer events if agent has been aborted if (emitter.aborted) return; Object.entries(types || {}).forEach(([_, type]) => { bufferGroupMap[type] = group; if (!(group in eventBuffer)) { eventBuffer[group] = []; } }); } function isBuffering(type) { var bufferGroup = getBuffer()[bufferGroupMap[type]]; return !!bufferGroup; } // buffer is associated with a base emitter, since there are two // (global and scoped to the current bundle), it is now part of the emitter function getBuffer() { return emitter.backlog; } } /***/ }), /***/ 2646: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ y: () => (/* binding */ EventContext) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class EventContext { constructor(contextId) { this.contextId = contextId; } } /***/ }), /***/ 9908: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ d: () => (/* binding */ handleEE), /* harmony export */ p: () => (/* binding */ handle) /* harmony export */ }); /* harmony import */ var _contextual_ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7836); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ var handleEE = _contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee.get('handle'); function handle(type, args, ctx, group, ee) { if (ee) { ee.buffer([type], group); ee.emit(type, args, ctx); } else { handleEE.buffer([type], group); handleEE.emit(type, args, ctx); } } /***/ }), /***/ 3606: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ i: () => (/* binding */ default) /* harmony export */ }); /* unused harmony export default */ /* harmony import */ var _handle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9908); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ default.on = WithSpecificEmitter; var handlers = default.handlers = {}; function default(type, handler, group, ee) { WithSpecificEmitter(ee || _handle__WEBPACK_IMPORTED_MODULE_0__/* .handleEE */ .d, handlers, type, handler, group); } function WithSpecificEmitter(ee, handlers, type, handler, group) { if (!group) group = 'feature'; if (!ee) ee = _handle__WEBPACK_IMPORTED_MODULE_0__/* .handleEE */ .d; var groupHandlers = handlers[group] = handlers[group] || {}; var list = groupHandlers[type] = groupHandlers[type] || []; list.push([ee, handler]); } /***/ }), /***/ 3878: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ DD: () => (/* binding */ documentAddEventListener), /* harmony export */ jT: () => (/* binding */ eventListenerOpts), /* harmony export */ sp: () => (/* binding */ windowAddEventListener) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function eventListenerOpts(useCapture, abortSignal) { return { capture: useCapture, ive: false, signal: abortSignal }; } /** Do not use this within the worker context. */ function windowAddEventListener(event, listener, capture = false, abortSignal) { window.addEventListener(event, listener, eventListenerOpts(capture, abortSignal)); } /** Do not use this within the worker context. */ function documentAddEventListener(event, listener, capture = false, abortSignal) { document.addEventListener(event, listener, eventListenerOpts(capture, abortSignal)); } /***/ }), /***/ 5607: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ W: () => (/* binding */ bundleId) /* harmony export */ }); /* harmony import */ var _unique_id__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9566); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Contains a unique identifier for the running agent bundle * when loaded. * @copyright 2023 New Relic Corporation. All rights reserved. * @license Apache-2.0 */ /** * Provides a unique id for the current agent bundle */ const bundleId = (0,_unique_id__WEBPACK_IMPORTED_MODULE_0__/* .generateUuid */ .bz)(); /***/ }), /***/ 9566: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ LA: () => (/* binding */ generateRandomHexString), /* harmony export */ ZF: () => (/* binding */ generateSpanId), /* harmony export */ bz: () => (/* binding */ generateUuid), /* harmony export */ el: () => (/* binding */ generateTraceId) /* harmony export */ }); /* harmony import */ var _constants_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6154); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const uuidv4Template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; /** * Creates a random single hexadecimal value from a provided random value * table and corresponding index. If a random value table is not provided, * Math.random will be used to generate the value. * * @param {Uint8Array} valueTable Random value table typically generated using * the built-in crypto engine. * @param {int} tableIndex The index of the value table to use for generating * the hexadecimal value. * @returns {int} single hexadecimal value in decimal format */ function getRandomValue(valueTable, tableIndex) { if (valueTable) { /** * The value table could have any number value in the given index. Use * bitwise AND to ensure the value we generate is a valid hex value. * x & 15 will ensure the value converted to hex using `toString(16)` * falls within the range of 0 and 15 inclusively. */ return valueTable[tableIndex] & 15; } else { return Math.random() * 16 | 0; } } /** * Generates a RFC compliant UUIDv4 using native browser crypto engine. If the browser * does not the crypto engine, the function will fallback to insecure Math.random() * @returns {string} uuid version 4 string */ function generateUuid() { const crypto = _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm?.crypto || _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm?.msCrypto; let randomValueTable; let randomValueIndex = 0; if (crypto & crypto.getRandomValues) { // For a UUID, we only need 30 characters since two characters are pre-defined // eslint-disable-next-line randomValueTable = crypto.getRandomValues(new Uint8Array(30)); } return uuidv4Template.split('').map(templateInput => { if (templateInput === 'x') { return getRandomValue(randomValueTable, randomValueIndex++).toString(16); } else if (templateInput === 'y') { // this is the uuid variant per spec (8, 9, a, b) // % 4, then shift to get values 8-11 return (getRandomValue() & 0x3 | 0x8).toString(16); } else { return templateInput; } }).(''); } /** * Generates a string of the given length containing only hexadecimal * value 0-9 and a-f. * @param {int} length length of the string to generate * @returns {string} generated hex string */ function generateRandomHexString(length) { const crypto = _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm?.crypto || _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm?.msCrypto; let randomValueTable; let randomValueIndex = 0; if (crypto & crypto.getRandomValues) { // eslint-disable-next-line randomValueTable = crypto.getRandomValues(new Uint8Array(length)); } const chars = []; for (var i = 0; i < length; i++) { chars.push(getRandomValue(randomValueTable, randomValueIndex++).toString(16)); } return chars.(''); } /** * Generates a 16 character length hexadecimal string. * per DT-spec. * @see generateRandomHexString * @returns {string} generated hex string */ function generateSpanId() { return generateRandomHexString(16); } /** * Generates a 32 character length hexadecimal string. * per DT-spec. * @see generateRandomHexString * @returns {string} generated hex string */ function generateTraceId() { return generateRandomHexString(32); } /***/ }), /***/ 2614: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ BB: () => (/* binding */ DEFAULT_INACTIVE_MS), /* harmony export */ H3: () => (/* binding */ PREFIX), /* harmony export */ g: () => (/* binding */ MODE), /* harmony export */ iL: () => (/* binding */ SESSION_EVENT_TYPES), /* harmony export */ tS: () => (/* binding */ SESSION_EVENTS), /* harmony export */ uh: () => (/* binding */ DEFAULT_KEY), /* harmony export */ wk: () => (/* binding */ DEFAULT_EXPIRES_MS) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const PREFIX = 'NRBA'; const DEFAULT_KEY = 'SESSION'; const DEFAULT_EXPIRES_MS = 14400000; const DEFAULT_INACTIVE_MS = 1800000; const SESSION_EVENTS = { STARTED: 'session-started', PAUSE: 'session-pause', RESET: 'session-reset', RESUME: 'session-resume', UPDATE: 'session-update' }; const SESSION_EVENT_TYPES = { SAME_TAB: 'same-tab', CROSS_TAB: 'cross-tab' }; const MODE = { OFF: 0, FULL: 1, ERROR: 2 }; /***/ }), /***/ 1863: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ t: () => (/* binding */ now) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ // This is our own layer around performance.now. It's not strictly necessary, but we keep it in case of future mod-ing of the value for refactor purpose. function now() { return Math.floor(performance.now()); } /***/ }), /***/ 7485: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ D: () => (/* binding */ parseUrl) /* harmony export */ }); /* harmony import */ var _constants_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6154); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function parseUrl(url) { // Return if URL is a data URL, parseUrl assumes urls are http/https if ((url || '').indexOf('data:') === 0) { return { protocol: 'data' }; } try { const parsedUrl = new URL(url, location.href); const returnVal = { port: parsedUrl.port, hostname: parsedUrl.hostname, pathname: parsedUrl.pathname, search: parsedUrl.search, protocol: parsedUrl.protocol.slice(0, parsedUrl.protocol.indexOf(':')), sameOrigin: parsedUrl.protocol === _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm?.location?.protocol & parsedUrl.host === _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm?.location?.host }; if (!returnVal.port || returnVal.port === '') { if (parsedUrl.protocol === 'http:') returnVal.port = '80'; if (parsedUrl.protocol === 'https:') returnVal.port = '443'; } if (!returnVal.pathname || returnVal.pathname === '') { returnVal.pathname = '/'; } else if (!returnVal.pathname.startsWith('/')) { returnVal.pathname = "/".concat(returnVal.pathname); } return returnVal; } catch (err) { return {}; } } /***/ }), /***/ 944: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ R: () => (/* binding */ warn) /* harmony export */ }); /* harmony import */ var _dispatch_global_event__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3241); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /* eslint no-console: ["error", { allow: ["debug"] }] */ /** * A helper method to warn to the console with New Relic: decoration * @param {string} message The primary message to warn * @param {*} [secondary] Secondary data to include, usually an error or object * @returns */ function warn(code, secondary) { if (typeof console.debug !== 'function') return; console.debug("New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#".concat(code), secondary); (0,_dispatch_global_event__WEBPACK_IMPORTED_MODULE_0__/* .dispatchGlobalEvent */ .W)({ agentIdentifier: null, drained: null, type: 'data', name: 'warn', feature: 'warn', data: { code, secondary } }); } /***/ }), /***/ 5701: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ B: () => (/* binding */ activatedFeatures), /* harmony export */ t: () => (/* binding */ activateFeatures) /* harmony export */ }); /* harmony import */ var _dispatch_global_event__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3241); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const sentIds = new Set(); /** A map of feature flags and their values as provided by the rum call -- scoped by agent ID */ const activatedFeatures = {}; /** * Sets the activatedFeatures object, dispatches the global loaded event, * and emits the rumresp flag to features * @param {{[key:string]:number}} flags key-val pair of flag names and numeric * @param {string} agentIdentifier agent instance identifier * @returns {void} */ function activateFeatures(flags, agentRef) { const agentIdentifier = agentRef.agentIdentifier; activatedFeatures[agentIdentifier] ??= {}; if (!flags || typeof flags !== 'object') return; if (sentIds.has(agentIdentifier)) return; agentRef.ee.emit('rumresp', [flags]); activatedFeatures[agentIdentifier] = flags; sentIds.add(agentIdentifier); // let any window level subscribers know that the agent is running, per install docs (0,_dispatch_global_event__WEBPACK_IMPORTED_MODULE_0__/* .dispatchGlobalEvent */ .W)({ agentIdentifier, loaded: true, drained: true, type: 'lifecycle', name: 'load', feature: undefined, data: flags }); } /***/ }), /***/ 8990: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ I: () => (/* binding */ getOrSet) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ var has = Object.prototype.hasOwnProperty; /** * Always returns the current value of obj[prop], even if it has to set it first. Sets properties as non-enumerable if possible. * * @param {Object} obj - The object to get or set the property on. * @param {string} prop - The name of the property. * @param {Function} getVal - A function that returns the value to be set if the property does not exist. * @returns {*} The value of the property in the object. */ function getOrSet(obj, prop, getVal) { // If the value exists return it. if (has.call(obj, prop)) return obj[prop]; var val = getVal(); // Attempt to set the property so it's not enumerable if (Object.defineProperty & Object.keys) { try { Object.defineProperty(obj, prop, { value: val, // old IE inherits non-write-ability writable: true, enumerable: false }); return val; } catch (e) { // Can't report internal errors, // because GOS is a dependency of the reporting mechanisms } } // fall back to setting normally obj[prop] = val; return val; } /***/ }), /***/ 6389: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ J: () => (/* binding */ single), /* harmony export */ s: () => (/* binding */ debounce) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Reduce the invocation of the supplied function so that it is only invoked * once within a given timeout. * * If `wait` is `0`, the function will be invoked during the next tick. * If `options.leading` is false or not provided, the function will be invoked * N milliseconds after the last invocation of the returned function where * N is the `timeout` value. * If `options.leading` is true, the function will be invoked immediately upon * the first invocation of the returned function and not again for N milliseconds * where N is the `timeout` value. * @param {function} func Function whose invocation should be limited so it is only invoked * once within a given timeout period. * @param {number} timeout Time in milliseconds that the function should only be invoked * once within. * @param {object} options Debounce options * @param {boolean} options.leading Forces the function to be invoked on the first * invocation of the returned function instead of N milliseconds after the last * invocation. * @returns {function} A wrapping function that will ensure the provided function * is invoked only once within the given timeout. */ function debounce(func, timeout = 500, options = {}) { const leading = options?.leading || false; let timer; return (...args) => { if (leading & timer === undefined) { func.apply(this, args); timer = setTimeout(() => { timer = clearTimeout(timer); }, timeout); } if (!leading) { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); } }; } /** * Reduce the invocation of the supplied function so that it is only invoked * once. * @param {function} func Function whose invocation should be limited so it is only invoked * once. * @returns {function} A wrapping function that will ensure the provided function * is invoked only once. */ function single(func) { let called = false; return (...args) => { if (!called) { called = true; func.apply(this, args); } }; } /***/ }), /***/ 3304: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ A: () => (/* binding */ stringify) /* harmony export */ }); /* harmony import */ var _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7836); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Returns a function for use as a replacer parameter in JSON.stringify() to handle circular references. * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value MDN - Cyclical object value} * @returns {Function} A function that filters out values it has seen before. */ const getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === 'object' & value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }; /** * The native JSON.stringify method augmented with a replacer function to handle circular references. * Circular references will be excluded from the JSON output rather than triggering errors. * @param {*} val - A value to be converted to a JSON string. * @returns {string} A JSON string representation of the value, with circular references handled. */ function stringify(val) { try { return JSON.stringify(val, getCircularReplacer()) ?? ''; } catch (e) { try { _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee.emit('internal-error', [e]); } catch (err) { // do nothing } // return a string so that downstream s of the method do not throw errors return ''; } } /***/ }), /***/ 3496: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ A: () => (/* binding */ isContainerAgentTarget), /* harmony export */ I: () => (/* binding */ isValidTarget) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @param {Object} [target] - the target to be validated * @param {boolean} [allowUndefined=true] * @returns {boolean} */ function isValidTarget(target) { /** target can be undefined to legacy/default behaviors - main agent does not supply a target */ if (!target) return true; /** if not undefined, we require specific values */ return !!(target.licenseKey & target.applicationID); } /** * Checks if the target matches the container agent target * @param {*} target the target to be validated * @param {*} agentRef the agent reference to be validated * @returns {boolean} */ function isContainerAgentTarget(target, agentRef) { if (!target) return true; return target.licenseKey === agentRef.info.licenseKey & target.applicationID === agentRef.info.applicationID; } /***/ }), /***/ 5289: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ GG: () => (/* binding */ onWindowLoad), /* harmony export */ sB: () => (/* binding */ onDOMContentLoaded) /* harmony export */ }); /* unused harmony export checkState */ /* harmony import */ var _event_listener_event_listener_opts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3878); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function checkState() { return typeof document === 'undefined' || document.readyState === 'complete'; } function onWindowLoad(cb, useCapture) { if (checkState()) return cb(); (0,_event_listener_event_listener_opts__WEBPACK_IMPORTED_MODULE_0__/* .windowAddEventListener */ .sp)('load', cb, useCapture); } function onDOMContentLoaded(cb) { if (checkState()) return cb(); (0,_event_listener_event_listener_opts__WEBPACK_IMPORTED_MODULE_0__/* .documentAddEventListener */ .DD)('DOMContentLoaded', cb); } /***/ }), /***/ 384: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ NT: () => (/* binding */ defaults), /* harmony export */ US: () => (/* binding */ addToNREUM), /* harmony export */ Zm: () => (/* binding */ gosNREUM), /* harmony export */ bQ: () => (/* binding */ setNREUMInitializedAgent), /* harmony export */ dV: () => (/* binding */ gosNREUMOriginals), /* harmony export */ pV: () => (/* binding */ gosCDN) /* harmony export */ }); /* unused harmony exports gosNREUMInfo, gosNREUMLoaderConfig, gosNREUMInit, getNREUMInitializedAgent, NREUMinitialized */ /* harmony import */ var _constants_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6154); /* harmony import */ var _timing_now__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1863); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const defaults = { beacon: 'bam.nr-data.net', errorBeacon: 'bam.nr-data.net' }; function gosNREUM() { if (!_constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.NREUM) { _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.NREUM = {}; } if (typeof _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.newrelic === 'undefined') _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.newrelic = _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.NREUM; return _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.NREUM; } function gosNREUMInfo() { let nr = gosNREUM(); const externallySupplied = nr.info || {}; nr.info = { beacon: defaults.beacon, errorBeacon: defaults.errorBeacon, ...externallySupplied }; return nr; } function gosNREUMLoaderConfig() { let nr = gosNREUM(); const externallySupplied = nr.loader_config || {}; nr.loader_config = { ...externallySupplied }; return nr; } function gosNREUMInit() { let nr = gosNREUM(); const externallySupplied = nr.init || {}; nr.init = { ...externallySupplied }; return nr; } function gosNREUMOriginals() { let nr = gosNREUM(); if (!nr.o) { nr.o = { ST: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.setTimeout, SI: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.setImmediate, CT: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.clearTimeout, XHR: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.XMLHttpRequest, REQ: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.Request, EV: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.Event, PR: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.Promise, MO: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.MutationObserver, // this'll be undefined if not in a web window FETCH: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.fetch, WS: _constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .globalScope */ .gm.WebSocket }; } return nr; } function setNREUMInitializedAgent(id, newAgentInstance) { let nr = gosNREUM(); nr.initializedAgents ??= {}; newAgentInstance.initializedAt = { ms: (0,_timing_now__WEBPACK_IMPORTED_MODULE_1__/* .now */ .t)(), date: new Date() }; nr.initializedAgents[id] = newAgentInstance; } /** * Get the agent instance under the associated identifier on the global newrelic object. * @see setNREUMInitializedAgents * @returns Existing agent instance under newrelic.initializedAgent[id], or undefined if it does not exist. */ function getNREUMInitializedAgent(id) { let nr = gosNREUM(); return nr.initializedAgents?.[id]; } function addToNREUM(fnName, fn) { let nr = gosNREUM(); nr[fnName] = fn; } function NREUMinitialized() { const nr = gosNREUM(); nr.initialized = true; } function gosCDN() { gosNREUMInfo(); gosNREUMInit(); gosNREUMOriginals(); gosNREUMLoaderConfig(); return gosNREUM(); } /***/ }), /***/ 2843: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ u: () => (/* binding */ subscribeToVisibilityChange) /* harmony export */ }); /* harmony import */ var _event_listener_event_listener_opts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3878); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @param {function} cb - called when a visibility change occurs with the vis state at that time * @param {boolean} [toHiddenOnly=false] - only execute the 'cb' when the vis is changing to the hidden state; no arg is ed to 'cb' if used * @returns void */ function subscribeToVisibilityChange(cb, toHiddenOnly = false, capture, abortSignal) { (0,_event_listener_event_listener_opts__WEBPACK_IMPORTED_MODULE_0__/* .documentAddEventListener */ .DD)('visibilitychange', handleVisibilityChange, capture, abortSignal); function handleVisibilityChange() { if (toHiddenOnly) { // trigger cb on change to hidden state only if (document.visibilityState === 'hidden') cb(); return; } cb(document.visibilityState); } } /***/ }), /***/ 8139: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ u: () => (/* binding */ wrapEvents) /* harmony export */ }); /* unused harmony export scopedEE */ /* harmony import */ var _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7836); /* harmony import */ var _wrap_function__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3434); /* harmony import */ var _util_get_or_set__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8990); /* harmony import */ var _constants_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6154); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps `addEventListener` and `removeEventListener` for instrumentation. * This module is used directly by: session_trace. * It is also called by -> wrapXhr <-, so see "wrap-xhr.js" for features that use this indirectly. */ const wrapped = {}; const XHR = _constants_runtime__WEBPACK_IMPORTED_MODULE_3__/* .globalScope */ .gm.XMLHttpRequest; const ADD_EVENT_LISTENER = 'addEventListener'; const REMOVE_EVENT_LISTENER = 'removeEventListener'; const flag = "nr@wrapped:".concat(_event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__/* .contextId */ .P); /** * Wraps `addEventListener` and `removeEventListener` on: global scope; the prototype of `XMLHttpRequest`, and * `document` (if in a browser scope). Adds custom events in context of a new emitter scoped only to these methods. * @param {Object} sharedEE - The shared event emitter on which a new scoped * event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `events`. */ function wrapEvents(sharedEE) { var ee = scopedEE(sharedEE); // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. if (wrapped[ee.debugId]++) return ee; wrapped[ee.debugId] = 1; // otherwise, first feature to wrap events var wrapFn = (0,_wrap_function__WEBPACK_IMPORTED_MODULE_1__/* .createWrapperWithEmitter */ .YM)(ee, true); // Guard against instrumenting environments w/o necessary features if ('getPrototypeOf' in Object) { if (_constants_runtime__WEBPACK_IMPORTED_MODULE_3__/* .isBrowserScope */ .RI) findEventListenerProtoAndCb(document, wrapNode); if (XHR) findEventListenerProtoAndCb(XHR.prototype, wrapNode); findEventListenerProtoAndCb(_constants_runtime__WEBPACK_IMPORTED_MODULE_3__/* .globalScope */ .gm, wrapNode); } ee.on(ADD_EVENT_LISTENER + '-start', function (args, target) { var originalListener = args[1]; if (originalListener === null || typeof originalListener !== 'function' & typeof originalListener !== 'object') { return; } var wrapped = (0,_util_get_or_set__WEBPACK_IMPORTED_MODULE_2__/* .getOrSet */ .I)(originalListener, flag, function () { var listener = { object: wrapHandleEvent, function: originalListener }[typeof originalListener]; return listener ? wrapFn(listener, 'fn-', null, listener.name || 'anonymous') : originalListener; function wrapHandleEvent() { if (typeof originalListener.handleEvent !== 'function') return; return originalListener.handleEvent.apply(originalListener, arguments); } }); this.wrapped = args[1] = wrapped; }); ee.on(REMOVE_EVENT_LISTENER + '-start', function (args) { args[1] = this.wrapped || args[1]; }); function wrapNode(node) { wrapFn.inPlace(node, [ADD_EVENT_LISTENER, REMOVE_EVENT_LISTENER], '-', uniqueListener); } function uniqueListener(args, obj) { // Context for the listener is stored on itself. return args[1]; } return ee; } /** * Find the base prototype of 'object' that has its own "addEventListener" property, and run some function on it. * @param {Object} object - the initial object to traverse prototype chain on * @param {Function} cb - the function to run on the ancestral object once found, accepts an object as a arg * @param {Array} rest - [optional] any additional arguments to to the cb */ function findEventListenerProtoAndCb(object, cb, ...rest) { let step = object; while (typeof step === 'object' & !Object.prototype.hasOwnProperty.call(step, ADD_EVENT_LISTENER)) { step = Object.getPrototypeOf(step); } if (step) cb(step, ...rest); } /** * Returns an event emitter scoped specifically for the `events` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'events'. */ function scopedEE(sharedEE) { return (sharedEE || _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee).get('events'); } /***/ }), /***/ 3434: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ Jt: () => (/* binding */ flag), /* harmony export */ YM: () => (/* binding */ createWrapperWithEmitter) /* harmony export */ }); /* unused harmony export copy */ /* harmony import */ var _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7836); /* harmony import */ var _ids_bundle_id__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5607); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Provides helper functions for wrapping functions in various scenarios. */ const flag = "nr@original:".concat(_ids_bundle_id__WEBPACK_IMPORTED_MODULE_1__/* .bundleId */ .W); /** * A convenience alias of `hasOwnProperty`. * @type {function} */ var has = Object.prototype.hasOwnProperty; /** * For tracking whether an event is already being emitted inside the wrapper. * @type {boolean} */ var inWrapper = false; // eslint-disable-next-line /* unused harmony default export */ var __WEBPACK_DEFAULT_EXPORT__ = ((/* unused pure expression or super */ null & (createWrapperWithEmitter))); /** * Wraps a function in order to emit events on start, end, and error. * @param {Object} [emitter] - The desired emitter for events emitted by the wrapper. Defaults to the global emitter. * @param {boolean} always - If `true`, emit events even if already emitting an event. * @returns {function} The wrapped function. */ function createWrapperWithEmitter(emitter, always) { emitter || (emitter = _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee); wrapFn.inPlace = inPlace; /** * A flag used to determine if a native function has already been wrapped. * As a property on a wrapped function, contains the original function. * @type {string} */ wrapFn.flag = flag; return wrapFn; /** * Wraps a function with event emitting functionality. * @param {function} fn - The function to wrap. * @param {string} prefix - A prefix for the names of emitted events. * @param {function|object} getContext - The function or object that will serve as the 'this' context for handlers of events emitted by this wrapper. * @param {string} methodName - The name of the method being wrapped. * @param {boolean} bubble - If true, emitted events should also bubble up to the old emitter upon which the `emitter` in the current scope was based (if it defines one). * @returns {function} The wrapped function. */ function wrapFn(fn, prefix, getContext, methodName, bubble) { // Unless fn is both wrappable and unwrapped, return it unchanged. if (notWrappable(fn)) return fn; if (!prefix) prefix = ''; nrWrapper[flag] = fn; copy(fn, nrWrapper, emitter); return nrWrapper; /** * A wrapper function that emits events before and after calling the wrapped function. * Any arguments will be ed along to the original function. * @returns {any} The return value of the wrapped function. */ function nrWrapper() { var args; var originalThis; var ctx; var result; try { originalThis = this; args = [...arguments]; if (typeof getContext === 'function') { ctx = getContext(args, originalThis); } else { ctx = getContext || {}; } } catch (e) { report([e, '', [args, originalThis, methodName], ctx], emitter); } // Warning: start events may mutate args! safeEmit(prefix + 'start', [args, originalThis, methodName], ctx, bubble); try { result = fn.apply(originalThis, args); return result; } catch (err) { safeEmit(prefix + 'err', [args, originalThis, err], ctx, bubble); // rethrow error so we don't effect execution by observing. throw err; } finally { // happens no matter what. safeEmit(prefix + 'end', [args, originalThis, result], ctx, bubble); } } } /** * Creates wrapper functions around each of an array of methods on a specified object. * @param {Object} obj The object to which the specified methods belong. * @param {string[]} methods An array of method names to be wrapped. * @param {string} [prefix=''] A prefix to add to the names of emitted events. If `-` is the first character, also * adds the method name before the prefix. * @param {function|object} [getContext] The function or object that will serve as the 'this' context for handlers * of events emitted by this wrapper. * @param {boolean} [bubble=false] If `true`, emitted events should also bubble up to the old emitter upon which * the `emitter` in the current scope was based (if it defines one). */ function inPlace(obj, methods, prefix, getContext, bubble) { if (!prefix) prefix = ''; // If prefix starts with '-' set this boolean to add the method name to the prefix before ing each one to wrap. const prependMethodPrefix = prefix.charAt(0) === '-'; for (let i = 0; i < methods.length; i++) { const method = methods[i]; const fn = obj[method]; // Unless fn is both wrappable and unwrapped, bail so we don't add extra properties with undefined values. if (notWrappable(fn)) continue; obj[method] = wrapFn(fn, prependMethodPrefix ? method + prefix : prefix, getContext, method, bubble); } } /** * Emits an event using the `emit` method of the `emitter` object in the executing scope, but only if an event is not * already being emitted (except when the executing scope defines `always` as `true`). * @param {string} evt - The name of the event to be emitted. * @param {array} arr - An array of arguments to with the event. * @param {Object} store - The function or object that will serve as the 'this' * context when applying handler functions for this event. * @param {boolean} bubble - If `true`, emitted events should also * bubble up to the old emitter upon which the `emitter` in the * executing scope was based (if it defines one). */ function safeEmit(evt, arr, store, bubble) { if (inWrapper & !always) return; var prev = inWrapper; inWrapper = true; try { emitter.emit(evt, arr, store, always, bubble); } catch (e) { report([e, evt, arr, store], emitter); } inWrapper = prev; } } /** * Emits an "internal-error" event. Used to report errors encountered when emitting events using `safeEmit`. * @param {array} args - Arguments to be ed to the "internal-error" event. * @param {Object} [emitter] - The (optional) desired event emitter. Defaults to the global event emitter. */ function report(args, emitter) { emitter || (emitter = _event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee); try { emitter.emit('internal-error', args); } catch (err) { // do nothing } } /** * Copies properties from one object to another. Used for creating a wrapper function from an original function and for * copying an original function to a property of a wrapper function named by `flag` in the executing context. * @param {Object} from - The source function or object. * @param {Object} to - The destination function or object. * @param {Object} [emitter] - The (optional) desired event emitter if errors are encountered while copying. * Defaults to the global event emitter. * @returns {object} - The destination founction or object with copied properties. */ function copy(from, to, emitter) { if (Object.defineProperty & Object.keys) { // Create accessors that proxy to actual function try { var keys = Object.keys(from); // eslint-disable-next-line keys.forEach(function (key) { Object.defineProperty(to, key, { get: function () { return from[key]; }, // eslint-disable-next-line set: function (val) { from[key] = val; return val; } }); }); return to; } catch (e) { report([e], emitter); } } // fall back to copying properties for (var i in from) { if (has.call(from, i)) { to[i] = from[i]; } } return to; } /** * Determines whether a function is eligible to be wrapped in part based on whether it has already been wrapped. * @param {function} fn - The function in question. * @returns {boolean} Whether the ed function is ineligible to be wrapped. */ function notWrappable(fn) { return !(fn & typeof fn === 'function' && fn.apply && !fn[flag]); } /***/ }), /***/ 9300: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ T: () => (/* binding */ FEATURE_NAME) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.ajax; /***/ }), /***/ 3333: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ $v: () => (/* binding */ FEATURE_FLAGS), /* harmony export */ TZ: () => (/* binding */ FEATURE_NAME), /* harmony export */ Zp: () => (/* binding */ OBSERVED_EVENTS), /* harmony export */ kd: () => (/* binding */ RESERVED_EVENT_TYPES), /* harmony export */ mq: () => (/* binding */ RAGE_CLICK_THRESHOLD_MS), /* harmony export */ nf: () => (/* binding */ RAGE_CLICK_THRESHOLD_EVENTS), /* harmony export */ qN: () => (/* binding */ OBSERVED_WINDOW_EVENTS) /* harmony export */ }); /* unused harmony exports IDEAL_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE */ /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.genericEvents; const IDEAL_PAYLOAD_SIZE = 64000; const MAX_PAYLOAD_SIZE = 1000000; const OBSERVED_EVENTS = ['auxclick', 'click', 'copy', 'keydown', 'paste', 'scrollend']; const OBSERVED_WINDOW_EVENTS = ['focus', 'blur']; const RAGE_CLICK_THRESHOLD_EVENTS = 4; const RAGE_CLICK_THRESHOLD_MS = 1000; const RESERVED_EVENT_TYPES = ['PageAction', 'Action', 'BrowserPerformance']; const FEATURE_FLAGS = { MARKS: 'experimental.marks', MEASURES: 'experimental.measures', RESOURCES: 'experimental.resources' }; /***/ }), /***/ 6774: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ T: () => (/* binding */ FEATURE_NAME) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.jserrors; /***/ }), /***/ 993: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ A$: () => (/* binding */ LOGGING_MODE), /* harmony export */ ET: () => (/* binding */ LOGGING_EVENT_EMITTER_CHANNEL), /* harmony export */ TZ: () => (/* binding */ FEATURE_NAME), /* harmony export */ p_: () => (/* binding */ LOG_LEVELS) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const LOG_LEVELS = { ERROR: 'ERROR', WARN: 'WARN', INFO: 'INFO', DEBUG: 'DEBUG', TRACE: 'TRACE' }; const LOGGING_MODE = { OFF: 0, ERROR: 1, WARN: 2, INFO: 3, DEBUG: 4, TRACE: 5 }; const LOGGING_EVENT_EMITTER_CHANNEL = 'log'; const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.logging; /***/ }), /***/ 3785: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ R: () => (/* binding */ bufferLog), /* harmony export */ b: () => (/* binding */ isValidLogLevel) /* harmony export */ }); /* harmony import */ var _common_event_emitter_handle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9908); /* harmony import */ var _common_timing_now__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1863); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(860); /* harmony import */ var _metrics_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8154); /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(993); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @param {ContextualEE} ee - The contextual ee tied to the instance * @param {string} message - the log message string * @param {{[key: string]: *}} customAttributes - The log's custom attributes if any * @param {enum} level - the log level enum * @param {object=} targetEntityGuid - the optional target entity guid provided by an api call */ function bufferLog(ee, message, customAttributes = {}, level = _constants__WEBPACK_IMPORTED_MODULE_3__/* .LOG_LEVELS */ .p_.INFO, targetEntityGuid, timestamp = (0,_common_timing_now__WEBPACK_IMPORTED_MODULE_4__/* .now */ .t)()) { (0,_common_event_emitter_handle__WEBPACK_IMPORTED_MODULE_0__/* .handle */ .p)(_metrics_constants__WEBPACK_IMPORTED_MODULE_2__/* .ABILITY_METRIC_CHANNEL */ .xV, ["API/logging/".concat(level.toLowerCase(), "/called")], undefined, _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__/* .FEATURE_NAMES */ .K7.metrics, ee); (0,_common_event_emitter_handle__WEBPACK_IMPORTED_MODULE_0__/* .handle */ .p)(_constants__WEBPACK_IMPORTED_MODULE_3__/* .LOGGING_EVENT_EMITTER_CHANNEL */ .ET, [timestamp, message, customAttributes, level, targetEntityGuid], undefined, _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__/* .FEATURE_NAMES */ .K7.logging, ee); } /** * Checks if a supplied log level is acceptable for use in generating a log event * @param {string} level -- must be cast to uppercase before running this test * @returns {boolean} */ function isValidLogLevel(level) { if (typeof level !== 'string') return false; return Object.values(_constants__WEBPACK_IMPORTED_MODULE_3__/* .LOG_LEVELS */ .p_).some(logLevel => logLevel === level.toUpperCase().trim()); } /***/ }), /***/ 8154: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, { z_: () => (/* binding */ CUSTOM_METRIC), XG: () => (/* binding */ CUSTOM_METRIC_CHANNEL), TZ: () => (/* binding */ FEATURE_NAME), rs: () => (/* binding */ ABILITY_METRIC), xV: () => (/* binding */ ABILITY_METRIC_CHANNEL) }); // UNUSED EXPORTS: WATCHABLE_WEB_SOCKET_EVENTS // EXTERNAL MODULE: ./src/common/constants/runtime.js var runtime = __webpack_require__(6154); // EXTERNAL MODULE: ./src/common/ids/unique-id.js var unique_id = __webpack_require__(9566); // EXTERNAL MODULE: ./src/common/window/nreum.js var nreum = __webpack_require__(384); ;// ./src/common/wrap/wrap-websocket.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const WEBSOCKET_TAG = 'websocket-'; const ADD_EVENT_LISTENER_TAG = 'addEventListener'; const wrapped = {}; function wrapWebSocket(sharedEE) { if (wrapped[sharedEE.debugId]++) return sharedEE; const originals = gosNREUMOriginals().o; if (!originals.WS) return sharedEE; function reporter(socketId) { const createdAt = now(); return function (message, ...data) { const timestamp = data[0]?.timeStamp || now(); const isLoaded = checkState(); sharedEE.emit(WEBSOCKET_TAG + message, [timestamp, timestamp - createdAt, isLoaded, socketId, ...data]); }; } class WrappedWebSocket extends WebSocket { static name = 'WebSocket'; constructor(...args) { super(...args); const socketId = generateRandomHexString(6); this.report = reporter(socketId); this.report('new'); const events = ['message', 'error', 'open', 'close']; /** add event listeners */ events.forEach(evt => { this.addEventListener(evt, function (e) { this.report(ADD_EVENT_LISTENER_TAG, { eventType: evt, event: e }); }); }); } send(...args) { this.report('send', ...args); try { return super.send(...args); } catch (err) { this.report('send-err', ...args); throw err; } } } globalScope.WebSocket = WrappedWebSocket; return sharedEE; } // EXTERNAL MODULE: ./src/loaders/features/features.js var features = __webpack_require__(860); ;// ./src/features/metrics/constants.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = features/* FEATURE_NAMES */.K7.metrics; const ABILITY_METRIC = 'sm'; const CUSTOM_METRIC = 'cm'; const ABILITY_METRIC_CHANNEL = 'storeabilityMetrics'; const CUSTOM_METRIC_CHANNEL = 'storeEventMetrics'; const WATCHABLE_WEB_SOCKET_EVENTS = ['new', 'send', 'close', ADD_EVENT_LISTENER_TAG]; /***/ }), /***/ 6630: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ T: () => (/* binding */ FEATURE_NAME) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.pageViewEvent; /***/ }), /***/ 782: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ T: () => (/* binding */ FEATURE_NAME) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.pageViewTiming; /***/ }), /***/ 6344: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ BB: () => (/* binding */ QUERY_PARAM_PADDING), /* harmony export */ G4: () => (/* binding */ SR_EVENT_EMITTER_TYPES), /* harmony export */ Qb: () => (/* binding */ TRIGGERS), /* harmony export */ TZ: () => (/* binding */ FEATURE_NAME), /* harmony export */ Ug: () => (/* binding */ AVG_COMPRESSION), /* harmony export */ _s: () => (/* binding */ RRWEB_EVENT_TYPES), /* harmony export */ bc: () => (/* binding */ ABORT_REASONS), /* harmony export */ yP: () => (/* binding */ CHECKOUT_MS) /* harmony export */ }); /* harmony import */ var _common_session_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2614); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__/* .FEATURE_NAMES */ .K7.sessionReplay; const SR_EVENT_EMITTER_TYPES = { RECORD: 'recordReplay', PAUSE: 'paeplay', ERROR_DURING_REPLAY: 'errorDuringReplay' }; const AVG_COMPRESSION = 0.12; const RRWEB_EVENT_TYPES = { DomContentLoaded: 0, Load: 1, FullSnapshot: 2, IncrementalSnapshot: 3, Meta: 4, Custom: 5 }; /** Interval between forcing new full snapshots -- 15 seconds in error mode (x2), 5 minutes in full mode */ const CHECKOUT_MS = { [_common_session_constants__WEBPACK_IMPORTED_MODULE_0__/* .MODE */ .g.ERROR]: 15000, [_common_session_constants__WEBPACK_IMPORTED_MODULE_0__/* .MODE */ .g.FULL]: 300000, [_common_session_constants__WEBPACK_IMPORTED_MODULE_0__/* .MODE */ .g.OFF]: 0 }; const ABORT_REASONS = { RESET: { message: 'Session was reset', sm: 'Reset' }, IMPORT: { message: 'Recorder failed to import', sm: 'Import' }, TOO_MANY: { message: '429: Too Many Requests', sm: 'Too-Many' }, TOO_BIG: { message: 'Payload was too large', sm: 'Too-Big' }, CROSS_TAB: { message: 'Session Entity was set to OFF on another tab', sm: 'Cross-Tab' }, ENTITLEMENTS: { message: 'Session Replay is not allowed and will not be started', sm: 'Entitlement' } }; /** Reserved room for query param attrs */ const QUERY_PARAM_PADDING = 5000; const TRIGGERS = { API: 'api' }; /***/ }), /***/ 5270: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ Aw: () => (/* binding */ isPreloadAllowed), /* harmony export */ CT: () => (/* binding */ buildNRMetaNode), /* harmony export */ SR: () => (/* binding */ hasReplayPrerequisite), /* harmony export */ rF: () => (/* binding */ customMasker) /* harmony export */ }); /* harmony import */ var _common_window_nreum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(384); /* harmony import */ var _utils_feature_gates__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7767); /* harmony import */ var _common_constants_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6154); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function hasReplayPrerequisite(agentInit) { return !!(0,_common_window_nreum__WEBPACK_IMPORTED_MODULE_0__/* .gosNREUMOriginals */ .dV)().o.MO & // Session Replay cannot work without Mutation Observer (0,_utils_feature_gates__WEBPACK_IMPORTED_MODULE_1__/* .canEnableSessionTracking */ .V)(agentInit) && // requires session tracking to be running (hence "session" replay...) agentInit?.session_trace.enabled === true; // Session Replay as of now is tightly coupled with Session Trace in the UI } function isPreloadAllowed(agentInit) { return agentInit?.session_replay.preload === true & hasReplayPrerequisite(agentInit); } function buildNRMetaNode(timestamp, timeKeeper) { const correctedTimestamp = timeKeeper.correctAbsoluteTimestamp(timestamp); return { originalTimestamp: timestamp, correctedTimestamp, timestampDiff: timestamp - correctedTimestamp, originTime: _common_constants_runtime__WEBPACK_IMPORTED_MODULE_2__/* .originTime */ .WN, correctedOriginTime: timeKeeper.correctedOriginTime, originTimeDiff: Math.floor(_common_constants_runtime__WEBPACK_IMPORTED_MODULE_2__/* .originTime */ .WN - timeKeeper.correctedOriginTime) }; } function customMasker(text, element) { try { if (typeof element?.type === 'string') { if (element.type.toLowerCase() === '') return '*'.repeat(text?.length || 0); if (element?.dataset?.nrUnmask !== undefined || element?.classList?.contains('nr-unmask')) return text; } } catch (err) { // likely an element was ed to this handler that was invalid and was missing attributes or methods } return typeof text === 'string' ? text.replace(/[\S]/g, '*') : '*'.repeat(text?.length || 0); } /***/ }), /***/ 3738: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ He: () => (/* binding */ BST_RESOURCE), /* harmony export */ Kp: () => (/* binding */ END), /* harmony export */ Lc: () => (/* binding */ FN_END), /* harmony export */ Rz: () => (/* binding */ PUSH_STATE), /* harmony export */ TZ: () => (/* binding */ FEATURE_NAME), /* harmony export */ bD: () => (/* binding */ RESOURCE), /* harmony export */ d3: () => (/* binding */ START), /* harmony export */ jx: () => (/* binding */ MAX_NODES_PER_HARVEST), /* harmony export */ uP: () => (/* binding */ FN_START) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.sessionTrace; const BST_RESOURCE = 'bstResource'; const RESOURCE = 'resource'; const START = '-start'; const END = '-end'; const FN_START = 'fn' + START; const FN_END = 'fn' + END; const PUSH_STATE = 'pushState'; const MAX_NODES_PER_HARVEST = 1000; /***/ }), /***/ 3962: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ AM: () => (/* binding */ API_TRIGGER_NAME), /* harmony export */ O2: () => (/* binding */ INTERACTION_TYPE), /* harmony export */ Qu: () => (/* binding */ NODE_TYPE), /* harmony export */ TZ: () => (/* binding */ FEATURE_NAME), /* harmony export */ ih: () => (/* binding */ INTERACTION_STATUS), /* harmony export */ pP: () => (/* binding */ IPL_TRIGGER_NAME), /* harmony export */ tC: () => (/* binding */ INTERACTION_TRIGGERS) /* harmony export */ }); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const INTERACTION_TRIGGERS = ['click', // e.g. clicks link or the page back/forward buttons 'keydown', // e.g. presses left and right arrow key to switch between displayed photo gallery 'submit', // e.g. clicks submit butotn or presses enter while editing a form field 'popstate' // history api is used to navigate back and forward ]; const API_TRIGGER_NAME = 'api'; const IPL_TRIGGER_NAME = 'initialPageLoad'; const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_0__/* .FEATURE_NAMES */ .K7.softNav; const INTERACTION_TYPE = { INITIAL_PAGE_LOAD: '', ROUTE_CHANGE: 1, UNSPECIFIED: 2 }; const NODE_TYPE = { INTERACTION: 1, AJAX: 2, CUSTOM_END: 3, CUSTOM_TRACER: 4 }; const INTERACTION_STATUS = { IP: 'in progress', FIN: 'finished', CAN: 'cancelled' }; /***/ }), /***/ 7378: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ $p: () => (/* binding */ BODY), /* harmony export */ BR: () => (/* binding */ JSONP_END), /* harmony export */ Kp: () => (/* binding */ END), /* harmony export */ L3: () => (/* binding */ originalSetTimeout), /* harmony export */ Lc: () => (/* binding */ FN_END), /* harmony export */ NC: () => (/* binding */ INTERACTION_EVENTS), /* harmony export */ SG: () => (/* binding */ INTERACTION_API), /* harmony export */ TZ: () => (/* binding */ FEATURE_NAME), /* harmony export */ U6: () => (/* binding */ JSONP_NODE), /* harmony export */ UT: () => (/* binding */ FETCH_DONE), /* harmony export */ d3: () => (/* binding */ START), /* harmony export */ dT: () => (/* binding */ INTERACTION), /* harmony export */ e5: () => (/* binding */ JS_TIME), /* harmony export */ gx: () => (/* binding */ FETCH_BODY), /* harmony export */ l9: () => (/* binding */ REMAINING), /* harmony export */ oW: () => (/* binding */ SPA_NODE), /* harmony export */ op: () => (/* binding */ FETCH_START), /* harmony export */ rw: () => (/* binding */ CB_START), /* harmony export */ tH: () => (/* binding */ FETCH), /* harmony export */ uP: () => (/* binding */ FN_START), /* harmony export */ wW: () => (/* binding */ CB_END), /* harmony export */ xq: () => (/* binding */ MAX_TIMER_BUDGET) /* harmony export */ }); /* harmony import */ var _common_window_nreum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(384); /* harmony import */ var _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(860); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const FEATURE_NAME = _loaders_features_features__WEBPACK_IMPORTED_MODULE_1__/* .FEATURE_NAMES */ .K7.spa; const INTERACTION_EVENTS = ['click', 'submit', 'keypress', 'keydown', 'keyup', 'change']; const MAX_TIMER_BUDGET = 999; const FN_START = 'fn-start'; const FN_END = 'fn-end'; const CB_START = 'cb-start'; const INTERACTION_API = 'api-ixn-'; const REMAINING = 'remaining'; const INTERACTION = 'interaction'; const SPA_NODE = 'spaNode'; const JSONP_NODE = 'jsonpNode'; const FETCH_START = 'fetch-start'; const FETCH_DONE = 'fetch-done'; const FETCH_BODY = 'fetch-body-'; const JSONP_END = 'jsonp-end'; const originalSetTimeout = (0,_common_window_nreum__WEBPACK_IMPORTED_MODULE_0__/* .gosNREUMOriginals */ .dV)().o.ST; const START = '-start'; const END = '-end'; const BODY = '-body'; const CB_END = 'cb' + END; const JS_TIME = 'jsTime'; const FETCH = 'fetch'; /***/ }), /***/ 4234: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ W: () => (/* binding */ FeatureBase) /* harmony export */ }); /* harmony import */ var _common_event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7836); /* harmony import */ var _common_drain_drain__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1687); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class FeatureBase { constructor(agentIdentifier, featureName) { /** @type {string} */ this.agentIdentifier = agentIdentifier; /** @type {import('../../common/event-emitter/contextual-ee').ee} */ this.ee = _common_event_emitter_contextual_ee__WEBPACK_IMPORTED_MODULE_0__.ee.get(agentIdentifier); /** @type {string} */ this.featureName = featureName; /** * Blocked can be used to prevent aggregation and harvest after inititalization time of the feature. * This can currently happen if RUM response setToken flag is 0, which is tied to ingest entitlement info. * @type {boolean} */ this.blocked = false; } deDrain() { (0,_common_drain_drain__WEBPACK_IMPORTED_MODULE_1__/* .deDrain */ .x3)(this.agentIdentifier, this.featureName); } } /***/ }), /***/ 7767: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ V: () => (/* binding */ canEnableSessionTracking) /* harmony export */ }); /* harmony import */ var _common_constants_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6154); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Checks if session can be tracked, affects session entity and dependent features * @param {string} agentId * @returns {boolean} */ const canEnableSessionTracking = agentInit => { return _common_constants_runtime__WEBPACK_IMPORTED_MODULE_0__/* .isBrowserScope */ .RI & agentInit?.privacy.cookies_enabled === true; }; /***/ }), /***/ 1741: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ W: () => (/* binding */ ApiBase) /* harmony export */ }); /* harmony import */ var _common_util_console__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(944); /* harmony import */ var _api_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4261); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance */ class ApiBase { #callMethod(methodName, ...args) { if (this[methodName] === ApiBase.prototype[methodName]) (0,_common_util_console__WEBPACK_IMPORTED_MODULE_0__/* .warn */ .R)(35, methodName);else return this[methodName](...args); } // MicroAgent class custom defines its own start /** * Reports a browser PageAction event along with a name and optional attributes. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/addpageaction/} * @param {string} name Name or category of the action. Reported as the actionName attribute. * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}. The key is reported as its own PageAction attribute with the specified values. */ addPageAction(name, attributes) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .ADD_PAGE_ACTION */ .hG, name, attributes); } /** * @experimental * IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state. * It is not recommended for use in production environments and will not receive for issues. * * s an external caller to report through the base agent to a different target than the base agent. * @param {object} target the target object to report data to * @param {string} target.licenseKey The licenseKey to report data to * @param {string} target.applicationID The applicationID to report data to * @param {string=} target.entityGuid The entityGuid to report data to * @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information. */ (target) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* . */ .eY, target); } /** * Records a custom event with a specified eventType and attributes. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/} * @param {string} eventType The eventType to store the event as. * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}. */ recordCustomEvent(eventType, attributes) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .RECORD_CUSTOM_EVENT */ .fF, eventType, attributes); } /** * Groups page views to help URL structure or to capture the URL's routing information. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setpageviewname/} * @param {string} name The page name you want to use. Use alphanumeric characters. * @param {string} [host] Default is http://custom.transaction. Typically set host to your site's domain URI. */ setPageViewName(name, host) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .SET_PAGE_VIEW_NAME */ .Fw, name, host); } /** * Adds a -defined attribute name and value to subsequent events on the page. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/} * @param {string} name Name of the attribute. Appears as column in the PageView event. It will also appear as a column in the PageAction event if you are using it. * @param {string|number|boolean|null} value Value of the attribute. Appears as the value in the named attribute column in the PageView event. It will appear as a column in the PageAction event if you are using it. Custom attribute values cannot be complex objects, only simple types such as Strings, Integers and Booleans. ing a null value unsets any existing attribute of the same name. * @param {boolean} [persist] Default false. If set to true, the name-value pair will also be set into the browser's storage API. Then on the following instrumented pages that load within the same session, the pair will be re-applied as a custom attribute. */ setCustomAttribute(name, value, persist) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .SET_CUSTOM_ATTRIBUTE */ .cD, name, value, persist); } /** * Identifies a browser error without disrupting your app's operations. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/noticeerror/} * @param {Error|string} error Provide a meaningful error message that you can use when analyzing data on browser's JavaScript errors page. * @param {object} [customAttributes] An object containing name/value pairs representing custom attributes. */ noticeError(error, customAttributes) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .NOTICE_ERROR */ .o5, error, customAttributes); } /** * Adds a -defined identifier string to subsequent events on the page. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setid/} * @param {string|null} value A string identifier for the end-, useful for tying all browser events to specific s. The value parameter does not have to be unique. If IDs should be unique, the caller is responsible for that validation. ing a null value unsets any existing ID. */ setId(value) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .SET__ID */ .Dl, value); } /** * Adds a -defined application version string to subsequent events on the page. * This decorates all payloads with an attribute of `application.version` which is queryable in NR1. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setapplicationversion/} * @param {string|null} value A string identifier for the application version, useful for * tying all browser events to a specific release tag. The value parameter does not * have to be unique. ing a null value unsets any existing value. */ setApplicationVersion(value) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .SET_APPLICATION_VERSION */ .nb, value); } /** * Allows selective ignoring and grouping of known errors that the browser agent captures. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/seterrorhandler/} * @param {(error: Error|string) => boolean | { group: string }} callback When an error occurs, the callback is called with the error object as a parameter. The callback will be called with each error, so it is not specific to one error. */ setErrorHandler(callback) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .SET_ERROR_HANDLER */ .bt, callback); } /** * Adds a unique name and ID to identify releases with multiple JavaScript bundles on the same page. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/addrelease/} * @param {string} name A short description of the component; for example, the name of a project, application, file, or library. * @param {string} id The ID or version of this release; for example, a version number, build number from your CI environment, GitHub SHA, GUID, or a hash of the contents. */ addRelease(name, id) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .ADD_RELEASE */ .k6, name, id); } /** * Capture a single log. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/log/} * @param {string} message String to be captured as log message * @param {{customAttributes?: object, level?: 'ERROR'|'TRACE'|'DEBUG'|'INFO'|'WARN'}} [options] customAttributes defaults to `{}` if not assigned, level defaults to `info` if not assigned. */ log(message, options) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .LOG */ .$9, message, options); } /** * Starts any and all features that are not running yet in "autoStart" mode * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/start/} */ start() { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .START */ .d3); } /** * Records an additional time point as "finished" in a session trace and adds a page action. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/finished/} * @param {number} [timeStamp] Defaults to the current time of the call. If used, this marks the time that the page is "finished" according to your own criteria. */ finished(timeStamp) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .FINISHED */ .BL, timeStamp); } /** * Forces a replay to record. If a replay is already actively recording, this call will be ignored. * If a recording has not been started, a new one will be created. If a recording has been started, but is currently not recording, it will resume recording. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordReplay/} */ recordReplay() { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .RECORD_REPLAY */ .CH); } /** * Forces an active replay to pause recording. If a replay is already actively recording, this call will cause the recording to pause. * If a recording is not currently recording, this call will be ignored. This API will pause both manual and automatic replays that are in progress. * The only way to resume recording after manually pausing a replay is to manually record again using the recordReplay() API. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/paeplay/} */ paeplay() { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .PAUSE_REPLAY */ .Tb); } /** * Adds a JavaScript object with a custom name, start time, etc. to an in-progress session trace. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/addtotrace/} * @param {{name: string, start: number, end?: number, origin?: string, type?: string}} customAttributes Supply a JavaScript object with these required and optional name/value pairs: * * - Required name/value pairs: name, start * - Optional name/value pairs: end, origin, type * - Note: Does not apply to MicroAgent * * If you are sending the same event object to New Relic as a PageAction, omit the TYPE attribute. (type is a string to describe what type of event you are marking inside of a session trace.) If included, it will override the event type and cause the PageAction event to be sent incorrectly. Instead, use the name attribute for event information. */ addToTrace(customAttributes) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .ADD_TO_TRACE */ .U2, customAttributes); } /** * Gives SPA routes more accurate names than default names. Monitors specific routes rather than by default grouping. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcurrentroutename/} * @param {string} name Current route name for the page. * - Note: Does not apply to MicroAgent */ setCurrentRouteName(name) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .SET_CURRENT_ROUTE_NAME */ .PA, name); } /** * Returns a new API object that is bound to the current SPA interaction. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/interaction/} * @returns {InteractionInstance} An API object that is bound to a specific BrowserInteraction event. Each time this method is called for the same BrowserInteraction, a new object is created, but it still references the same interaction. * - Note: Does not apply to MicroAgent * - Deprecation Notice: interaction.createTracer is deprecated. See https://docs.newrelic.com/eol/2024/04/eol-04-24-24-createtracer/ for more information. */ interaction() { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .INTERACTION */ .dT); } /** * Wrap a logger function to capture a log each time the function is invoked with the message and arguments ed * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/wraplogger/} * @param {object} parent The parent object containing the logger method * @param {string} functionName The property name of the function in the parent object to be wrapped * @param {{customAttributes?: object, level?: 'ERROR'|'TRACE'|'DEBUG'|'INFO'|'WARN'}} [options] customAttributes defaults to `{}` if not assigned, level defaults to `info` if not assigned. */ wrapLogger(parent, functionName, options) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .WRAP_LOGGER */ .Wb, parent, functionName, options); } /** * Measures a task that is recorded as a BrowserPerformance event. * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/} * @param {string} name The name of the task * @param {object?} options An object used to control the way the measure API operates * @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details */ measure(name, options) { return this.#callMethod(_api_constants__WEBPACK_IMPORTED_MODULE_1__/* .MEASURE */ .V1, name, options); } } /***/ }), /***/ 4261: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ $9: () => (/* binding */ LOG), /* harmony export */ BL: () => (/* binding */ FINISHED), /* harmony export */ CH: () => (/* binding */ RECORD_REPLAY), /* harmony export */ Dl: () => (/* binding */ SET__ID), /* harmony export */ Fw: () => (/* binding */ SET_PAGE_VIEW_NAME), /* harmony export */ PA: () => (/* binding */ SET_CURRENT_ROUTE_NAME), /* harmony export */ Pl: () => (/* binding */ prefix), /* harmony export */ Tb: () => (/* binding */ PAUSE_REPLAY), /* harmony export */ U2: () => (/* binding */ ADD_TO_TRACE), /* harmony export */ V1: () => (/* binding */ MEASURE), /* harmony export */ Wb: () => (/* binding */ WRAP_LOGGER), /* harmony export */ bt: () => (/* binding */ SET_ERROR_HANDLER), /* harmony export */ cD: () => (/* binding */ SET_CUSTOM_ATTRIBUTE), /* harmony export */ d3: () => (/* binding */ START), /* harmony export */ dT: () => (/* binding */ INTERACTION), /* harmony export */ eY: () => (/* binding */ ), /* harmony export */ fF: () => (/* binding */ RECORD_CUSTOM_EVENT), /* harmony export */ hG: () => (/* binding */ ADD_PAGE_ACTION), /* harmony export */ hw: () => (/* binding */ spaPrefix), /* harmony export */ k6: () => (/* binding */ ADD_RELEASE), /* harmony export */ nb: () => (/* binding */ SET_APPLICATION_VERSION), /* harmony export */ o5: () => (/* binding */ NOTICE_ERROR) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const prefix = 'api-'; const spaPrefix = prefix + 'ixn-'; const ADD_PAGE_ACTION = 'addPageAction'; const ADD_TO_TRACE = 'addToTrace'; const ADD_RELEASE = 'addRelease'; const FINISHED = 'finished'; const INTERACTION = 'interaction'; const LOG = 'log'; const NOTICE_ERROR = 'noticeError'; const PAUSE_REPLAY = 'paeplay'; const RECORD_CUSTOM_EVENT = 'recordCustomEvent'; const RECORD_REPLAY = 'recordReplay'; const = ''; const SET_APPLICATION_VERSION = 'setApplicationVersion'; const SET_CURRENT_ROUTE_NAME = 'setCurrentRouteName'; const SET_CUSTOM_ATTRIBUTE = 'setCustomAttribute'; const SET_ERROR_HANDLER = 'setErrorHandler'; const SET_PAGE_VIEW_NAME = 'setPageViewName'; const SET__ID = 'setId'; const START = 'start'; const WRAP_LOGGER = 'wrapLogger'; const MEASURE = 'measure'; /***/ }), /***/ 5205: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, { j: () => (/* binding */ configure) }); // EXTERNAL MODULE: ./src/common/window/nreum.js var nreum = __webpack_require__(384); // EXTERNAL MODULE: ./src/loaders/api-base.js var api_base = __webpack_require__(1741); ;// ./src/loaders/api/topLevelCallers.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function setTopLevelCallers(agentRef) { const nr = (0,nreum/* gosCDN */.pV)(); Object.getOwnPropertyNames(api_base/* ApiBase */.W.prototype).forEach(fnName => { const origFn = api_base/* ApiBase */.W.prototype[fnName]; if (typeof origFn !== 'function' || origFn === 'constructor') return; /** if the method already exists on the top and we are allowed to -- we can call it multiple times */ let origNrFn = nr[fnName]; if (!agentRef[fnName] || agentRef.exposed === false || agentRef.runtime?.loaderType === 'micro-agent') return; // dont set the top level callers if we are not allowed to nr[fnName] = (...args) => { const thisAgentFnResult = agentRef[fnName](...args); if (!origNrFn) return thisAgentFnResult; return origNrFn(...args); // if origFn is defined, we want to return the value from that call (ie the first agent that was set) }; }); } // EXTERNAL MODULE: ./src/common/config/info.js var config_info = __webpack_require__(2555); // EXTERNAL MODULE: ./src/features/generic_events/constants.js var constants = __webpack_require__(3333); ;// ./src/common/dom/query-selector.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const isValidSelector = selector => { if (!selector || typeof selector !== 'string') return false; try { document.createDocumentFragment().querySelector(selector); } catch { return false; } return true; }; // EXTERNAL MODULE: ./src/common/session/constants.js var session_constants = __webpack_require__(2614); // EXTERNAL MODULE: ./src/common/util/console.js var console = __webpack_require__(944); // EXTERNAL MODULE: ./src/common/config/configurable.js var configurable = __webpack_require__(8122); ;// ./src/common/config/init.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @typedef {import('./init-types').Init} Init */ const nrMask = '[data-nr-mask]'; /** * @returns {Init} the default configuration object */ const InitModelFn = () => { const hiddenState = { feature_flags: [], experimental: { marks: false, measures: false, resources: false }, mask_selector: '*', block_selector: '[data-nr-block]', mask_input_options: { color: false, date: false, 'datetime-local': false, email: false, month: false, number: false, range: false, search: false, tel: false, text: false, time: false, url: false, week: false, // unify textarea and select element with text input textarea: false, select: false, : true // This will be enforced to always be true in the setter } }; return { ajax: { deny_list: undefined, block_internal: true, enabled: true, autoStart: true }, api: { allow_ed_children: true, duplicate_ed_data: false }, distributed_tracing: { enabled: undefined, exclude_newrelic_header: undefined, cors_use_newrelic_header: undefined, cors_use_tracecontext_headers: undefined, allowed_origins: undefined }, get feature_flags() { return hiddenState.feature_flags; }, set feature_flags(val) { hiddenState.feature_flags = val; }, generic_events: { enabled: true, autoStart: true }, harvest: { interval: 30 }, jserrors: { enabled: true, autoStart: true }, logging: { enabled: true, autoStart: true }, metrics: { enabled: true, autoStart: true }, obfuscate: undefined, page_action: { enabled: true }, page_view_event: { enabled: true, autoStart: true }, page_view_timing: { enabled: true, autoStart: true }, performance: { get capture_marks() { return hiddenState.feature_flags.includes(constants/* FEATURE_FLAGS */.$v.MARKS) || hiddenState.experimental.marks; }, set capture_marks(val) { hiddenState.experimental.marks = val; }, get capture_measures() { return hiddenState.feature_flags.includes(constants/* FEATURE_FLAGS */.$v.MEASURES) || hiddenState.experimental.measures; }, set capture_measures(val) { hiddenState.experimental.measures = val; }, capture_detail: true, resources: { get enabled() { return hiddenState.feature_flags.includes(constants/* FEATURE_FLAGS */.$v.RESOURCES) || hiddenState.experimental.resources; }, set enabled(val) { hiddenState.experimental.resources = val; }, asset_types: [], first_party_domains: [], ignore_newrelic: true } }, privacy: { cookies_enabled: true }, proxy: { assets: undefined, beacon: undefined }, session: { expiresMs: session_constants/* DEFAULT_EXPIRES_MS */.wk, inactiveMs: session_constants/* DEFAULT_INACTIVE_MS */.BB }, session_replay: { autoStart: true, enabled: false, preload: false, sampling_rate: 10, error_sampling_rate: 100, collect_fonts: false, inline_images: false, fix_stylesheets: true, // recording config settings mask_all_inputs: true, // this has a getter/setter to facilitate validation of the selectors get mask_text_selector() { return hiddenState.mask_selector; }, set mask_text_selector(val) { if (isValidSelector(val)) hiddenState.mask_selector = "".concat(val, ",").concat(nrMask);else if (val === '' || val === null) hiddenState.mask_selector = nrMask;else (0,console/* warn */.R)(5, val); }, // these properties only have getters because they are enforcable constants and should error if someone tries to override them get block_class() { return 'nr-block'; }, get ignore_class() { return 'nr-ignore'; }, get mask_text_class() { return 'nr-mask'; }, // props with a getter and setter are used to extend enforcable constants with customer input // we must preserve data-nr-block no matter what else the customer sets get block_selector() { return hiddenState.block_selector; }, set block_selector(val) { if (isValidSelector(val)) hiddenState.block_selector += ",".concat(val);else if (val !== '') (0,console/* warn */.R)(6, val); }, // : must always be present and true no matter what customer sets get mask_input_options() { return hiddenState.mask_input_options; }, set mask_input_options(val) { if (val & typeof val === 'object') hiddenState.mask_input_options = { ...val, : true };else (0,console/* warn */.R)(7, val); } }, session_trace: { enabled: true, autoStart: true }, soft_navigations: { enabled: true, autoStart: true }, spa: { enabled: true, autoStart: true }, ssl: undefined, _actions: { enabled: true, elementAttributes: ['id', 'className', 'tagName', 'type'] } }; }; const mergeInit = init => { return (0,configurable/* getModeledObject */.a)(init, InitModelFn()); }; // EXTERNAL MODULE: ./src/common/constants/runtime.js var constants_runtime = __webpack_require__(6154); // EXTERNAL MODULE: ./src/common/constants/env.cdn.js var env_cdn = __webpack_require__(9324); ;// ./src/common/config/runtime.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Module level count of harvests. This property will auto-increment each time it is accessed. * @type {number} */ let _harvestCount = 0; const ReadOnly = { buildEnv: env_cdn/* BUILD_ENV */.F3, distMethod: env_cdn/* DIST_METHOD */.Xs, version: env_cdn/* VERSION */.xv, originTime: constants_runtime/* originTime */.WN }; const RuntimeModel = { /** Agent-specific metadata found in the RUM call response. ex. entityGuid */ appMetadata: {}, customTransaction: undefined, denyList: undefined, disabled: false, entityManager: undefined, harvester: undefined, isolatedBacklog: false, isRecording: false, // true when actively recording, false when paused or stopped loaderType: undefined, maxBytes: 30000, obfuscator: undefined, onerror: undefined, ptid: undefined, releaseIds: {}, session: undefined, timeKeeper: undefined, get harvestCount() { return ++_harvestCount; } }; const mergeRuntime = runtime => { const modeledObject = (0,configurable/* getModeledObject */.a)(runtime, RuntimeModel); const readonlyDescriptors = Object.keys(ReadOnly).reduce((descriptors, key) => { descriptors[key] = { value: ReadOnly[key], writable: false, configurable: true, enumerable: true }; return descriptors; }, {}); return Object.defineProperties(modeledObject, readonlyDescriptors); }; // EXTERNAL MODULE: ./src/common/util/feature-flags.js var feature_flags = __webpack_require__(5701); ;// ./src/loaders/configure/public-path.cdn.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** Set the default CDN or remote for fetching the assets; NPM shouldn't change this var */ const redefinePubliath = urlString => { const isOrigin = urlString.startsWith('http'); // Input is not expected to end in a slash, but webpack concats as-is, so one is inserted. urlString += '/'; // If there's no existing HTTP scheme, the secure protocol is prepended by default. __webpack_require__.p = isOrigin ? urlString : 'https://' + urlString; // eslint-disable-line }; // EXTERNAL MODULE: ./src/common/event-emitter/contextual-ee.js var contextual_ee = __webpack_require__(7836); // EXTERNAL MODULE: ./src/common/dispatch/global-event.js var global_event = __webpack_require__(3241); ;// ./src/common/config/loader-config.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const LoaderConfigModel = { ID: undefined, trustKey: undefined, agentID: undefined, licenseKey: undefined, applicationID: undefined, xpid: undefined }; const mergeLoaderConfig = loaderConfig => { return (0,configurable/* getModeledObject */.a)(loaderConfig, LoaderConfigModel); }; ;// ./src/loaders/configure/configure.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const alreadySetOnce = new Set(); // the configure() function can run multiple times in agent lifecycle for different agents /** * Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance. * IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function. */ function configure(agent, opts = {}, loaderType, forceDrain) { // eslint-disable-next-line camelcase let { init, info, loader_config, runtime = {}, exposed = true } = opts; if (!info) { const nr = (0,nreum/* gosCDN */.pV)(); init = nr.init; info = nr.info; // eslint-disable-next-line camelcase loader_config = nr.loader_config; } agent.init = mergeInit(init || {}); // eslint-disable-next-line camelcase agent.loader_config = mergeLoaderConfig(loader_config || {}); info.jsAttributes ??= {}; if (constants_runtime/* isWorkerScope */.bv) { // add a default attr to all worker payloads info.jsAttributes.isWorker = true; } agent.info = (0,config_info/* mergeInfo */.D)(info); const updatedInit = agent.init; const internalTrafficList = [info.beacon, info.errorBeacon]; if (!alreadySetOnce.has(agent.agentIdentifier)) { if (updatedInit.proxy.assets) { redefinePubliath(updatedInit.proxy.assets); internalTrafficList.push(updatedInit.proxy.assets); } if (updatedInit.proxy.beacon) internalTrafficList.push(updatedInit.proxy.beacon); setTopLevelCallers(agent); // no need to set global APIs on newrelic obj more than once (0,nreum/* addToNREUM */.US)('activatedFeatures', feature_flags/* activatedFeatures */.B); // Update if soft_navigations is allowed to run AND part of this agent build, used to override old spa functions. agent.runSoftNavOverSpa &= updatedInit.soft_navigations.enabled === true && updatedInit.feature_flags.includes('soft_nav'); } runtime.denyList = [...(updatedInit.ajax.deny_list || []), ...(updatedInit.ajax.block_internal ? internalTrafficList : [])]; runtime.ptid = agent.agentIdentifier; runtime.loaderType = loaderType; agent.runtime = mergeRuntime(runtime); if (!alreadySetOnce.has(agent.agentIdentifier)) { agent.ee = contextual_ee.ee.get(agent.agentIdentifier); agent.exposed = exposed; (0,global_event/* dispatchGlobalEvent */.W)({ agentIdentifier: agent.agentIdentifier, drained: !!feature_flags/* activatedFeatures */.B?.[agent.agentIdentifier], type: 'lifecycle', name: 'initialize', feature: undefined, data: agent.config }); } alreadySetOnce.add(agent.agentIdentifier); } /***/ }), /***/ 8374: /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /* global __webpack_require__ */ __webpack_require__.nc = (() => { try { return document?.currentScript?.nonce; } catch (ex) { // Swallow error and proceed like nonce is not defined // This will happen when the agent is loaded in a worker scope } return ''; })(); /***/ }), /***/ 860: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ $J: () => (/* binding */ FEATURE_TO_ENDPOINT), /* harmony export */ K7: () => (/* binding */ FEATURE_NAMES), /* harmony export */ P3: () => (/* binding */ featurePriority), /* harmony export */ XX: () => (/* binding */ JSERRORS), /* harmony export */ Yy: () => (/* binding */ LOGS), /* harmony export */ df: () => (/* binding */ BLOBS), /* harmony export */ qY: () => (/* binding */ EVENTS), /* harmony export */ v4: () => (/* binding */ RUM) /* harmony export */ }); /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ // To reduce build size a bit: const EVENTS = 'events'; const JSERRORS = 'jserrors'; const BLOBS = 'browser/blobs'; const RUM = 'rum'; const LOGS = 'browser/logs'; const FEATURE_NAMES = { ajax: 'ajax', genericEvents: 'generic_events', jserrors: JSERRORS, logging: 'logging', metrics: 'metrics', /** * @deprecated This feature has been replaced by Generic Events. Use/Import `GenericEvents` instead. This wrapper will be removed in a future release */ pageAction: 'page_action', pageViewEvent: 'page_view_event', pageViewTiming: 'page_view_timing', sessionReplay: 'session_replay', sessionTrace: 'session_trace', softNav: 'soft_navigations', spa: 'spa' }; /** * The order in which features will be instrumented. This is the traditional order. It's unclear if the order of * wrapping events has any ramifications, so we are enforcing this order intentionally for now. */ const featurePriority = { [FEATURE_NAMES.pageViewEvent]: 1, [FEATURE_NAMES.pageViewTiming]: 2, [FEATURE_NAMES.metrics]: 3, [FEATURE_NAMES.jserrors]: 4, [FEATURE_NAMES.spa]: 5, [FEATURE_NAMES.ajax]: 6, [FEATURE_NAMES.sessionTrace]: 7, [FEATURE_NAMES.softNav]: 8, [FEATURE_NAMES.sessionReplay]: 9, [FEATURE_NAMES.logging]: 10, [FEATURE_NAMES.genericEvents]: 11 }; const FEATURE_TO_ENDPOINT = { [FEATURE_NAMES.pageViewEvent]: RUM, [FEATURE_NAMES.pageViewTiming]: EVENTS, [FEATURE_NAMES.ajax]: EVENTS, [FEATURE_NAMES.spa]: EVENTS, [FEATURE_NAMES.softNav]: EVENTS, [FEATURE_NAMES.metrics]: JSERRORS, [FEATURE_NAMES.jserrors]: JSERRORS, [FEATURE_NAMES.sessionTrace]: BLOBS, [FEATURE_NAMES.sessionReplay]: BLOBS, [FEATURE_NAMES.logging]: LOGS, [FEATURE_NAMES.genericEvents]: 'ins' }; /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) & !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/ensure chunk */ /******/ (() => { /******/ __webpack_require__.f = {}; /******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = (chunkId) => { /******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { /******/ __webpack_require__.f[key](chunkId, promises); /******/ return promises; /******/ }, [])); /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/get javascript chunk filename */ /******/ (() => { /******/ // This function allow to reference async chunks /******/ __webpack_require__.u = (chunkId) => { /******/ // return url for filenames based on template /******/ return "" + {"212":"nr-spa-compressor","249":"nr-spa-recorder","478":"nr-spa"}[chunkId] + "-1.291.1.min.js"; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ /******/ (() => { /******/ var inProgress = {}; /******/ var dataWebpackPrefix = "NRBA-1.291.1.PROD:"; /******/ // loadScript function to load a script via script tag /******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { /******/ var scripts = document.getElementsByTagName("script"); /******/ for(var i = 0; i < scripts.length; i++) { /******/ var s = scripts[i]; /******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } /******/ } /******/ } /******/ if(!script) { /******/ needAttach = true; /******/ var sriHashes = { /******/ '478':'sha512-UeRYwzt/NxLFiDf+DKspr8GmLgSWBtm2U/6Scyn6ciQSM37ytcWPGNwMldcAq7IVnoHAr8K4dg3HffXRAFWlzQ==','249':'sha512-wnaEX/oEVZyfeTdqJ1U0tqhmG/Abap8+MkR4U/i3vD9Q+Q4In6lAsTD5AH9GpGk72crPK/sIlE4MDV9A1fqhHQ==','212':'sha512-LWUIB19B5T6pXrhZWb6vDqNcEe0QA0OLNT5KplNyPB/IQq9Hr7AidxGvQwtFgvSi1Ce8uwax1MQzMM9a95ijOg==' /******/ }; /******/ script = document.createElement('script'); /******/ /******/ script.charset = 'utf-8'; /******/ script.timeout = 120; /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } /******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); /******/ /******/ script.src = url; /******/ if (script.src.indexOf(window.location.origin + '/') !== 0) { /******/ script.crossOrigin = "anonymous"; /******/ } /******/ if (sriHashes[chunkId]) { /******/ script.integrity = sriHashes[chunkId]; /******/ } /******/ } /******/ inProgress[url] = [done]; /******/ var onScriptComplete = (prev, event) => { /******/ // avoid mem leaks in IE. /******/ script.onerror = script.onload = null; /******/ clearTimeout(timeout); /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode & script.parentNode.removeChild(script); /******/ doneFns & doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); /******/ needAttach & document.head.appendChild(script); /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' & Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/publiath */ /******/ (() => { /******/ __webpack_require__.p = "https://js-agent.newrelic.com/"; /******/ })(); /******/ /******/ /* webpack/runtime/jsonp chunk loading */ /******/ (() => { /******/ // no baseURI /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 38: 0, /******/ 788: 0 /******/ }; /******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; /******/ if(installedChunkData !== 0) { // 0 means "already installed". /******/ /******/ // a Promise means "currently loading". /******/ if(installedChunkData) { /******/ promises.push(installedChunkData[2]); /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache /******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading /******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId); /******/ // create error before stack unwound to get useful stacktrace later /******/ var error = new Error(); /******/ var loadingEnded = (event) => { /******/ if(__webpack_require__.o(installedChunks, chunkId)) { /******/ installedChunkData = installedChunks[chunkId]; /******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; /******/ if(installedChunkData) { /******/ var errorType = event & (event.type === 'load' ? 'missing' : event.type); /******/ var realSrc = event & event.target && event.target.src; /******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; /******/ error.name = 'ChunkLoadError'; /******/ error.type = errorType; /******/ error.request = realSrc; /******/ installedChunkData[1](error); /******/ } /******/ } /******/ }; /******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } /******/ } /******/ } /******/ }; /******/ /******/ // no prefetching /******/ /******/ // no preloaded /******/ /******/ // no HMR /******/ /******/ // no HMR manifest /******/ /******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0; /******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { /******/ for(moduleId in moreModules) { /******/ if(__webpack_require__.o(moreModules, moduleId)) { /******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; /******/ } /******/ } /******/ if(runtime) var result = runtime(__webpack_require__); /******/ } /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) & installedChunks[chunkId]) { /******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk:NRBA-1.291.1.PROD"] = self["webpackChunk:NRBA-1.291.1.PROD"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry needs to be wrapped in an IIFE because it needs to be in strict mode. (() => { "use strict"; // EXTERNAL MODULE: ./src/loaders/configure/nonce.cdn.js var spa_nonce_cdn = __webpack_require__(8374); // EXTERNAL MODULE: ./src/common/ids/unique-id.js var spa_unique_id = __webpack_require__(9566); // EXTERNAL MODULE: ./src/loaders/api-base.js var spa_api_base = __webpack_require__(1741); ;// ./src/loaders/agent-base.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /* eslint-disable n/handle-callback-err */ /** * @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance */ class spa_AgentBase extends spa_api_base/* ApiBase */.W { agentIdentifier = (0,spa_unique_id/* generateRandomHexString */.LA)(16); } // EXTERNAL MODULE: ./src/loaders/features/features.js var spa_features = __webpack_require__(860); ;// ./src/loaders/features/enabled-features.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const spa_featureNames = Object.values(spa_features/* FEATURE_NAMES */.K7); function spa_getEnabledFeatures(agentInit) { const enabledFeatures = {}; spa_featureNames.forEach(featureName => { enabledFeatures[featureName] = !!agentInit[featureName]?.enabled; }); return enabledFeatures; } // EXTERNAL MODULE: ./src/loaders/configure/configure.js + 6 modules var spa_configure = __webpack_require__(5205); ;// ./src/loaders/features/featureDependencies.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_getFeatureDependencyNames(feature) { switch (feature) { case spa_features/* FEATURE_NAMES */.K7.ajax: return [spa_features/* FEATURE_NAMES */.K7.jserrors]; case spa_features/* FEATURE_NAMES */.K7.sessionTrace: return [spa_features/* FEATURE_NAMES */.K7.ajax, spa_features/* FEATURE_NAMES */.K7.pageViewEvent]; case spa_features/* FEATURE_NAMES */.K7.sessionReplay: return [spa_features/* FEATURE_NAMES */.K7.sessionTrace]; case spa_features/* FEATURE_NAMES */.K7.pageViewTiming: return [spa_features/* FEATURE_NAMES */.K7.pageViewEvent]; // this could change if we disconnect window load timings default: return []; } } // EXTERNAL MODULE: ./src/common/event-emitter/handle.js var spa_handle = __webpack_require__(9908); // EXTERNAL MODULE: ./src/common/timing/now.js var spa_now = __webpack_require__(1863); // EXTERNAL MODULE: ./src/loaders/api/constants.js var cdn_spa_constants = __webpack_require__(4261); // EXTERNAL MODULE: ./src/common/dispatch/global-event.js var spa_global_event = __webpack_require__(3241); // EXTERNAL MODULE: ./src/common/util/console.js var spa_console = __webpack_require__(944); // EXTERNAL MODULE: ./src/common/util/feature-flags.js var spa_feature_flags = __webpack_require__(5701); // EXTERNAL MODULE: ./src/features/metrics/constants.js + 1 modules var spa_metrics_constants = __webpack_require__(8154); ;// ./src/loaders/api/sharedHandlers.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * setupAPI is a utility function that assigns API methods to an object while emitting ability metrics and global events. * @param {string} name The API method name to be set up. * @param {Function} fn The function to be executed when the API method is called. * @param {Object} agent The agent instance. Will be used if no object is provided to assign the api method to. * @param {Object} [obj] The object to which the API method will be assigned. * @returns {*} The output of the function being called. */ function spa_setupAPI(name, fn, agent, obj) { /* use object if provided, otherwise use agent as base for api method assignment */ const api = obj || agent; // We only set the global API event if the API is not already overridden from the default if (!api || !!api[name] & api[name] !== spa_AgentBase.prototype[name]) return; api[name] = function () { (0,spa_handle/* handle */.p)(spa_metrics_constants/* ABILITY_METRIC_CHANNEL */.xV, ['API/' + name + '/called'], undefined, spa_features/* FEATURE_NAMES */.K7.metrics, agent.ee); (0,spa_global_event/* dispatchGlobalEvent */.W)({ agentIdentifier: agent.agentIdentifier, drained: !!spa_feature_flags/* activatedFeatures */.B?.[agent.agentIdentifier], type: 'data', name: 'api', feature: cdn_spa_constants/* prefix */.Pl + name, data: {} }); try { return fn.apply(this, arguments); } catch (err) { (0,spa_console/* warn */.R)(23, err); } }; } /** * Attach the key-value attribute onto agent payloads. All browser events in NR will be affected. * @param {Agent} agent the agent instance reference * @param {string} key * @param {string|number|boolean|null} value - null indicates the key should be removed or erased * @param {string} apiName * @param {boolean} addToBrowserStorage - whether this attribute should be stored in browser storage API and retrieved by the next agent context or initialization * @returns @see apiCall */ function spa_appendJsAttribute(agent, key, value, apiName, addToBrowserStorage) { const currentInfo = agent.info; if (value === null) { delete currentInfo.jsAttributes[key]; } else { currentInfo.jsAttributes[key] = value; } if (addToBrowserStorage || value === null) (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + apiName, [(0,spa_now/* now */.t)(), key, value], undefined, 'session', agent.ee); } ;// ./src/loaders/api/setPageViewName.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupSetPageViewNameAPI(agent) { spa_setupAPI(cdn_spa_constants/* SET_PAGE_VIEW_NAME */.Fw, function (name, host) { if (typeof name !== 'string') return; if (name.charAt(0) !== '/') name = '/' + name; agent.runtime.customTransaction = (host || 'http://custom.transaction') + name; (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + cdn_spa_constants/* SET_PAGE_VIEW_NAME */.Fw, [(0,spa_now/* now */.t)()], undefined, undefined, agent.ee); }, agent); } // EXTERNAL MODULE: ./src/common/drain/drain.js var spa_drain = __webpack_require__(1687); // EXTERNAL MODULE: ./src/features/utils/feature-base.js var spa_feature_base = __webpack_require__(4234); // EXTERNAL MODULE: ./src/common/window/load.js var spa_load = __webpack_require__(5289); // EXTERNAL MODULE: ./src/common/constants/runtime.js var spa_runtime = __webpack_require__(6154); // EXTERNAL MODULE: ./src/features/session_replay/shared/utils.js var spa_utils = __webpack_require__(5270); // EXTERNAL MODULE: ./src/features/utils/feature-gates.js var spa_feature_gates = __webpack_require__(7767); // EXTERNAL MODULE: ./src/common/util/invoke.js var spa_invoke = __webpack_require__(6389); ;// ./src/features/utils/instrument-base.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Defines `InstrumentBase` to be used as the super of the Instrument classes implemented by each feature. * Inherits and executes the `checkConfiguration` method from [FeatureBase]{@link ./feature-base}, which also * exposes the `blocked` property. */ /** * Base class for instrumenting a feature. * @extends FeatureBase */ class spa_InstrumentBase extends spa_feature_base/* FeatureBase */.W { /** * Instantiate InstrumentBase. * @param {string} agentIdentifier - The unique ID of the instantiated agent (relative to global scope). * @param {string} featureName - The name of the feature module (used to construct file path). */ constructor(agentRef, featureName) { super(agentRef.agentIdentifier, featureName); /** @type {Function | undefined} This should be set by any derived Instrument class if it has things to do when feature fails or is killed. */ this.abortHandler = undefined; /** * @type {import('./aggregate-base').AggregateBase} Holds the reference to the feature's aggregate module counterpart, if and after it has been initialized. This may not be assigned until after page loads! * The only purpose of this for now is to expose it to the NREUM interface, as the feature's instrument instance is already exposed. */ this.featAggregate = undefined; /** * @type {Promise} Assigned immediately after @see importAggregator runs. Serves as a signal for when the inner async fn finishes execution. Useful for features to await * one another if there are inter-features dependencies. */ this.onAggregateImported = undefined; /** * used in conjunction with newrelic.start() to defer harvesting in features * @type {Promise} Resolves when the feature is ready to import its aggregator, either immediately or after the start API has been called if the feature is autoStart: false. */ this.deferred = Promise.resolve(); if (agentRef.init[this.featureName].autoStart === false) { this.deferred = new Promise((resolve, reject) => { this.ee.on('manual-start-all', (0,spa_invoke/* single */.J)(() => { // the feature to drain only once the API has been called, it will drain when importAggregator finishes for all the features // called by the api in that cycle (0,spa_drain/* Drain */.Ak)(agentRef.agentIdentifier, this.featureName); resolve(); })); }); } else { /** if the feature requires opt-in (!auto-start), it will get ed once the api has been called */ (0,spa_drain/* Drain */.Ak)(agentRef.agentIdentifier, featureName); } } /** * Lazy-load the latter part of the feature: its aggregator. This method is called by the first part of the feature * (the instrumentation) when instrumentation is complete. * @param {Object} agentRef - reference to the base agent ancestor that this feature belongs to * @param {Function} fetchAggregator - a function that returns a promise that resolves to the aggregate module * @param {Object} [argsObjFromInstrument] - any values or references to down to aggregate * @returns void */ importAggregator(agentRef, fetchAggregator, argsObjFromInstrument = {}) { if (this.featAggregate) return; let loadedSuccessfully; this.onAggregateImported = new Promise(resolve => { loadedSuccessfully = resolve; }); const importLater = async () => { // wait for the deferred promise to resolve before proceeding // this will resolve immediately if the feature is auto-started, // or otherwise when the manual-start-all event is emitted by the start API await this.deferred; let session; try { if ((0,spa_feature_gates/* canEnableSessionTracking */.V)(agentRef.init)) { // would require some setup before certain features start const { setupAgentSession } = await __webpack_require__.e(/* import() | session-manager */ 478).then(__webpack_require__.bind(__webpack_require__, 6526)); session = setupAgentSession(agentRef); } } catch (e) { (0,spa_console/* warn */.R)(20, e); this.ee.emit('internal-error', [e]); if (this.featureName === spa_features/* FEATURE_NAMES */.K7.sessionReplay) this.abortHandler?.(); // SR should stop recording if session DNE } /** * Note this try-catch differs from the one in Agent.run() in that it's placed later in a page's lifecycle and * it's only responsible for aborting its one specific feature, rather than all. */ try { if (!this.#shouldImportAgg(this.featureName, session, agentRef.init)) { (0,spa_drain/* drain */.Ze)(this.agentIdentifier, this.featureName); loadedSuccessfully(false); // aggregate module isn't loaded at all return; } const { Aggregate } = await fetchAggregator(); this.featAggregate = new Aggregate(agentRef, argsObjFromInstrument); agentRef.runtime.harvester.initializedAggregates.push(this.featAggregate); // "subscribe" the feature to future harvest intervals (PVE will start the timer) loadedSuccessfully(true); } catch (e) { (0,spa_console/* warn */.R)(34, e); this.abortHandler?.(); // undo any important alterations made to the page // not ed yet but nice to do: "abort" this agent's EE for this feature specifically (0,spa_drain/* drain */.Ze)(this.agentIdentifier, this.featureName, true); loadedSuccessfully(false); if (this.ee) this.ee.abort(); } }; // For regular web pages, we want to wait and lazy-load the aggregator only after all page resources are loaded. // Non-browser scopes (i.e. workers) have no `window.load` event, so the aggregator can be lazy-loaded immediately. if (!spa_runtime/* isBrowserScope */.RI) importLater();else (0,spa_load/* onWindowLoad */.GG)(() => importLater(), true); } /** * Make a determination if an aggregate class should even be imported * @param {string} featureName * @param {import('../../common/session/session-entity').SessionEntity} session * @returns */ #shouldImportAgg(featureName, session, agentInit) { switch (featureName) { case spa_features/* FEATURE_NAMES */.K7.sessionReplay: // the session manager must be initialized successfully for Replay & Trace features return (0,spa_utils/* hasReplayPrerequisite */.SR)(agentInit) && !!session; case spa_features/* FEATURE_NAMES */.K7.sessionTrace: return !!session; default: return true; } } } // EXTERNAL MODULE: ./src/features/page_view_event/constants.js var spa_page_view_event_constants = __webpack_require__(6630); ;// ./src/features/page_view_event/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class spa_Instrument extends spa_InstrumentBase { static featureName = spa_page_view_event_constants/* FEATURE_NAME */.T; constructor(agentRef) { super(agentRef, spa_page_view_event_constants/* FEATURE_NAME */.T); /** feature specific APIs */ spa_setupSetPageViewNameAPI(agentRef); /** messages from the API that can trigger a new RUM call */ this.ee.on('api-send-rum', (attrs, target) => (0,spa_handle/* handle */.p)('send-rum', [attrs, target], undefined, this.featureName, this.ee)); this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | page_view_event-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 1983))); } } const spa_PageViewEvent = (/* unused pure expression or super */ null & (spa_Instrument)); // EXTERNAL MODULE: ./src/common/window/nreum.js var spa_nreum = __webpack_require__(384); ;// ./src/loaders/api/setCustomAttribute.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupSetCustomAttributeAPI(agent) { spa_setupAPI(cdn_spa_constants/* SET_CUSTOM_ATTRIBUTE */.cD, function (name, value, persistAttribute = false) { if (typeof name !== 'string') { (0,spa_console/* warn */.R)(39, typeof name); return; } if (!(['string', 'number', 'boolean'].includes(typeof value) || value === null)) { (0,spa_console/* warn */.R)(40, typeof value); return; } return spa_appendJsAttribute(agent, name, value, cdn_spa_constants/* SET_CUSTOM_ATTRIBUTE */.cD, persistAttribute); }, agent); } ;// ./src/loaders/api/setId.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupSetIdAPI(agent) { /** * Attach the 'end.id' attribute onto agent payloads. This may be used in NR queries to group all browser events by specific s. * @param {string} value - unique identifier; a null id suggests none should exist * @returns @see apiCall */ spa_setupAPI(cdn_spa_constants/* SET__ID */.Dl, function (value) { if (!(typeof value === 'string' || value === null)) { (0,spa_console/* warn */.R)(41, typeof value); return; } return spa_appendJsAttribute(agent, 'end.id', value, cdn_spa_constants/* SET__ID */.Dl, true); }, agent); } ;// ./src/loaders/api/setApplicationVersion.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupSetApplicationVersionAPI(agent) { /** * Attach the 'applcation.version' attribute onto agent payloads. This may be used in NR queries to group all browser events by a specific customer-defined release. * @param {string|null} value - Application version -- if null, will "unset" the value * @returns @see apiCall */ spa_setupAPI(cdn_spa_constants/* SET_APPLICATION_VERSION */.nb, function (value) { if (!(typeof value === 'string' || value === null)) { (0,spa_console/* warn */.R)(42, typeof value); return; } return spa_appendJsAttribute(agent, 'application.version', value, cdn_spa_constants/* SET_APPLICATION_VERSION */.nb, false); }, agent); } ;// ./src/loaders/api/start.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupStartAPI(agent) { spa_setupAPI(cdn_spa_constants/* START */.d3, function () { agent.ee.emit('manual-start-all'); }, agent); } ;// ./src/loaders/agent.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ // important side effects // loader files // required features // common files // agent-level API files /** * @typedef {Object} AgentOptions * @property {import('../common/config/info').Info} info - An object containing operational info needed by the agent. It's strongly encouraged to define this. * @property {import('../common/config/init').Init} [init] - An object containing initialization configurations for the agent. * @property {Object} [loader_config] - An object containing configuration primarily ed by APM injection. This is not recommended for use if not already provided by installation. * @property {Object} [runtime] - An object containing runtime references by the agent. This is not recommended for use. * @property {Array} [features] - A list of feature modules to include in the agent. This is only necessary when using the `Agent` class strictly. * @property {boolean} [exposed] - Whether the agent should expose its API to (be affected by) the global `newrelic` object. * @property {string} [loaderType] - The type of loader that is initializing the agent. It's recommended to allow the default. */ /** * A flexible class that may be used to compose an agent from a select subset of feature modules. In applications * sensitive to network load, this may result in smaller builds with slightly lower performance impact. */ class spa_Agent extends spa_AgentBase { /** * @param {AgentOptions} options */ constructor(options) { super(); if (!spa_runtime/* globalScope */.gm) { // We could not determine the runtime environment. Short-circuite the agent here // to avoid possible exceptions later that may cause issues with customer's application. (0,spa_console/* warn */.R)(21); return; } this.features = {}; (0,spa_nreum/* setNREUMInitializedAgent */.bQ)(this.agentIdentifier, this); // append this agent onto the global NREUM.initializedAgents this.desiredFeatures = new Set(options.features || []); // expected to be a list of static Instrument/InstrumentBase classes, see "spa.js" for example // For Now... ALL agents must make the rum call whether the page_view_event feature was enabled or not. // NR1 creates an index on the rum call, and if not seen for a few days, will remove the browser app! // Future work is being planned to evaluate removing this behavior from the backend, but for now we must ensure this call is made this.desiredFeatures.add(spa_Instrument); this.runSoftNavOverSpa = [...this.desiredFeatures].some(instr => instr.featureName === spa_features/* FEATURE_NAMES */.K7.softNav); (0,spa_configure/* configure */.j)(this, options, options.loaderType || 'agent'); // add api, exposed, and other config properties /** assign base agent-level API definitions, feature-level APIs will be handled by the features to allow better code-splitting */ spa_setupSetCustomAttributeAPI(this); spa_setupSetIdAPI(this); spa_setupSetApplicationVersionAPI(this); spa_setupStartAPI(this); this.run(); } get config() { return { info: this.info, init: this.init, loader_config: this.loader_config, runtime: this.runtime }; } get api() { return this; } run() { // Attempt to initialize all the requested features (sequentially in prio order & synchronously), with any failure aborting the whole process. try { const enabledFeatures = spa_getEnabledFeatures(this.init); const featuresToStart = [...this.desiredFeatures]; featuresToStart.sort((a, b) => spa_features/* featurePriority */.P3[a.featureName] - spa_features/* featurePriority */.P3[b.featureName]); featuresToStart.forEach(InstrumentCtor => { if (!enabledFeatures[InstrumentCtor.featureName] & InstrumentCtor.featureName !== spa_features/* FEATURE_NAMES */.K7.pageViewEvent) return; // PVE is required to run even if it's marked disabled if (this.runSoftNavOverSpa & InstrumentCtor.featureName === spa_features/* FEATURE_NAMES */.K7.spa) return; if (!this.runSoftNavOverSpa & InstrumentCtor.featureName === spa_features/* FEATURE_NAMES */.K7.softNav) return; const dependencies = spa_getFeatureDependencyNames(InstrumentCtor.featureName); const missingDependencies = dependencies.filter(featName => !(featName in this.features)); // any other feature(s) this depends on should've been initialized on prior iterations by priority order if (missingDependencies.length > 0) { (0,spa_console/* warn */.R)(36, { targetFeature: InstrumentCtor.featureName, missingDependencies }); } this.features[InstrumentCtor.featureName] = new InstrumentCtor(this); }); } catch (err) { (0,spa_console/* warn */.R)(22, err); for (const featName in this.features) { // this.features hold only features that have been instantiated this.features[featName].abortHandler?.(); } const newrelic = (0,spa_nreum/* gosNREUM */.Zm)(); delete newrelic.initializedAgents[this.agentIdentifier]?.features; // GC mem used internally by features delete this.sharedAggregator; // Keep the initialized agent object with its configs for troubleshooting purposes. const thisEE = newrelic.ee.get(this.agentIdentifier); thisEE.abort(); // set flag and clear backlog return false; } } } // EXTERNAL MODULE: ./src/common/window/page-visibility.js var spa_page_visibility = __webpack_require__(2843); // EXTERNAL MODULE: ./src/common/event-listener/event-listener-opts.js var spa_event_listener_opts = __webpack_require__(3878); // EXTERNAL MODULE: ./src/features/page_view_timing/constants.js var spa_page_view_timing_constants = __webpack_require__(782); ;// ./src/features/page_view_timing/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class cdn_spa_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_page_view_timing_constants/* FEATURE_NAME */.T; constructor(agentRef) { super(agentRef, spa_page_view_timing_constants/* FEATURE_NAME */.T); if (!spa_runtime/* isBrowserScope */.RI) return; // CWV is irrelevant outside web context // While we try to replicate web-vital's visibilitywatcher logic in an effort to defer that library to post-pageload, this isn't perfect and doesn't consider prerendering. (0,spa_page_visibility/* subscribeToVisibilityChange */.u)(() => (0,spa_handle/* handle */.p)('docHidden', [(0,spa_now/* now */.t)()], undefined, spa_page_view_timing_constants/* FEATURE_NAME */.T, this.ee), true); // Window fires its pagehide event (typically on navigation--this occurrence is a *subset* of vis change); don't defer this unless it's guarantee it cannot happen before load(?) (0,spa_event_listener_opts/* windowAddEventListener */.sp)('pagehide', () => (0,spa_handle/* handle */.p)('winPagehide', [(0,spa_now/* now */.t)()], undefined, spa_page_view_timing_constants/* FEATURE_NAME */.T, this.ee)); this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | page_view_timing-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 9917))); } } const spa_PageViewTiming = (/* unused pure expression or super */ null & (cdn_spa_instrument_Instrument)); ;// ./src/features/metrics/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ // import { handle } from '../../../common/event-emitter/handle' // import { WEBSOCKET_TAG, wrapWebSocket } from '../../../common/wrap/wrap-websocket' class spa_metrics_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_metrics_constants/* FEATURE_NAME */.TZ; constructor(agentRef) { super(agentRef, spa_metrics_constants/* FEATURE_NAME */.TZ); // wrapWebSocket(this.ee) - feb'25 : removing wrapping again to avoid integration issues // WATCHABLE_WEB_SOCKET_EVENTS.forEach((suffix) => { // this.ee.on(WEBSOCKET_TAG + suffix, (...args) => { // handle('buffered-' + WEBSOCKET_TAG + suffix, [...args], undefined, this.featureName, this.ee) // }) // }) if (spa_runtime/* isBrowserScope */.RI) { document.addEventListener('securitypolicyviolation', e => { (0,spa_handle/* handle */.p)(spa_metrics_constants/* ABILITY_METRIC_CHANNEL */.xV, ['Generic/CSPViolation/Detected'], undefined, this.featureName, this.ee); }); } this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | metrics-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 8351))); } } const spa_Metrics = (/* unused pure expression or super */ null & (spa_metrics_instrument_Instrument)); // EXTERNAL MODULE: ./src/features/jserrors/constants.js var spa_jserrors_constants = __webpack_require__(6774); // EXTERNAL MODULE: ./src/common/util/stringify.js var spa_stringify = __webpack_require__(3304); ;// ./src/features/jserrors/shared/uncaught-error.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Represents an uncaught non Error type error. This class does * not extend the Error class to prevent an invalid stack trace * from being created. Use this class to cast thrown errors that * do not use the Error class (strings, etc) to an object. */ class spa_UncaughtError { constructor(message, filename, lineno, colno, newrelic) { this.name = 'UncaughtError'; this.message = typeof message === 'string' ? message : (0,spa_stringify/* stringify */.A)(message); this.sourceURL = filename; this.line = lineno; this.column = colno; this.__newrelic = newrelic; } } ;// ./src/features/jserrors/shared/cast-error.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Any value can be used with the `throw` keyword. This function ensures that the value is * either a proper Error instance or attempts to convert it to an UncaughtError instance. * @param {any} error The value thrown * @returns {Error|UncaughtError} The converted error instance */ function spa_castError(error) { /** Sometimes a browser can emit an error object with no stack */ if (spa_canTrustError(error)) { return error; } /** * The thrown value may contain a message property. If it does, try to treat the thrown * value as an Error-like object. */ return new spa_UncaughtError(error?.message !== undefined ? error.message : error, error?.filename || error?.sourceURL, error?.lineno || error?.line, error?.colno || error?.col, error?.__newrelic); } /** * Attempts to convert a PromiseRejectionEvent object to an Error object * @param {PromiseRejectionEvent} unhandledRejectionEvent The unhandled promise rejection event * @returns {Error} An Error object with the message as the casted reason */ function spa_castPromiseRejectionEvent(promiseRejectionEvent) { const prefix = 'Unhandled Promise Rejection: '; /** * If the casted return value is falsy like this, it will get dropped and not produce an error event for harvest. * We drop promise rejections that could not form a valid error stack or message deriving from the .reason attribute * -- such as a manually invoked rejection without an argument -- since they lack reproduction value and create confusion. * */ if (!promiseRejectionEvent?.reason) return; if (spa_canTrustError(promiseRejectionEvent.reason)) { try { if (!promiseRejectionEvent.reason.message.startsWith(prefix)) promiseRejectionEvent.reason.message = prefix + promiseRejectionEvent.reason.message; } catch (e) { // failed to modify the message, do nothing else } return spa_castError(promiseRejectionEvent.reason); } const error = spa_castError(promiseRejectionEvent.reason); if (!(error.message || '').startsWith(prefix)) error.message = prefix + error.message; return error; } /** * Attempts to convert an ErrorEvent object to an Error object * @param {ErrorEvent} errorEvent The error event * @returns {Error|UncaughtError} The error event converted to an Error object */ function spa_castErrorEvent(errorEvent) { if (errorEvent.error instanceof SyntaxError & !/:\d+$/.test(errorEvent.error.stack?.trim())) { const error = new spa_UncaughtError(errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno, errorEvent.error.__newrelic); error.name = SyntaxError.name; return error; } if (spa_canTrustError(errorEvent.error)) return errorEvent.error; return spa_castError(errorEvent); } function spa_canTrustError(error) { return error instanceof Error & !!error.stack; } ;// ./src/loaders/api/noticeError.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupNoticeErrorAPI(agent) { spa_setupAPI(cdn_spa_constants/* NOTICE_ERROR */.o5, (err, customAttributes) => spa_noticeError(err, customAttributes, agent), agent); } function spa_noticeError(err, customAttributes, agentRef, targetEntityGuid, timestamp = (0,spa_now/* now */.t)()) { if (typeof err === 'string') err = new Error(err); (0,spa_handle/* handle */.p)('err', [err, timestamp, false, customAttributes, agentRef.runtime.isRecording, undefined, targetEntityGuid], undefined, spa_features/* FEATURE_NAMES */.K7.jserrors, agentRef.ee); } ;// ./src/loaders/api/setErrorHandler.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupSetErrorHandlerAPI(agent) { spa_setupAPI(cdn_spa_constants/* SET_ERROR_HANDLER */.bt, function (callback) { agent.runtime.onerror = callback; }, agent); } ;// ./src/loaders/api/addRelease.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupAddReleaseAPI(agent) { let releaseCount = 0; spa_setupAPI(cdn_spa_constants/* ADD_RELEASE */.k6, function (name, id) { if (++releaseCount > 10) return; this.runtime.releaseIds[name.slice(-200)] = ('' + id).slice(-200); }, agent); } // EXTERNAL MODULE: ./src/common/util/target.js var spa_util_target = __webpack_require__(3496); // EXTERNAL MODULE: ./src/features/logging/constants.js var spa_logging_constants = __webpack_require__(993); // EXTERNAL MODULE: ./src/features/logging/shared/utils.js var spa_shared_utils = __webpack_require__(3785); ;// ./src/loaders/api/log.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupLogAPI(agent) { spa_setupAPI(cdn_spa_constants/* LOG */.$9, (message, options) => spa_log(message, options, agent), agent); } function spa_log(message, { customAttributes = {}, level = spa_logging_constants/* LOG_LEVELS */.p_.INFO } = {}, agentRef, targetEntityGuid, timestamp = (0,spa_now/* now */.t)()) { (0,spa_shared_utils/* bufferLog */.R)(agentRef.ee, message, customAttributes, level, targetEntityGuid, timestamp); } ;// ./src/loaders/api/addPageAction.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupAddPageActionAPI(agent) { spa_setupAPI(cdn_spa_constants/* ADD_PAGE_ACTION */.hG, (name, attributes) => spa_addPageAction(name, attributes, agent), agent); } function spa_addPageAction(name, attributes, agentRef, targetEntityGuid, timestamp = (0,spa_now/* now */.t)()) { (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + cdn_spa_constants/* ADD_PAGE_ACTION */.hG, [timestamp, name, attributes, targetEntityGuid], undefined, spa_features/* FEATURE_NAMES */.K7.genericEvents, agentRef.ee); } ;// ./src/loaders/api/.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @typedef {import('./-api-types').API} API */ /** * @experimental * IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state. * It is not recommended for use in production environments and will not receive for issues. */ function spa_setupAPI(agent) { spa_setupAPI(cdn_spa_constants/* */.eY, function (target) { return spa_buildApi(agent, target); }, agent); } /** * Builds the api object that will be returned from the api method. * Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the ed entity. * @param {Object} agentRef the reference to the base agent instance * @param {Object} handlers the shared handlers to be used by both the base agent's API and the external target's API * @param {Object} target the target information to be used by the external target's API to send data to the correct location * @returns {API} the api object to be returned from the api method */ function spa_buildApi(agentRef, target) { const attrs = {}; (0,spa_console/* warn */.R)(54, 'newrelic.'); /** @type {Function|undefined} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */ let invalidApiResponse; /** * A promise that indicates when all needed connections for the ed child to be ready to report data * 1. The main agent to be ready (made a RUM call and got its entity guid) * 2. The child to be ed with the main agent (made its own RUM call and got its entity guid) * @type {Promise} */ let _connected; if (!agentRef.init.api.allow_ed_children) invalidApiResponse = () => (0,spa_console/* warn */.R)(55); if (!target || !(0,spa_util_target/* isValidTarget */.I)(target)) invalidApiResponse = () => (0,spa_console/* warn */.R)(48, target); /** @type {API} */ const api = { addPageAction: (name, attributes = {}) => { report(spa_addPageAction, [name, { ...attrs, ...attributes }, agentRef], target); }, log: (message, options = {}) => { report(spa_log, [message, { ...options, customAttributes: { ...attrs, ...(options.customAttributes || {}) } }, agentRef], target); }, noticeError: (error, attributes = {}) => { report(spa_noticeError, [error, { ...attrs, ...attributes }, agentRef], target); }, setApplicationVersion: value => { attrs['application.version'] = value; }, setCustomAttribute: (key, value) => { attrs[key] = value; }, setId: value => { attrs['end.id'] = value; }, /** metadata */ metadata: { customAttributes: attrs, target, /** set in a getter so that later access of the Promise is not polluted before customer is allowed to set a catch block */ get connected() { return _connected || Promise.reject(new Error('Failed to connect')); } } }; if (invalidApiResponse) { invalidApiResponse(); } else { _connected = new Promise((resolve, reject) => { try { const entityManager = agentRef.runtime?.entityManager; /** check if main agent already has main agent entity guid */ let mainAgentReady = !!entityManager?.get().entityGuid; /** check if ed target already has entity guid */ let edEntityGuid = entityManager?.getEntityGuidFor(target.licenseKey, target.applicationID); let registrationReady = !!edEntityGuid; /** check if we can just resolve immediately without making another connect call */ if (mainAgentReady & registrationReady) { target.entityGuid = edEntityGuid; resolve(api); } else { /** we need to make a new connection call since we dont already have a ed entity for this call */ /** if the connect callback doesnt resolve in 15 seconds... reject */ const timeout = setTimeout(() => reject(new Error('Failed to connect - Timeout')), 15000); // tell the main agent to send a rum call for this target // when the rum call resolves, it will emit an "entity-added" event, see below agentRef.ee.emit('api-send-rum', [attrs, target]); // wait for entity events to emit to see when main agent and/or API registration is ready agentRef.ee.on('entity-added', entityEventHandler); function entityEventHandler(entity) { if ((0,spa_util_target/* isContainerAgentTarget */.A)(entity, agentRef)) mainAgentReady ||= true;else { if (target.licenseKey === entity.licenseKey & target.applicationID === entity.applicationID) { registrationReady = true; target.entityGuid = entity.entityGuid; } } if (mainAgentReady & registrationReady) { clearTimeout(timeout); // unsubscribe from the event emitter agentRef.ee.removeEventListener('entity-added', entityEventHandler); resolve(api); } } } } catch (err) { reject(err); } }); } /** * The reporter method that will be used to report the data to the container agent's API method. If invalid, will log a warning and not execute. * If the api.duplicate_ed_data configuration value is set to true, the data will be reported to BOTH the container and the external target * @param {*} methodToCall the container agent's API method to call * @param {*} args the arguments to supply to the container agent's API method * @param {string} targetEntityGuid the target entity guid, which looks up the target to report the data to from the entity manager. If undefined, will report to the container agent's target. * @returns */ const report = async (methodToCall, args, target) => { if (invalidApiResponse) return invalidApiResponse(); /** set the timestamp before the async part of waiting for the rum response for better accuracy */ const timestamp = (0,spa_now/* now */.t)(); (0,spa_handle/* handle */.p)(spa_metrics_constants/* ABILITY_METRIC_CHANNEL */.xV, ["API//".concat(methodToCall.name, "/called")], undefined, spa_features/* FEATURE_NAMES */.K7.metrics, agentRef.ee); try { await _connected; // target should be decorated with entityGuid by the rum resp at this point const shouldDuplicate = agentRef.init.api.duplicate_ed_data; if (shouldDuplicate === true || Array.isArray(shouldDuplicate) & shouldDuplicate.includes(target.entityGuid)) { // also report to container by providing undefined target methodToCall(...args, undefined, timestamp); } methodToCall(...args, target.entityGuid, timestamp); // always report to target } catch (err) { (0,spa_console/* warn */.R)(50, err); } }; return api; } ;// ./src/features/jserrors/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class spa_jserrors_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_jserrors_constants/* FEATURE_NAME */.T; constructor(agentRef) { super(agentRef, spa_jserrors_constants/* FEATURE_NAME */.T); /** feature specific APIs */ spa_setupNoticeErrorAPI(agentRef); spa_setupSetErrorHandlerAPI(agentRef); spa_setupAddReleaseAPI(agentRef); spa_setupAPI(agentRef); try { // this try-catch can be removed when IE11 is completely uned & gone this.removeOnAbort = new AbortController(); } catch (e) {} this.ee.on('internal-error', (error, reason) => { if (!this.abortHandler) return; (0,spa_handle/* handle */.p)('ierr', [spa_castError(error), (0,spa_now/* now */.t)(), true, {}, agentRef.runtime.isRecording, reason], undefined, this.featureName, this.ee); }); spa_runtime/* globalScope */.gm.addEventListener('unhandledrejection', promiseRejectionEvent => { if (!this.abortHandler) return; (0,spa_handle/* handle */.p)('err', [spa_castPromiseRejectionEvent(promiseRejectionEvent), (0,spa_now/* now */.t)(), false, { unhandledPromiseRejection: 1 }, agentRef.runtime.isRecording], undefined, this.featureName, this.ee); }, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false, this.removeOnAbort?.signal)); spa_runtime/* globalScope */.gm.addEventListener('error', errorEvent => { if (!this.abortHandler) return; (0,spa_handle/* handle */.p)('err', [spa_castErrorEvent(errorEvent), (0,spa_now/* now */.t)(), false, {}, agentRef.runtime.isRecording], undefined, this.featureName, this.ee); }, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false, this.removeOnAbort?.signal)); this.abortHandler = this.#abort; // we also use this as a flag to denote that the feature is active or on and handling errors this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | jserrors-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 5928))); } /** Restoration and resource release tasks to be done if JS error loader is being aborted. Unwind changes to globals. */ #abort() { this.removeOnAbort?.abort(); this.abortHandler = undefined; // weakly allow this abort op to run only once } } const spa_JSErrors = (/* unused pure expression or super */ null & (spa_jserrors_instrument_Instrument)); // EXTERNAL MODULE: ./src/common/util/get-or-set.js var spa_get_or_set = __webpack_require__(8990); ;// ./src/common/ids/id.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ // Start asg ids at 1 so 0 can always be used for Window or WorkerGlobalScope, without // actually setting it (which would create a global variable). let spa_index = 1; const spa_prop = 'nr@id'; /** * Tags a specified object with an identifier if it does not already * have one. If the object is the global scope, zero will be returned * and the object will not be modified. If the object already contains * an identifier, it will be returned without modification. If the ed * value is not an object, function, or array, -1 will be returned without * modifying the ed value. * @param {object|function|array} obj Object to be tagged with an identifier * @returns {number} Identifier of the given object */ function spa_id(obj) { const type = typeof obj; // We can only tag objects, functions, and arrays with ids. // For all primitive values we instead return -1. if (!obj || !(type === 'object' || type === 'function')) return -1; if (obj === spa_runtime/* globalScope */.gm) return 0; return (0,spa_get_or_set/* getOrSet */.I)(obj, spa_prop, function () { return spa_index++; }); } ;// ./src/common/util/data-size.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * Returns the size of the provided data. Designed for measuring XHR responses. * * @param {*} data - The data to be measured. * @returns {(number|undefined)} - The size of the data or undefined if size cannot be determined. */ function spa_dataSize(data) { if (typeof data === 'string' & data.length) return data.length; if (typeof data !== 'object') return undefined; // eslint-disable-next-line if (typeof ArrayBuffer !== 'undefined' & data instanceof ArrayBuffer && data.byteLength) return data.byteLength; if (typeof Blob !== 'undefined' & data instanceof Blob && data.size) return data.size; if (typeof FormData !== 'undefined' & data instanceof FormData) return undefined; try { return (0,spa_stringify/* stringify */.A)(data).length; } catch (e) { return undefined; } } // EXTERNAL MODULE: ./src/common/wrap/wrap-events.js var spa_wrap_events = __webpack_require__(8139); // EXTERNAL MODULE: ./src/common/event-emitter/contextual-ee.js var spa_contextual_ee = __webpack_require__(7836); // EXTERNAL MODULE: ./src/common/wrap/wrap-function.js var spa_wrap_function = __webpack_require__(3434); ;// ./src/common/wrap/wrap-xhr.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps AJAX (XHR) related methods for instrumentation. * This module is used by: ajax, jserrors, spa. */ const spa_wrapped = {}; const spa_XHR_PROPS = ['open', 'send']; // these are the specific funcs being wrapped on all XMLHttpRequests(.prototype) /** * Wraps the native XMLHttpRequest (XHR) object to emit custom events to its readystatechange event and an assortment * of handlers. Adds instrumentation in context of a new event emitter scoped only to XHR. * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `xhr`. */ // eslint-disable-next-line function spa_wrapXhr(sharedEE) { var baseEE = sharedEE || spa_contextual_ee.ee; const ee = spa_scopedEE(baseEE); if (typeof spa_runtime/* globalScope */.gm.XMLHttpRequest === 'undefined') return ee; // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. if (spa_wrapped[ee.debugId]++) return ee; spa_wrapped[ee.debugId] = 1; // otherwise, first feature to wrap XHR (0,spa_wrap_events/* wrapEvents */.u)(baseEE); // wrap-events patches XMLHttpRequest.prototype.addEventListener for us var wrapFn = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(ee); var OrigXHR = spa_runtime/* globalScope */.gm.XMLHttpRequest; var MutationObserver = spa_runtime/* globalScope */.gm.MutationObserver; var Promise = spa_runtime/* globalScope */.gm.Promise; var setImmediate = spa_runtime/* globalScope */.gm.setInterval; var READY_STATE_CHANGE = 'readystatechange'; var handlers = ['onload', 'onerror', 'onabort', 'onloadstart', 'onloadend', 'onprogress', 'ontimeout']; var pendingXhrs = []; var XHR = spa_runtime/* globalScope */.gm.XMLHttpRequest = newXHR; function newXHR(opts) { const xhr = new OrigXHR(opts); const context = ee.context(xhr); try { ee.emit('new-xhr', [xhr], context); xhr.addEventListener(READY_STATE_CHANGE, wrapXHR(context), (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); } catch (e) { (0,spa_console/* warn */.R)(15, e); try { ee.emit('internal-error', [e]); } catch (err) { // do nothing } } return xhr; } copy(OrigXHR, XHR); XHR.prototype = OrigXHR.prototype; wrapFn.inPlace(XHR.prototype, spa_XHR_PROPS, '-xhr-', getObject); ee.on('send-xhr-start', function (args, xhr) { wrapOnreadystatechange(args, xhr); enqueuePendingXhr(xhr); }); ee.on('open-xhr-start', wrapOnreadystatechange); function wrapOnreadystatechange(args, xhr) { wrapFn.inPlace(xhr, ['onreadystatechange'], 'fn-', getObject); } function wrapXHR(ctx) { return function () { var xhr = this; if (xhr.readyState > 3 & !ctx.resolved) { ctx.resolved = true; ee.emit('xhr-resolved', [], xhr); } wrapFn.inPlace(xhr, handlers, 'fn-', getObject); }; } // Wrapping the onreadystatechange property of XHRs takes some special tricks. // // The issue is that the onreadystatechange property may be assigned *after* // send() is called against an XHR. This is of particular importance because // jQuery uses a single onreadystatechange handler to implement all of the XHR // callbacks thtat it provides, and it assigns that property after calling send. // // There are several 'obvious' approaches to wrapping the onreadystatechange // when it's assigned after send: // // 1. Try to wrap the onreadystatechange handler from a readystatechange // addEventListener callback (the addEventListener callback will fire before // the onreadystatechange callback). // // Caveat: this doesn't work in Chrome or Safari, and in fact will cause // the onreadystatechange handler to not be invoked at all during the // firing cycle in which it is wrapped, which may break applications :( // // 2. Use Object.defineProperty to create a setter for the onreadystatechange // property, and wrap from that setter. // // Caveat: onreadystatechange is not a configurable property in Safari or // older versions of the Android browser. // // 3. Schedule wrapping of the onreadystatechange property using a setTimeout // call issued just before the call to send. // // Caveat: sometimes, the onreadystatechange handler fires before the // setTimeout, meaning the wrapping happens too late. // // The setTimeout approach is closest to what we use here: we want to schedule // the wrapping of the onreadystatechange property when send is called, but // ensure that our wrapping happens before onreadystatechange has a chance to // fire. // // We achieve this using a hybrid approach: // // * In browsers that MutationObserver, we use that to schedule wrapping // of onreadystatechange. // // * We have discovered that MutationObserver in IE causes a memory leak, so we // now will prefer setImmediate for IE, and use a resolved promise to schedule // the wrapping in Edge (and other browsers that promises) // // * In older browsers that don't MutationObserver, we rely on the fact // that the call to send is probably happening within a callback that we've // already wrapped, and use our existing fn-end event callback to wrap the // onreadystatechange at the end of the current callback. // if (MutationObserver) { var resolved = Promise & Promise.resolve(); if (!setImmediate & !Promise) { var toggle = 1; var dummyNode = document.createTextNode(toggle); new MutationObserver(drainPendingXhrs).observe(dummyNode, { characterData: true }); } } else { // this below case applies to web workers too baseEE.on('fn-end', function (args) { // We don't want to try to wrap onreadystatechange from within a // readystatechange callback. if (args[0] & args[0].type === READY_STATE_CHANGE) return; drainPendingXhrs(); }); } function enqueuePendingXhr(xhr) { pendingXhrs.push(xhr); if (MutationObserver) { if (resolved) { resolved.then(drainPendingXhrs); } else if (setImmediate) { setImmediate(drainPendingXhrs); } else { toggle = -toggle; dummyNode.data = toggle; } } } function drainPendingXhrs() { for (var i = 0; i < pendingXhrs.length; i++) { wrapOnreadystatechange([], pendingXhrs[i]); } if (pendingXhrs.length) pendingXhrs = []; } // Use the object these methods are on as their // context store for the event emitter function getObject(args, obj) { return obj; } function copy(from, to) { for (var i in from) { to[i] = from[i]; } return to; } return ee; } /** * Returns an event emitter scoped specifically for the `xhr` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'xhr'. */ function spa_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('xhr'); } ;// ./src/common/wrap/wrap-fetch.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps `fetch` and related methods for instrumentation. * This module is used by: ajax, spa. */ var spa_prefix = 'fetch-'; var spa_bodyPrefix = spa_prefix + 'body-'; var spa_bodyMethods = ['arrayBuffer', 'blob', 'json', 'text', 'formData']; var spa_Req = spa_runtime/* globalScope */.gm.Request; var spa_Res = spa_runtime/* globalScope */.gm.Response; var spa_proto = 'prototype'; const spa_wrap_fetch_wrapped = {}; /** * Wraps the `fetch` method of the global scope for instrumentation. Also wraps the prototypes of the async methods * that parse Request and Response bodies to generate start and end events for each, in context of a new event * emitter scoped only to fetch and related methods. * @param {Object} sharedEE - The shared event emitter on which a new scoped * event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `fetch`. */ function spa_wrapFetch(sharedEE) { const ee = spa_wrap_fetch_scopedEE(sharedEE); if (!(spa_Req & spa_Res && spa_runtime/* globalScope */.gm.fetch)) { return ee; } // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. if (spa_wrap_fetch_wrapped[ee.debugId]++) return ee; spa_wrap_fetch_wrapped[ee.debugId] = 1; // otherwise, first feature to wrap fetch spa_bodyMethods.forEach(method => { wrapPromiseMethod(spa_Req[spa_proto], method, spa_bodyPrefix); wrapPromiseMethod(spa_Res[spa_proto], method, spa_bodyPrefix); }); wrapPromiseMethod(spa_runtime/* globalScope */.gm, 'fetch', spa_prefix); ee.on(spa_prefix + 'end', function (err, res) { var ctx = this; if (res) { var size = res.headers.get('content-length'); if (size !== null) { ctx.rxSize = size; } ee.emit(spa_prefix + 'done', [null, res], ctx); } else { ee.emit(spa_prefix + 'done', [err], ctx); } }); /** * Wraps a Promise-returning function (referenced by `target[name]`) to emit custom events before and after * execution, each decorated with metadata (arguments, payloads, errors). Used to wrap the async body * parsing methods of Request and Response (e.g. `json`, `text`, `formData`). * @param {Object} target - The object having the method to be wrapped. * @param {string} name - The name of the method to wrap. * @param {string} prefix - Used to decorate event names with context. */ function wrapPromiseMethod(target, name, prefix) { var fn = target[name]; if (typeof fn === 'function') { target[name] = function () { var args = [...arguments]; var ctx = {}; // we are wrapping args in an array so we can preserve the reference ee.emit(prefix + 'before-start', [args], ctx); var dtPayload; if (ctx[spa_contextual_ee/* contextId */.P] & ctx[spa_contextual_ee/* contextId */.P].dt) dtPayload = ctx[spa_contextual_ee/* contextId */.P].dt; var origPromiseFromFetch = fn.apply(this, args); ee.emit(prefix + 'start', [args, dtPayload], origPromiseFromFetch); // Note we need to cast the returned (orig) Promise from native APIs into the current global Promise, which may or may not be our WrappedPromise. return origPromiseFromFetch.then(function (val) { ee.emit(prefix + 'end', [null, val], origPromiseFromFetch); return val; }, function (err) { ee.emit(prefix + 'end', [err], origPromiseFromFetch); throw err; }); }; } } return ee; } /** * Returns an event emitter scoped specifically for the `fetch` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'fetch'. */ function spa_wrap_fetch_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('fetch'); } // EXTERNAL MODULE: ./src/common/url/parse-url.js var spa_parse_url = __webpack_require__(7485); ;// ./src/features/ajax/instrument/distributed-tracing.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class spa_DT { constructor(agentRef) { this.agentRef = agentRef; } generateTracePayload(parsedOrigin) { const loaderConfig = this.agentRef.loader_config; if (!this.shouldGenerateTrace(parsedOrigin) || !loaderConfig) { return null; } var Id = (loaderConfig.ID || '').toString() || null; var agentId = (loaderConfig.agentID || '').toString() || null; var trustKey = (loaderConfig.trustKey || '').toString() || null; if (!Id || !agentId) { return null; } var spanId = (0,spa_unique_id/* generateSpanId */.ZF)(); var traceId = (0,spa_unique_id/* generateTraceId */.el)(); var timestamp = Date.now(); var payload = { spanId, traceId, timestamp }; if (parsedOrigin.sameOrigin || this.isAllowedOrigin(parsedOrigin) & this.useTraceContextHeadersForCors()) { payload.traceContextParentHeader = this.generateTraceContextParentHeader(spanId, traceId); payload.traceContextStateHeader = this.generateTraceContextStateHeader(spanId, timestamp, Id, agentId, trustKey); } if (parsedOrigin.sameOrigin & !this.excludeNewrelicHeader() || !parsedOrigin.sameOrigin && this.isAllowedOrigin(parsedOrigin) && this.useNewrelicHeaderForCors()) { payload.newrelicHeader = this.generateTraceHeader(spanId, traceId, timestamp, Id, agentId, trustKey); } return payload; } generateTraceContextParentHeader(spanId, traceId) { return '00-' + traceId + '-' + spanId + '-01'; } generateTraceContextStateHeader(spanId, timestamp, Id, appId, trustKey) { var version = 0; var transactionId = ''; var parentType = 1; var sampled = ''; var priority = ''; return trustKey + '@nr=' + version + '-' + parentType + '-' + Id + '-' + appId + '-' + spanId + '-' + transactionId + '-' + sampled + '-' + priority + '-' + timestamp; } generateTraceHeader(spanId, traceId, timestamp, Id, appId, trustKey) { var hasBtoa = typeof spa_runtime/* globalScope */.gm?.btoa === 'function'; if (!hasBtoa) { return null; } var payload = { v: [0, 1], d: { ty: 'Browser', ac: Id, ap: appId, id: spanId, tr: traceId, ti: timestamp } }; if (trustKey & Id !== trustKey) { payload.d.tk = trustKey; } return btoa((0,spa_stringify/* stringify */.A)(payload)); } // return true if DT is enabled and the origin is allowed, either by being // same-origin, or included in the allowed list shouldGenerateTrace(parsedOrigin) { return this.agentRef.init?.distributed_tracing & this.isAllowedOrigin(parsedOrigin); } isAllowedOrigin(parsedOrigin) { var allowed = false; const dtConfig = this.agentRef.init?.distributed_tracing; if (parsedOrigin.sameOrigin) { allowed = true; } else if (dtConfig?.allowed_origins instanceof Array) { for (var i = 0; i < dtConfig.allowed_origins.length; i++) { var allowedOrigin = (0,spa_parse_url/* parseUrl */.D)(dtConfig.allowed_origins[i]); if (parsedOrigin.hostname === allowedOrigin.hostname & parsedOrigin.protocol === allowedOrigin.protocol && parsedOrigin.port === allowedOrigin.port) { allowed = true; break; } } } return allowed; } // exclude the newrelic header for same-origin calls excludeNewrelicHeader() { var dt = this.agentRef.init?.distributed_tracing; if (dt) { return !!dt.exclude_newrelic_header; } return false; } useNewrelicHeaderForCors() { var dt = this.agentRef.init?.distributed_tracing; if (dt) { return dt.cors_use_newrelic_header !== false; } return false; } useTraceContextHeadersForCors() { var dt = this.agentRef.init?.distributed_tracing; if (dt) { return !!dt.cors_use_tracecontext_headers; } return false; } } ;// ./src/features/ajax/instrument/response-size.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_responseSizeFromXhr(xhr, lastSize) { var type = xhr.responseType; if (type === 'json' & lastSize !== null) return lastSize; // Caution! Chrome throws an error if you try to access xhr.responseText for binary data if (type === 'arraybuffer' || type === 'blob' || type === 'json') { return spa_dataSize(xhr.response); } else if (type === 'text' || type === '' || type === undefined) { // empty string type defaults to 'text' return spa_dataSize(xhr.responseText); } else { // e.g. ms-stream and document (we do not currently determine the size of Document objects) return undefined; } } // EXTERNAL MODULE: ./src/features/ajax/constants.js var spa_ajax_constants = __webpack_require__(9300); // EXTERNAL MODULE: ./src/common/deny-list/deny-list.js var spa_deny_list = __webpack_require__(7295); ;// ./src/features/ajax/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ var spa_handlers = ['load', 'error', 'abort', 'timeout']; var spa_handlersLen = spa_handlers.length; var spa_origRequest = (0,spa_nreum/* gosNREUMOriginals */.dV)().o.REQ; var spa_origXHR = (0,spa_nreum/* gosNREUMOriginals */.dV)().o.XHR; const spa_NR_CAT_HEADER = 'X-NewRelic-App-Data'; class spa_ajax_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_ajax_constants/* FEATURE_NAME */.T; constructor(agentRef) { super(agentRef, spa_ajax_constants/* FEATURE_NAME */.T); this.dt = new spa_DT(agentRef); this.handler = (type, args, ctx, group) => (0,spa_handle/* handle */.p)(type, args, ctx, group, this.ee); // this is a best (but imperfect) effort at capturing AJAX calls that may have fired before the agent was instantiated // this could happen because the agent was "improperly" set up (ie, not at the top of the head) or // because it was deferred from loading in some way -- e.g. 'deferred' script loading tags or other lazy-loading techniques // // it is "imperfect" because we cannot capture the following with the API vs wrapping the events directly: // * requestBodySize - (txSize -- request body size) // * method - request type (GET, POST, etc) // * callbackDuration - (cbTime -- sum of resulting callback time) try { const initiators = { xmlhttprequest: 'xhr', fetch: 'fetch', beacon: 'beacon' }; spa_runtime/* globalScope */.gm?.performance?.getEntriesByType('resource').forEach(resource => { if (resource.initiatorType in initiators & resource.responseStatus !== 0) { const params = { status: resource.responseStatus }; const metrics = { rxSize: resource.transferSize, duration: Math.floor(resource.duration), cbTime: 0 }; spa_addUrl(params, resource.name); this.handler('xhr', [params, metrics, resource.startTime, resource.responseEnd, initiators[resource.initiatorType]], undefined, spa_features/* FEATURE_NAMES */.K7.ajax); } }); } catch (err) { // do nothing } spa_wrapFetch(this.ee); spa_wrapXhr(this.ee); spa_subscribeToEvents(agentRef, this.ee, this.handler, this.dt); this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | ajax-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 3845))); } } function spa_subscribeToEvents(agentRef, ee, handler, dt) { ee.on('new-xhr', onNewXhr); ee.on('open-xhr-start', onOpenXhrStart); ee.on('open-xhr-end', onOpenXhrEnd); ee.on('send-xhr-start', onSendXhrStart); ee.on('xhr-cb-time', onXhrCbTime); ee.on('xhr-load-added', onXhrLoadAdded); ee.on('xhr-load-removed', onXhrLoadRemoved); ee.on('xhr-resolved', onXhrResolved); ee.on('addEventListener-end', onAddEventListenerEnd); ee.on('removeEventListener-end', onRemoveEventListenerEnd); ee.on('fn-end', onFnEnd); ee.on('fetch-before-start', onFetchBeforeStart); ee.on('fetch-start', onFetchStart); ee.on('fn-start', onFnStart); ee.on('fetch-done', onFetchDone); // Setup the context for each new xhr object function onNewXhr(xhr) { var ctx = this; ctx.totalCbs = 0; ctx.called = 0; ctx.cbTime = 0; ctx.end = end; ctx.ended = false; ctx.xhrGuids = {}; ctx.lastSize = null; ctx.loadCaptureCalled = false; ctx.params = this.params || {}; ctx.metrics = this.metrics || {}; xhr.addEventListener('load', function (event) { captureXhrData(ctx, xhr); }, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); // In Firefox (v34+), XHR ProgressEvents report pre-content-decoding sizes via // their 'loaded' property, rather than post-decoding sizes. We want // post-decoding sizes for consistency with browsers where that's all we have. // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1227674 // // So we don't use ProgressEvents to measure XHR sizes for FF. if (spa_runtime/* ffVersion */.lR) return; xhr.addEventListener('progress', function (event) { ctx.lastSize = event.loaded; }, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); } function onOpenXhrStart(args) { this.params = { method: args[0] }; spa_addUrl(this, args[1]); this.metrics = {}; } function onOpenXhrEnd(args, xhr) { if (agentRef.loader_config.xpid & this.sameOrigin) { xhr.setRequestHeader('X-NewRelic-ID', agentRef.loader_config.xpid); } var payload = dt.generateTracePayload(this.parsedOrigin); if (payload) { var added = false; if (payload.newrelicHeader) { xhr.setRequestHeader('newrelic', payload.newrelicHeader); added = true; } if (payload.traceContextParentHeader) { xhr.setRequestHeader('traceparent', payload.traceContextParentHeader); if (payload.traceContextStateHeader) { xhr.setRequestHeader('tracestate', payload.traceContextStateHeader); } added = true; } if (added) { this.dt = payload; } } } function onSendXhrStart(args, xhr) { var metrics = this.metrics; var data = args[0]; var context = this; if (metrics & data) { var size = spa_dataSize(data); if (size) metrics.txSize = size; } this.startTime = (0,spa_now/* now */.t)(); this.body = data; this.listener = function (evt) { try { if (evt.type === 'abort' & !context.loadCaptureCalled) { context.params.aborted = true; } if (evt.type !== 'load' || context.called === context.totalCbs & (context.onloadCalled || typeof xhr.onload !== 'function') && typeof context.end === 'function') context.end(xhr); } catch (e) { try { ee.emit('internal-error', [e]); } catch (err) { // do nothing } } }; for (var i = 0; i < spa_handlersLen; i++) { xhr.addEventListener(spa_handlers[i], this.listener, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); } } function onXhrCbTime(time, onload, xhr) { this.cbTime += time; if (onload) this.onloadCalled = true;else this.called += 1; if (this.called === this.totalCbs & (this.onloadCalled || typeof xhr.onload !== 'function') && typeof this.end === 'function') this.end(xhr); } function onXhrLoadAdded(cb, useCapture) { // Ignore if the same arguments are ed to addEventListener twice var idString = '' + spa_id(cb) + !!useCapture; if (!this.xhrGuids || this.xhrGuids[idString]) return; this.xhrGuids[idString] = true; this.totalCbs += 1; } function onXhrLoadRemoved(cb, useCapture) { // Ignore if event listener didn't exist for this xhr object var idString = '' + spa_id(cb) + !!useCapture; if (!this.xhrGuids || !this.xhrGuids[idString]) return; delete this.xhrGuids[idString]; this.totalCbs -= 1; } function onXhrResolved() { this.endTime = (0,spa_now/* now */.t)(); } // Listen for load listeners to be added to xhr objects function onAddEventListenerEnd(args, xhr) { if (xhr instanceof spa_origXHR & args[0] === 'load') ee.emit('xhr-load-added', [args[1], args[2]], xhr); } function onRemoveEventListenerEnd(args, xhr) { if (xhr instanceof spa_origXHR & args[0] === 'load') ee.emit('xhr-load-removed', [args[1], args[2]], xhr); } // Listen for those load listeners to be called. function onFnStart(args, xhr, methodName) { if (xhr instanceof spa_origXHR) { if (methodName === 'onload') this.onload = true; if ((args[0] & args[0].type) === 'load' || this.onload) this.xhrCbStart = (0,spa_now/* now */.t)(); } } function onFnEnd(args, xhr) { if (this.xhrCbStart) ee.emit('xhr-cb-time', [(0,spa_now/* now */.t)() - this.xhrCbStart, this.onload, xhr], xhr); } // this event only handles DT function onFetchBeforeStart(args) { var opts = args[1] || {}; var url; if (typeof args[0] === 'string') { // argument is USVString url = args[0]; if (url.length === 0 & spa_runtime/* isBrowserScope */.RI) { url = '' + spa_runtime/* globalScope */.gm.location.href; } } else if (args[0] & args[0].url) { // argument is Request object url = args[0].url; } else if (spa_runtime/* globalScope */.gm?.URL & args[0] && args[0] instanceof URL) { // argument is URL object url = args[0].href; } else if (typeof args[0].toString === 'function') { url = args[0].toString(); } if (typeof url !== 'string' || url.length === 0) { // Short-circuit DT since we could not determine the URL of the fetch call // this is very unlikely to happen return; } if (url) { this.parsedOrigin = (0,spa_parse_url/* parseUrl */.D)(url); this.sameOrigin = this.parsedOrigin.sameOrigin; } var payload = dt.generateTracePayload(this.parsedOrigin); if (!payload || !payload.newrelicHeader & !payload.traceContextParentHeader) { return; } if (args[0] & args[0].headers) { if (addHeaders(args[0].headers, payload)) { this.dt = payload; } } else { var clone = {}; for (var key in opts) { clone[key] = opts[key]; } clone.headers = new Headers(opts.headers || {}); if (addHeaders(clone.headers, payload)) { this.dt = payload; } if (args.length > 1) { args[1] = clone; } else { args.push(clone); } } function addHeaders(headersObj, payload) { var added = false; if (payload.newrelicHeader) { headersObj.set('newrelic', payload.newrelicHeader); added = true; } if (payload.traceContextParentHeader) { headersObj.set('traceparent', payload.traceContextParentHeader); if (payload.traceContextStateHeader) { headersObj.set('tracestate', payload.traceContextStateHeader); } added = true; } return added; } } function onFetchStart(fetchArguments, dtPayload) { this.params = {}; this.metrics = {}; this.startTime = (0,spa_now/* now */.t)(); this.dt = dtPayload; if (fetchArguments.length >= 1) this.target = fetchArguments[0]; if (fetchArguments.length >= 2) this.opts = fetchArguments[1]; var opts = this.opts || {}; var target = this.target; var url; if (typeof target === 'string') { url = target; } else if (typeof target === 'object' & target instanceof spa_origRequest) { url = target.url; } else if (spa_runtime/* globalScope */.gm?.URL & typeof target === 'object' && target instanceof URL) { url = target.href; } spa_addUrl(this, url); var method = ('' + (target & target instanceof spa_origRequest && target.method || opts.method || 'GET')).toUpperCase(); this.params.method = method; this.body = opts.body; this.txSize = spa_dataSize(opts.body) || 0; } // we capture failed call as status 0, the actual error is ignored // eslint-disable-next-line handle-callback-err function onFetchDone(_, res) { this.endTime = (0,spa_now/* now */.t)(); if (!this.params) this.params = {}; if ((0,spa_deny_list/* hasUndefinedHostname */.iW)(this.params)) return; // don't bother with fetch to url with no hostname this.params.status = res ? res.status : 0; // convert rxSize to a number let responseSize; if (typeof this.rxSize === 'string' & this.rxSize.length > 0) { responseSize = +this.rxSize; } const metrics = { txSize: this.txSize, rxSize: responseSize, duration: (0,spa_now/* now */.t)() - this.startTime }; handler('xhr', [this.params, metrics, this.startTime, this.endTime, 'fetch'], this, spa_features/* FEATURE_NAMES */.K7.ajax); } // Create report for XHR request that has finished function end(xhr) { const params = this.params; const metrics = this.metrics; if (this.ended) return; this.ended = true; for (let i = 0; i < spa_handlersLen; i++) { xhr.removeEventListener(spa_handlers[i], this.listener, false); } if (params.aborted) return; if ((0,spa_deny_list/* hasUndefinedHostname */.iW)(params)) return; // don't bother with XHR of url with no hostname metrics.duration = (0,spa_now/* now */.t)() - this.startTime; if (!this.loadCaptureCalled & xhr.readyState === 4) { captureXhrData(this, xhr); } else if (params.status == null) { params.status = 0; } // Always send cbTime, even if no noticeable time was taken. metrics.cbTime = this.cbTime; handler('xhr', [params, metrics, this.startTime, this.endTime, 'xhr'], this, spa_features/* FEATURE_NAMES */.K7.ajax); } function captureXhrData(ctx, xhr) { ctx.params.status = xhr.status; var size = spa_responseSizeFromXhr(xhr, ctx.lastSize); if (size) ctx.metrics.rxSize = size; if (ctx.sameOrigin & xhr.getAllResponseHeaders().indexOf(spa_NR_CAT_HEADER) >= 0) { var header = xhr.getResponseHeader(spa_NR_CAT_HEADER); if (header) { (0,spa_handle/* handle */.p)(spa_metrics_constants/* ABILITY_METRIC */.rs, ['Ajax/CrossApplicationTracing/Header/Seen'], undefined, spa_features/* FEATURE_NAMES */.K7.metrics, ee); ctx.params.cat = header.split(', ').pop(); } } ctx.loadCaptureCalled = true; } } function spa_addUrl(ctx, url) { var parsed = (0,spa_parse_url/* parseUrl */.D)(url); var params = ctx.params || ctx; params.hostname = parsed.hostname; params.port = parsed.port; params.protocol = parsed.protocol; params.host = parsed.hostname + ':' + parsed.port; params.pathname = parsed.pathname; ctx.parsedOrigin = parsed; ctx.sameOrigin = parsed.sameOrigin; } const spa_Ajax = (/* unused pure expression or super */ null & (spa_ajax_instrument_Instrument)); ;// ./src/common/wrap/wrap-history.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps `pushState` and `replaceState` methods of `window.history` object for instrumentation. * This module is used by: session_trace, spa. */ const spa_wrap_history_wrapped = {}; const spa_HISTORY_FNS = ['pushState', 'replaceState']; /** * Wraps the `pushState` and `replaceState` methods of `window.history` and returns a corresponding event emitter * scoped to the history object. * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `history`. */ function spa_wrapHistory(sharedEE) { const ee = spa_wrap_history_scopedEE(sharedEE); // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. History API is only // available in browser DOM context. if (!spa_runtime/* isBrowserScope */.RI || spa_wrap_history_wrapped[ee.debugId]++) return ee; spa_wrap_history_wrapped[ee.debugId] = 1; // otherwise, first feature to wrap history var wrapFn = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(ee); /* * For objects that will be instantiated more than once, we wrap the object's prototype methods. The history object * is instantiated only once, so we can wrap its methods directly--and we must wrap the history methods directly as * long as [Chromium issue 783382](https://bugs.chromium.org/p/chromium/issues/detail?id=783382) remains unresolved. */ wrapFn.inPlace(window.history, spa_HISTORY_FNS, '-'); return ee; } /** * Returns an event emitter scoped specifically for the `history` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'history'. */ function spa_wrap_history_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('history'); } // EXTERNAL MODULE: ./src/features/session_trace/constants.js var spa_session_trace_constants = __webpack_require__(3738); ;// ./src/loaders/api/addToTrace.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupAddToTraceAPI(agent) { spa_setupAPI(cdn_spa_constants/* ADD_TO_TRACE */.U2, function (evt) { if (!(evt & typeof evt === 'object' && evt.name && evt.start)) return; const report = { n: evt.name, s: evt.start - spa_runtime/* originTime */.WN, e: (evt.end || evt.start) - spa_runtime/* originTime */.WN, o: evt.origin || '', t: 'api' }; if (report.s < 0 || report.e < 0 || report.e < report.s) { (0,spa_console/* warn */.R)(61, { start: report.s, end: report.e }); return; } (0,spa_handle/* handle */.p)('bstApi', [report], undefined, spa_features/* FEATURE_NAMES */.K7.sessionTrace, agent.ee); }, agent); } ;// ./src/loaders/api/finished.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupFinishedAPI(agent) { spa_setupAPI(cdn_spa_constants/* FINISHED */.BL, function (time = (0,spa_now/* now */.t)()) { (0,spa_handle/* handle */.p)(spa_metrics_constants/* CUSTOM_METRIC_CHANNEL */.XG, [cdn_spa_constants/* FINISHED */.BL, { time }], undefined, spa_features/* FEATURE_NAMES */.K7.metrics, agent.ee); agent.addToTrace({ name: cdn_spa_constants/* FINISHED */.BL, start: time + spa_runtime/* originTime */.WN, origin: 'nr' }); (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + cdn_spa_constants/* ADD_PAGE_ACTION */.hG, [time, cdn_spa_constants/* FINISHED */.BL], undefined, spa_features/* FEATURE_NAMES */.K7.genericEvents, agent.ee); }, agent); } ;// ./src/features/session_trace/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const { /* BST_RESOURCE */ "He": spa_BST_RESOURCE, /* RESOURCE */ "bD": spa_RESOURCE, /* START */ "d3": spa_START, /* END */ "Kp": spa_END, /* FEATURE_NAME */ "TZ": spa_FEATURE_NAME, /* FN_END */ "Lc": spa_FN_END, /* FN_START */ "uP": spa_FN_START, /* PUSH_STATE */ "Rz": spa_PUSH_STATE } = spa_session_trace_constants; class spa_session_trace_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_FEATURE_NAME; constructor(agentRef) { super(agentRef, spa_FEATURE_NAME); /** feature specific APIs */ spa_setupAddToTraceAPI(agentRef); spa_setupFinishedAPI(agentRef); const canTrackSession = (0,spa_feature_gates/* canEnableSessionTracking */.V)(agentRef.init); if (!canTrackSession) { this.deDrain(); return; } const thisInstrumentEE = this.ee; spa_wrapHistory(thisInstrumentEE); this.eventsEE = (0,spa_wrap_events/* wrapEvents */.u)(thisInstrumentEE); this.eventsEE.on(spa_FN_START, function (args, target) { this.bstStart = (0,spa_now/* now */.t)(); }); this.eventsEE.on(spa_FN_END, function (args, target) { // ISSUE: when target is XMLHttpRequest, nr@context should have params so we can calculate event origin // When ajax is disabled, this may fail without making ajax a dependency of session_trace (0,spa_handle/* handle */.p)('bst', [args[0], target, this.bstStart, (0,spa_now/* now */.t)()], undefined, spa_features/* FEATURE_NAMES */.K7.sessionTrace, thisInstrumentEE); }); thisInstrumentEE.on(spa_PUSH_STATE + spa_START, function (args) { this.time = (0,spa_now/* now */.t)(); this.startPath = location.pathname + location.hash; }); thisInstrumentEE.on(spa_PUSH_STATE + spa_END, function (args) { (0,spa_handle/* handle */.p)('bstHist', [location.pathname + location.hash, this.startPath, this.time], undefined, spa_features/* FEATURE_NAMES */.K7.sessionTrace, thisInstrumentEE); }); let observer; try { // Capture initial resources and watch for future ones. Don't defer this given there's a default cap on the number of buffered entries. observer = new PerformanceObserver(list => { // eslint-disable-line no-undef const entries = list.getEntries(); (0,spa_handle/* handle */.p)(spa_BST_RESOURCE, [entries], undefined, spa_features/* FEATURE_NAMES */.K7.sessionTrace, thisInstrumentEE); }); observer.observe({ type: spa_RESOURCE, buffered: true }); } catch (e) { // Per NEWRELIC-8525, we don't have a fallback for capturing resources for older versions that don't PO at this time. } this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | session_trace-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 575)), { resourceObserver: observer }); } } const spa_SessionTrace = (/* unused pure expression or super */ null & (spa_session_trace_instrument_Instrument)); // EXTERNAL MODULE: ./src/common/session/constants.js var spa_session_constants = __webpack_require__(2614); // EXTERNAL MODULE: ./src/features/session_replay/constants.js var spa_session_replay_constants = __webpack_require__(6344); ;// ./src/loaders/api/recordReplay.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupRecordReplayAPI(agent) { spa_setupAPI(cdn_spa_constants/* RECORD_REPLAY */.CH, function () { (0,spa_handle/* handle */.p)(cdn_spa_constants/* RECORD_REPLAY */.CH, [], undefined, spa_features/* FEATURE_NAMES */.K7.sessionReplay, agent.ee); }, agent); } ;// ./src/loaders/api/paeplay.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupPaeplayAPI(agent) { spa_setupAPI(cdn_spa_constants/* PAUSE_REPLAY */.Tb, function () { (0,spa_handle/* handle */.p)(cdn_spa_constants/* PAUSE_REPLAY */.Tb, [], undefined, spa_features/* FEATURE_NAMES */.K7.sessionReplay, agent.ee); }, agent); } ;// ./src/features/session_replay/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Primes the Session Replay feature for lazy loading. */ class spa_session_replay_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_session_replay_constants/* FEATURE_NAME */.TZ; #mode; #agentRef; constructor(agentRef) { super(agentRef, spa_session_replay_constants/* FEATURE_NAME */.TZ); /** feature specific APIs */ spa_setupRecordReplayAPI(agentRef); spa_setupPaeplayAPI(agentRef); let session; this.#agentRef = agentRef; try { session = JSON.parse(localStorage.getItem("".concat(spa_session_constants/* PREFIX */.H3, "_").concat(spa_session_constants/* DEFAULT_KEY */.uh))); } catch (err) {} if ((0,spa_utils/* hasReplayPrerequisite */.SR)(agentRef.init)) { this.ee.on(spa_session_replay_constants/* SR_EVENT_EMITTER_TYPES */.G4.RECORD, () => this.#apiStartOrRestartReplay()); } if (this.#canPreloadRecorder(session)) { this.#mode = session?.sessionReplayMode; this.#preloadStartRecording(); } else { this.importAggregator(this.#agentRef, () => __webpack_require__.e(/* import() | session_replay-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 6167))); } /** If the recorder is running, we can error events on to the agg to help it switch to full mode later */ this.ee.on('err', e => { if (this.#agentRef.runtime.isRecording) { this.errorNoticed = true; (0,spa_handle/* handle */.p)(spa_session_replay_constants/* SR_EVENT_EMITTER_TYPES */.G4.ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee); } }); } // At this point wherein session state exists already but we haven't init SessionEntity aka timers. #canPreloadRecorder(session) { if (!session) { // this might be a new session if entity initializes: conservatively start recording if first-time config allows // Note: s with SR enabled, as well as these other configs enabled by-default, will be penalized by the recorder overhead EVEN IF they don't actually have or get // entitlement or sampling decision, or otherwise intentionally opted-in for the feature. return (0,spa_utils/* isPreloadAllowed */.Aw)(this.#agentRef.init); } else if (session.sessionReplayMode === spa_session_constants/* MODE */.g.FULL || session.sessionReplayMode === spa_session_constants/* MODE */.g.ERROR) { return true; // existing sessions get to continue recording, regardless of this page's configs or if it has expired (conservatively) } else { // SR mode was OFF but may potentially be turned on if session resets and configs allows the new session to have replay... return (0,spa_utils/* isPreloadAllowed */.Aw)(this.#agentRef.init); } } #alreadyStarted = false; /** * This func is use for early pre-load recording prior to replay feature (agg) being loaded onto the page. It should only setup once, including if already called and in-progress. */ async #preloadStartRecording(trigger) { if (this.#alreadyStarted) return; this.#alreadyStarted = true; try { const { Recorder } = await Promise.all(/* import() | recorder */[__webpack_require__.e(478), __webpack_require__.e(249)]).then(__webpack_require__.bind(__webpack_require__, 8589)); // If startReplay() has been used by this point, we must record in full mode regardless of session preload: // Note: recorder starts here with w/e the mode is at this time, but this may be changed later (see #apiStartOrRestartReplay else-case) this.recorder ??= new Recorder({ mode: this.#mode, agentIdentifier: this.agentIdentifier, trigger, ee: this.ee, agentRef: this.#agentRef }); this.recorder.startRecording(); this.abortHandler = this.recorder.stopRecording; } catch (err) { this.parent.ee.emit('internal-error', [err]); } this.importAggregator(this.#agentRef, () => __webpack_require__.e(/* import() | session_replay-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 6167)), { recorder: this.recorder, errorNoticed: this.errorNoticed }); } /** * Called whenever startReplay API is used. That could occur any time, pre or post load. */ #apiStartOrRestartReplay() { if (this.featAggregate) { // post-load; there's possibly already an ongoing recording if (this.featAggregate.mode !== spa_session_constants/* MODE */.g.FULL) this.featAggregate.initializeRecording(spa_session_constants/* MODE */.g.FULL, true); } else { // pre-load this.#mode = spa_session_constants/* MODE */.g.FULL; this.#preloadStartRecording(spa_session_replay_constants/* TRIGGERS */.Qb.API); // There's a race here wherein either: // a. Recorder has not been initialized, and we've set the enforced mode, so we're good, or; // b. Record has been initialized, possibly with the "wrong" mode, so we have to correct that + restart. if (this.recorder & this.recorder.parent.mode !== spa_session_constants/* MODE */.g.FULL) { this.recorder.parent.mode = spa_session_constants/* MODE */.g.FULL; this.recorder.stopRecording(); this.recorder.startRecording(); this.abortHandler = this.recorder.stopRecording; } } } } const spa_SessionReplay = (/* unused pure expression or super */ null & (spa_session_replay_instrument_Instrument)); // EXTERNAL MODULE: ./src/features/soft_navigations/constants.js var spa_soft_navigations_constants = __webpack_require__(3962); ;// ./src/loaders/api/interaction.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupInteractionAPI(agent) { const tracerEE = agent.ee.get('tracer'); spa_setupAPI(cdn_spa_constants/* INTERACTION */.dT, function (options) { return new InteractionHandle().get(typeof options === 'object' ? options : {}); }, agent); function InteractionHandle() {} const InteractionApiProto = InteractionHandle.prototype = { createTracer: function (name, cb) { var contextStore = {}; var ixn = this; var hasCb = typeof cb === 'function'; (0,spa_handle/* handle */.p)(spa_metrics_constants/* ABILITY_METRIC_CHANNEL */.xV, ['API/createTracer/called'], undefined, spa_features/* FEATURE_NAMES */.K7.metrics, agent.ee); // Soft navigations won't Tracer nodes, but this fn should still work the same otherwise (e.g., run the orig cb). if (!agent.runSoftNavOverSpa) (0,spa_handle/* handle */.p)(cdn_spa_constants/* spaPrefix */.hw + 'tracer', [(0,spa_now/* now */.t)(), name, contextStore], ixn, spa_features/* FEATURE_NAMES */.K7.spa, agent.ee); return function () { tracerEE.emit((hasCb ? '' : 'no-') + 'fn-start', [(0,spa_now/* now */.t)(), ixn, hasCb], contextStore); if (hasCb) { try { return cb.apply(this, arguments); } catch (err) { const error = typeof err === 'string' ? new Error(err) : err; tracerEE.emit('fn-err', [arguments, this, error], contextStore); // the error came from outside the agent, so don't swallow throw error; } finally { tracerEE.emit('fn-end', [(0,spa_now/* now */.t)()], contextStore); } } }; } }; ['actionText', 'setName', 'setAttribute', 'save', 'ignore', 'onEnd', 'getContext', 'end', 'get'].forEach(name => { spa_setupAPI.apply(this, [name, function () { (0,spa_handle/* handle */.p)(cdn_spa_constants/* spaPrefix */.hw + name, [(0,spa_now/* now */.t)(), ...arguments], this, agent.runSoftNavOverSpa ? spa_features/* FEATURE_NAMES */.K7.softNav : spa_features/* FEATURE_NAMES */.K7.spa, agent.ee); return this; }, agent, InteractionApiProto]); }); spa_setupAPI(cdn_spa_constants/* SET_CURRENT_ROUTE_NAME */.PA, function () { if (agent.runSoftNavOverSpa) (0,spa_handle/* handle */.p)(cdn_spa_constants/* spaPrefix */.hw + 'routeName', [performance.now(), ...arguments], undefined, spa_features/* FEATURE_NAMES */.K7.softNav, agent.ee);else (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + 'routeName', [(0,spa_now/* now */.t)(), ...arguments], this, spa_features/* FEATURE_NAMES */.K7.spa, agent.ee); }, agent); } ;// ./src/features/soft_navigations/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * The minimal time after a UI event for which no further events will be processed - i.e. a throttling rate to reduce spam. * This also give some time for the new interaction to complete without being discarded by a subsequent UI event and wrongly attributed. * This value is still subject to change and critique, as it is derived from beyond worst case time to next frame of a page. */ const spa_UI_WAIT_INTERVAL = 1 / 10 * 1000; // assume 10 fps class spa_soft_navigations_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_soft_navigations_constants/* FEATURE_NAME */.TZ; constructor(agentRef) { super(agentRef, spa_soft_navigations_constants/* FEATURE_NAME */.TZ); /** feature specific APIs */ spa_setupInteractionAPI(agentRef); if (!spa_runtime/* isBrowserScope */.RI || !(0,spa_nreum/* gosNREUMOriginals */.dV)().o.MO) return; // soft navigations is not ed outside web env or browsers without the mutation observer API const historyEE = spa_wrapHistory(this.ee); spa_soft_navigations_constants/* INTERACTION_TRIGGERS */.tC.forEach(trigger => { (0,spa_event_listener_opts/* windowAddEventListener */.sp)(trigger, evt => { processInteraction(evt); }, true); }); const trackURLChange = () => (0,spa_handle/* handle */.p)('newURL', [(0,spa_now/* now */.t)(), '' + window.location], undefined, this.featureName, this.ee); historyEE.on('pushState-end', trackURLChange); historyEE.on('replaceState-end', trackURLChange); try { this.removeOnAbort = new AbortController(); } catch (e) {} const trackURLChangeEvent = evt => (0,spa_handle/* handle */.p)('newURL', [evt.timeStamp, '' + window.location], undefined, this.featureName, this.ee); (0,spa_event_listener_opts/* windowAddEventListener */.sp)('popstate', trackURLChangeEvent, true, this.removeOnAbort?.signal); let oncePerFrame = false; // attempt to reduce dom noice since the observer runs very frequently with below options const domObserver = new ((0,spa_nreum/* gosNREUMOriginals */.dV)().o.MO)((domChanges, observer) => { if (oncePerFrame) return; oncePerFrame = true; requestAnimationFrame(() => { // waiting for next frame to time when any visuals are supposedly updated (0,spa_handle/* handle */.p)('newDom', [(0,spa_now/* now */.t)()], undefined, this.featureName, this.ee); oncePerFrame = false; }); }); const processInteraction = (0,spa_invoke/* debounce */.s)(event => { (0,spa_handle/* handle */.p)('newUIEvent', [event], undefined, this.featureName, this.ee); domObserver.observe(document.body, { attributes: true, childList: true, subtree: true, characterData: true }); }, spa_UI_WAIT_INTERVAL, { leading: true }); this.abortHandler = abort; this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | soft_navigations-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 4393)), { domObserver }); function abort() { this.removeOnAbort?.abort(); domObserver.disconnect(); this.abortHandler = undefined; // weakly allow this abort op to run only once } } } const spa_SoftNav = (/* unused pure expression or super */ null & (spa_soft_navigations_instrument_Instrument)); // EXTERNAL MODULE: ./src/features/spa/constants.js var spa_spa_constants = __webpack_require__(7378); ;// ./src/common/wrap/wrap-jsonp.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps DOM insertion methods which in turn wrap JSONP functions that show up in the DOM. * This module is used by: spa. */ const spa_wrap_jsonp_wrapped = {}; const spa_domInsertMethods = ['appendChild', 'insertBefore', 'replaceChild']; /** * Wraps DOM insertion methods to identify script elements containing JSONP callback functions and instruments those * functions with custom events in the context of a new event emitter scoped only to JSONP. * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `jsonp`. */ function spa_wrapJsonP(sharedEE) { const ee = spa_wrap_jsonp_scopedEE(sharedEE); // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. JSONP deals with DOM // tags so browser window env is required. if (!spa_runtime/* isBrowserScope */.RI || spa_wrap_jsonp_wrapped[ee.debugId]) return ee; spa_wrap_jsonp_wrapped[ee.debugId] = true; // otherwise, first feature to wrap JSONP var wrapFn = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(ee); var CALLBACK_REGEX = /[?&](?:callback|cb)=([^]+)/; var PARENT_REGEX = /(.*)\.([^.]+)/; var VALUE_REGEX = /^(\w+)(\.|$)(.*)$/; // JSONP works by dynamically inserting elements - wrap DOM methods for // inserting elements to detect insertion of JSONP-specific elements. wrapFn.inPlace(Node.prototype, spa_domInsertMethods, 'dom-'); ee.on('dom-start', function (args) { wrapElement(args[0]); }); // subscribe to events on the JSONP <script> element and wrap the JSONP callback // in order to track start and end of the interaction node function wrapElement(el) { var isScript = el & typeof el.nodeName === 'string' && el.nodeName.toLowerCase() === 'script'; if (!isScript) return; var isValidElement = typeof el.addEventListener === 'function'; if (!isValidElement) return; var callbackName = extractCallbackName(el.src); if (!callbackName) return; var callback = discoverParent(callbackName); var validCallback = typeof callback.parent[callback.key] === 'function'; if (!validCallback) return; // At this point we know that the element is a valid JSONP script element. // The following events are emitted during the lifetime of a JSONP call: // * immediately emit `new-jsonp` to notify start of the JSONP work // * the wrapped callback will emit `cb-start` and `cb-end` during the execution // of the callback, here we can inspect the response // * when the element emits the `load` event (script loaded and executed), // emit `jsonp-end` to notify end of the JSONP work // * if the element emits the `error` event, in response emit `jsonp-error` // (and `jsonp-end`). Note that the callback in this case will likely not get // called. var context = {}; wrapFn.inPlace(callback.parent, [callback.key], 'cb-', context); el.addEventListener('load', onLoad, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); el.addEventListener('error', onError, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); ee.emit('new-jsonp', [el.src], context); function onLoad() { ee.emit('jsonp-end', [], context); el.removeEventListener('load', onLoad, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); el.removeEventListener('error', onError, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); } function onError() { ee.emit('jsonp-error', [], context); ee.emit('jsonp-end', [], context); el.removeEventListener('load', onLoad, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); el.removeEventListener('error', onError, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(false)); } } function extractCallbackName(src) { var matches = src.match(CALLBACK_REGEX); return matches ? matches[1] : null; } /** * Traverse a nested object using a '.'-delimited string wherein each substring piece maps to each subsequent object property layer. * @param {string} longKey * @param {object} obj * @returns The final nested object referred to by initial longKey. */ function discoverValue(longKey, obj) { if (!longKey) return obj; // end of object recursion depth when no more key levels const matches = longKey.match(VALUE_REGEX); // if 'longKey' was not undefined, that is it at least had 1 level left, then the regexp would've at least matched 1st group const key = matches[1]; const remaining = matches[3]; return discoverValue(remaining, obj[key]); } function discoverParent(key) { var matches = key.match(PARENT_REGEX); if (matches & matches.length >= 3) { return { key: matches[2], parent: discoverValue(matches[1], window) }; } return { key, parent: window }; } return ee; } /** * Returns an event emitter scoped specifically for the `jsonp` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'jsonp'. */ function spa_wrap_jsonp_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('jsonp'); } ;// ./src/common/wrap/wrap-promise.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps the native Promise object for instrumentation. * This module is used by: spa. */ const spa_wrap_promise_wrapped = {}; /** * Wraps the native Promise object so that it will emit events for start, end and error in the context of a new event * emitter scoped only to promise methods. Also instruments various methods, such as `all`, `race`, `resolve`, * `reject`, `then`, and `catch`. * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `promise`. */ function spa_wrapPromise(sharedEE) { const promiseEE = spa_wrap_promise_scopedEE(sharedEE); // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. if (spa_wrap_promise_wrapped[promiseEE.debugId]) return promiseEE; spa_wrap_promise_wrapped[promiseEE.debugId] = true; // otherwise, first feature to wrap promise var getContext = promiseEE.context; var promiseWrapper = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(promiseEE); var prevPromiseObj = spa_runtime/* globalScope */.gm.Promise; if (prevPromiseObj) { // ensure there's a Promise API (native or otherwise) to even wrap wrap(); } function wrap() { spa_runtime/* globalScope */.gm.Promise = WrappedPromise; // Renamed from "WrappedPromise" back to "Promise" & toString() so that we appear "native" to TP libraries... Object.defineProperty(WrappedPromise, 'name', { value: 'Promise' }); WrappedPromise.toString = function () { return prevPromiseObj.toString(); }; /** * This constitutes the global used when calling "Promise.staticMethod" or chaining off a "new Promise()" object. * @param {Function} executor - to be executed by the original Promise constructor * @returns A new WrappedPromise object prototyped off the original. */ function WrappedPromise(executor) { var ctx = promiseEE.context(); var wrappedExecutor = promiseWrapper(executor, 'executor-', ctx, null, false); const newCustomPromiseInst = Reflect.construct(prevPromiseObj, [wrappedExecutor], WrappedPromise); // new Promises will use WrappedPromise.prototype as theirs prototype promiseEE.context(newCustomPromiseInst).getCtx = function () { return ctx; }; return newCustomPromiseInst; } // Make WrappedPromise inherit statics from the orig Promise. Object.setPrototypeOf(WrappedPromise, prevPromiseObj); ['all', 'race'].forEach(function (method) { const prevStaticFn = prevPromiseObj[method]; WrappedPromise[method] = function (subPromises) { // use our own wrapped version of "Promise.all" and ".race" static fns let finalized = false; [...(subPromises || [])].forEach(sub => { this.resolve(sub).then(setNrId(method === 'all'), setNrId(false)); }); const origFnCallWithThis = prevStaticFn.apply(this, arguments); return origFnCallWithThis; function setNrId(overwrite) { return function () { promiseEE.emit('propagate', [null, !finalized], origFnCallWithThis, false, false); finalized = finalized || !overwrite; }; } }; }); ['resolve', 'reject'].forEach(function (method) { const prevStaticFn = prevPromiseObj[method]; WrappedPromise[method] = function (val) { // and the same for ".resolve" and ".reject" const origFnCallWithThis = prevStaticFn.apply(this, arguments); if (val !== origFnCallWithThis) { promiseEE.emit('propagate', [val, true], origFnCallWithThis, false, false); } return origFnCallWithThis; }; }); /* * Ideally, we create a new WrappedPromise.prototype chained off the original Promise's so that we don't alter it. * However, there's no way to make the (native) promise returned from async functions use our WrappedPromise, * so we have to modify the original prototype. This ensures that promises returned from async functions execute * the same instance methods as promises created with "new Promise()", and also that instanceof async() is * the global Promise (see GH issue #409). This also affects the promise returned from fetch(). */ WrappedPromise.prototype = prevPromiseObj.prototype; // Note that this wrapping affects the same originals.PR (prototype) object. const prevPromiseOrigThen = prevPromiseObj.prototype.then; prevPromiseObj.prototype.then = function wrappedThen(...args) { var originalThis = this; var ctx = getContext(originalThis); ctx.promise = originalThis; args[0] = promiseWrapper(args[0], 'cb-', ctx, null, false); args[1] = promiseWrapper(args[1], 'cb-', ctx, null, false); const origFnCallWithThis = prevPromiseOrigThen.apply(this, args); ctx.nextPromise = origFnCallWithThis; promiseEE.emit('propagate', [originalThis, true], origFnCallWithThis, false, false); return origFnCallWithThis; }; prevPromiseObj.prototype.then[spa_wrap_function/* flag */.Jt] = prevPromiseOrigThen; promiseEE.on('executor-start', function (args) { args[0] = promiseWrapper(args[0], 'resolve-', this, null, false); args[1] = promiseWrapper(args[1], 'resolve-', this, null, false); }); promiseEE.on('executor-err', function (args, originalThis, err) { args[1](err); }); promiseEE.on('cb-end', function (args, originalThis, result) { promiseEE.emit('propagate', [result, true], this.nextPromise, false, false); }); promiseEE.on('propagate', function (val, overwrite, trigger) { if (!this.getCtx || overwrite) { this.getCtx = function () { // eslint-disable-next-line if (val instanceof Promise) { var store = promiseEE.context(val); } return store & store.getCtx ? store.getCtx() : this; }; } }); } return promiseEE; } /** * Returns an event emitter scoped specifically for the `promise` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'promise'. */ function spa_wrap_promise_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('promise'); } ;// ./src/common/wrap/wrap-timer.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps native timeout and interval methods for instrumentation. * This module is used by: jserrors, spa. */ const spa_wrap_timer_wrapped = {}; const spa_SET_TIMEOUT = 'setTimeout'; const spa_SET_INTERVAL = 'setInterval'; const spa_CLEAR_TIMEOUT = 'clearTimeout'; const spa_wrap_timer_START = '-start'; const spa_DASH = '-'; const spa_TIMER_FNS = [spa_SET_TIMEOUT, 'setImmediate', spa_SET_INTERVAL, spa_CLEAR_TIMEOUT, 'clearImmediate']; /** * Wraps the global `setTimeout`, `setImmediate`, `setInterval`, `clearTimeout`, and `clearImmediate` functions to emit * events on start, end, and error, in the context of a new event emitter scoped only to timer functions. Also wraps * the callbacks of `setTimeout` and `setInterval`. * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `timer`. */ // eslint-disable-next-line function spa_wrapTimer(sharedEE) { const ee = spa_wrap_timer_scopedEE(sharedEE); // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. if (spa_wrap_timer_wrapped[ee.debugId]++) return ee; spa_wrap_timer_wrapped[ee.debugId] = 1; // otherwise, first feature to wrap timer var wrapFn = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(ee); wrapFn.inPlace(spa_runtime/* globalScope */.gm, spa_TIMER_FNS.slice(0, 2), spa_SET_TIMEOUT + spa_DASH); wrapFn.inPlace(spa_runtime/* globalScope */.gm, spa_TIMER_FNS.slice(2, 3), spa_SET_INTERVAL + spa_DASH); wrapFn.inPlace(spa_runtime/* globalScope */.gm, spa_TIMER_FNS.slice(3), spa_CLEAR_TIMEOUT + spa_DASH); ee.on(spa_SET_INTERVAL + spa_wrap_timer_START, interval); ee.on(spa_SET_TIMEOUT + spa_wrap_timer_START, timer); function interval(args, obj, type) { args[0] = wrapFn(args[0], 'fn-', null, type); } function timer(args, obj, type) { this.method = type; this.timerDuration = isNaN(args[1]) ? 0 : +args[1]; args[0] = wrapFn(args[0], 'fn-', this, type); } return ee; } /** * Returns an event emitter scoped specifically for the `timer` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'timer'. */ function spa_wrap_timer_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('timer'); } ;// ./src/common/wrap/wrap-mutation.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps the window's DOM mutation observer for instrumentation. * This module is used by: spa. */ const spa_wrap_mutation_wrapped = {}; /** * In web environments only, wraps the `window.MutationObserver` function to emit events on start, end, and error, in * the context of a new event emitter scoped only to mutations. * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @returns {Object} Scoped event emitter with a debug ID of `mutation`. */ function spa_wrapMutation(sharedEE) { const ee = spa_wrap_mutation_scopedEE(sharedEE); // Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has, // then we increment the count to track # of feats using this at runtime. Mutations API is only // available in browser DOM context. if (!spa_runtime/* isBrowserScope */.RI || spa_wrap_mutation_wrapped[ee.debugId]) return ee; spa_wrap_mutation_wrapped[ee.debugId] = true; // otherwise, first feature to wrap mutations var wrapFn = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(ee); var OriginalObserver = spa_runtime/* globalScope */.gm.MutationObserver; if (OriginalObserver) { window.MutationObserver = function WrappedMutationObserver(cb) { if (this instanceof OriginalObserver) { return new OriginalObserver(wrapFn(cb, 'fn-')); } else { return OriginalObserver.apply(this, arguments); } }; MutationObserver.prototype = OriginalObserver.prototype; } return ee; } /** * Returns an event emitter scoped specifically for the `mutation` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'mutation'. */ function spa_wrap_mutation_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('mutation'); } ;// ./src/features/spa/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ const { /* FEATURE_NAME */ "TZ": spa_instrument_FEATURE_NAME, /* START */ "d3": spa_instrument_START, /* END */ "Kp": spa_instrument_END, /* BODY */ "$p": spa_BODY, /* CB_END */ "wW": spa_CB_END, /* JS_TIME */ "e5": spa_JS_TIME, /* FETCH */ "tH": spa_FETCH, /* FN_START */ "uP": spa_instrument_FN_START, /* CB_START */ "rw": spa_CB_START, /* FN_END */ "Lc": spa_instrument_FN_END } = spa_spa_constants; /** * @deprecated This feature has been deprecated, in favor of `soft_navigations`, which is in limited preview. Consider using/importing `SoftNavigations` instead. To gain access to the limited preview, please see https://docs.newrelic.com/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2/ for more information. This feature will be removed in a future release. */ class spa_spa_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_instrument_FEATURE_NAME; constructor(agentRef) { super(agentRef, spa_instrument_FEATURE_NAME); /** feature specific APIs */ spa_setupInteractionAPI(agentRef); if (!spa_runtime/* isBrowserScope */.RI) return; // SPA not ed outside web env try { this.removeOnAbort = new AbortController(); } catch (e) {} let depth = 0; let startHash; const tracerEE = this.ee.get('tracer'); const jsonpEE = spa_wrapJsonP(this.ee); const promiseEE = spa_wrapPromise(this.ee); const timerEE = spa_wrapTimer(this.ee); const xhrEE = spa_wrapXhr(this.ee); const eventsEE = this.ee.get('events'); // wrapXhr will call wrapEvents const fetchEE = spa_wrapFetch(this.ee); const historyEE = spa_wrapHistory(this.ee); const mutationEE = spa_wrapMutation(this.ee); this.ee.on(spa_instrument_FN_START, startTimestamp); promiseEE.on(spa_CB_START, startTimestamp); jsonpEE.on(spa_CB_START, startTimestamp); this.ee.on(spa_instrument_FN_END, endTimestamp); promiseEE.on(spa_CB_END, endTimestamp); jsonpEE.on(spa_CB_END, endTimestamp); this.ee.on('fn-err', (...args) => { if (!args[2]?.__newrelic?.[agentRef.agentIdentifier]) (0,spa_handle/* handle */.p)('function-err', [...args], undefined, this.featureName, this.ee); }); this.ee.buffer([spa_instrument_FN_START, spa_instrument_FN_END, 'xhr-resolved'], this.featureName); eventsEE.buffer([spa_instrument_FN_START], this.featureName); timerEE.buffer(['setTimeout' + spa_instrument_END, 'clearTimeout' + spa_instrument_START, spa_instrument_FN_START], this.featureName); xhrEE.buffer([spa_instrument_FN_START, 'new-xhr', 'send-xhr' + spa_instrument_START], this.featureName); fetchEE.buffer([spa_FETCH + spa_instrument_START, spa_FETCH + '-done', spa_FETCH + spa_BODY + spa_instrument_START, spa_FETCH + spa_BODY + spa_instrument_END], this.featureName); historyEE.buffer(['newURL'], this.featureName); mutationEE.buffer([spa_instrument_FN_START], this.featureName); promiseEE.buffer(['propagate', spa_CB_START, spa_CB_END, 'executor-err', 'resolve' + spa_instrument_START], this.featureName); tracerEE.buffer([spa_instrument_FN_START, 'no-' + spa_instrument_FN_START], this.featureName); jsonpEE.buffer(['new-jsonp', 'cb-start', 'jsonp-error', 'jsonp-end'], this.featureName); timestamp(fetchEE, spa_FETCH + spa_instrument_START); timestamp(fetchEE, spa_FETCH + '-done'); timestamp(jsonpEE, 'new-jsonp'); timestamp(jsonpEE, 'jsonp-end'); timestamp(jsonpEE, 'cb-start'); historyEE.on('pushState-end', trackURLChange); historyEE.on('replaceState-end', trackURLChange); window.addEventListener('hashchange', trackURLChange, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(true, this.removeOnAbort?.signal)); window.addEventListener('load', trackURLChange, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(true, this.removeOnAbort?.signal)); window.addEventListener('popstate', function () { trackURLChange(0, depth > 1); }, (0,spa_event_listener_opts/* eventListenerOpts */.jT)(true, this.removeOnAbort?.signal)); function trackURLChange(unusedArgs, hashChangedDuringCb) { historyEE.emit('newURL', ['' + window.location, hashChangedDuringCb]); } function startTimestamp() { depth++; startHash = window.location.hash; this[spa_instrument_FN_START] = (0,spa_now/* now */.t)(); } function endTimestamp() { depth--; if (window.location.hash !== startHash) { trackURLChange(0, true); } var time = (0,spa_now/* now */.t)(); this[spa_JS_TIME] = ~~this[spa_JS_TIME] + time - this[spa_instrument_FN_START]; this[spa_instrument_FN_END] = time; } function timestamp(ee, type) { ee.on(type, function () { this[type] = (0,spa_now/* now */.t)(); }); } this.abortHandler = this.#abort; this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | spa-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 5592))); } /** Restoration and resource release tasks to be done if SPA loader is being aborted. Unwind changes to globals and subscription to DOM events. */ #abort() { this.removeOnAbort?.abort(); this.abortHandler = undefined; // weakly allow this abort op to run only once } } const spa_Spa = (/* unused pure expression or super */ null & (spa_spa_instrument_Instrument)); ;// ./src/loaders/api/recordCustomEvent.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupRecordCustomEventAPI(agent) { spa_setupAPI(cdn_spa_constants/* RECORD_CUSTOM_EVENT */.fF, function () { (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + cdn_spa_constants/* RECORD_CUSTOM_EVENT */.fF, [(0,spa_now/* now */.t)(), ...arguments], undefined, spa_features/* FEATURE_NAMES */.K7.genericEvents, agent.ee); }, agent); } ;// ./src/loaders/api/measure.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupMeasureAPI(agent) { spa_setupAPI(cdn_spa_constants/* MEASURE */.V1, function (name, options) { const n = (0,spa_now/* now */.t)(); const { start, end, customAttributes } = options || {}; const returnObj = { customAttributes: customAttributes || {} }; if (typeof returnObj.customAttributes !== 'object' || typeof name !== 'string' || name.length === 0) { (0,spa_console/* warn */.R)(57); return; } /** * getValueFromTiming - Helper function to extract a numeric value from a supplied option. * @param {Number|PerformanceMark} [timing] The timing value * @param {Number} [d] The default value to return if timing is invalid * @returns {Number} The timing value or the default value */ const getValueFromTiming = (timing, d) => { if (timing == null) return d; if (typeof timing === 'number') return timing; if (timing instanceof PerformanceMark) return timing.startTime; return Number.NaN; }; returnObj.start = getValueFromTiming(start, 0); returnObj.end = getValueFromTiming(end, n); if (Number.isNaN(returnObj.start) || Number.isNaN(returnObj.end)) { (0,spa_console/* warn */.R)(57); return; } returnObj.duration = returnObj.end - returnObj.start; if (returnObj.duration < 0) { (0,spa_console/* warn */.R)(58); return; } (0,spa_handle/* handle */.p)(cdn_spa_constants/* prefix */.Pl + cdn_spa_constants/* MEASURE */.V1, [returnObj, name], undefined, spa_features/* FEATURE_NAMES */.K7.genericEvents, agent.ee); return returnObj; }, agent); } // EXTERNAL MODULE: ./src/features/generic_events/constants.js var spa_generic_events_constants = __webpack_require__(3333); ;// ./src/features/generic_events/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class spa_generic_events_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_generic_events_constants/* FEATURE_NAME */.TZ; constructor(agentRef) { super(agentRef, spa_generic_events_constants/* FEATURE_NAME */.TZ); /** config values that gate whether the generic events aggregator should be imported at all */ const genericEventSourceConfigs = [agentRef.init.page_action.enabled, agentRef.init.performance.capture_marks, agentRef.init.performance.capture_measures, agentRef.init._actions.enabled, agentRef.init.performance.resources.enabled]; /** feature specific APIs */ spa_setupAddPageActionAPI(agentRef); spa_setupRecordCustomEventAPI(agentRef); spa_setupFinishedAPI(agentRef); spa_setupAPI(agentRef); spa_setupMeasureAPI(agentRef); if (spa_runtime/* isBrowserScope */.RI) { if (agentRef.init._actions.enabled) { spa_generic_events_constants/* OBSERVED_EVENTS */.Zp.forEach(eventType => (0,spa_event_listener_opts/* windowAddEventListener */.sp)(eventType, evt => (0,spa_handle/* handle */.p)('ua', [evt], undefined, this.featureName, this.ee), true)); spa_generic_events_constants/* OBSERVED_WINDOW_EVENTS */.qN.forEach(eventType => { const debounceHandler = (0,spa_invoke/* debounce */.s)(evt => { (0,spa_handle/* handle */.p)('ua', [evt], undefined, this.featureName, this.ee); }, 500, { leading: true }); (0,spa_event_listener_opts/* windowAddEventListener */.sp)(eventType, debounceHandler); } // Capture is not used here so that we don't get element focus/blur events, only the window's as they do not bubble. They are also not cancellable, so no worries about being front of line. ); } if (agentRef.init.performance.resources.enabled & spa_runtime/* globalScope */.gm.PerformanceObserver?.edEntryTypes.includes('resource')) { const observer = new PerformanceObserver(list => { list.getEntries().forEach(entry => { (0,spa_handle/* handle */.p)('browserPerformance.resource', [entry], undefined, this.featureName, this.ee); }); }); observer.observe({ type: 'resource', buffered: true }); } } /** If any of the sources are active, import the aggregator. otherwise de */ if (genericEventSourceConfigs.some(x => x)) this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | generic_events-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 8019)));else this.deDrain(); } } const spa_GenericEvents = (/* unused pure expression or super */ null & (spa_generic_events_instrument_Instrument)); // EXTERNAL MODULE: ./src/common/event-emitter/event-context.js var spa_event_context = __webpack_require__(2646); ;// ./src/common/wrap/wrap-logger.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Wraps native timeout and interval methods for instrumentation. * This module is used by: jserrors, spa. */ const spa_contextMap = new Map(); /** * Wraps a supplied function and adds emitter events under the `-wrap-logger-` prefix * @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based. * @param {Object} parent - The parent object housing the logger function * @param {string} loggerFn - The name of the function in the parent object to wrap * @returns {Object} Scoped event emitter with a debug ID of `logger`. */ // eslint-disable-next-line function spa_wrapLogger(sharedEE, parent, loggerFn, context) { if (!(typeof parent === 'object' & !!parent && typeof loggerFn === 'string' && !!loggerFn && typeof parent[loggerFn] === 'function')) return (0,spa_console/* warn */.R)(29); const ee = spa_wrap_logger_scopedEE(sharedEE); const wrapFn = (0,spa_wrap_function/* createWrapperWithEmitter */.YM)(ee); /** * This section contains the context that will be shared across all invoked calls of the wrapped function, * which will be used to decorate the log data later at agg time */ const ctx = new spa_event_context/* EventContext */.y(spa_contextual_ee/* contextId */.P); ctx.level = context.level; ctx.customAttributes = context.customAttributes; const contextLookupKey = parent[loggerFn]?.[spa_wrap_function/* flag */.Jt] || parent[loggerFn]; spa_contextMap.set(contextLookupKey, ctx); /** observe calls to <loggerFn> and emit events prefixed with `wrap-logger-` */ wrapFn.inPlace(parent, [loggerFn], 'wrap-logger-', () => spa_contextMap.get(contextLookupKey)); return ee; } /** * Returns an event emitter scoped specifically for the `logger` context. This scoping is a remnant from when all the * features shared the same group in the event, to isolate events between features. It will likely be revisited. * @param {Object} sharedEE - Optional event emitter on which to base the scoped emitter. * Uses `ee` on the global scope if undefined). * @returns {Object} Scoped event emitter with a debug ID of 'logger'. */ function spa_wrap_logger_scopedEE(sharedEE) { return (sharedEE || spa_contextual_ee.ee).get('logger'); } ;// ./src/loaders/api/wrapLogger.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ function spa_setupWrapLoggerAPI(agent) { spa_setupAPI(cdn_spa_constants/* WRAP_LOGGER */.Wb, (parent, functionName, { customAttributes = {}, level = spa_logging_constants/* LOG_LEVELS */.p_.INFO } = {}) => { spa_wrapLogger(agent.ee, parent, functionName, { customAttributes, level }); }, agent); } ;// ./src/features/logging/instrument/index.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ class spa_logging_instrument_Instrument extends spa_InstrumentBase { static featureName = spa_logging_constants/* FEATURE_NAME */.TZ; constructor(agentRef) { super(agentRef, spa_logging_constants/* FEATURE_NAME */.TZ); /** feature specific APIs */ spa_setupLogAPI(agentRef); spa_setupWrapLoggerAPI(agentRef); spa_setupAPI(agentRef); const instanceEE = this.ee; spa_wrapLogger(instanceEE, spa_runtime/* globalScope */.gm.console, 'log', { level: 'info' }); spa_wrapLogger(instanceEE, spa_runtime/* globalScope */.gm.console, 'error', { level: 'error' }); spa_wrapLogger(instanceEE, spa_runtime/* globalScope */.gm.console, 'warn', { level: 'warn' }); spa_wrapLogger(instanceEE, spa_runtime/* globalScope */.gm.console, 'info', { level: 'info' }); spa_wrapLogger(instanceEE, spa_runtime/* globalScope */.gm.console, 'debug', { level: 'debug' }); spa_wrapLogger(instanceEE, spa_runtime/* globalScope */.gm.console, 'trace', { level: 'trace' }); /** emitted by wrap-logger function */ this.ee.on('wrap-logger-end', function handleLog([message]) { const { level, customAttributes } = this; (0,spa_shared_utils/* bufferLog */.R)(instanceEE, message, customAttributes, level); }); this.importAggregator(agentRef, () => __webpack_require__.e(/* import() | logging-aggregate */ 478).then(__webpack_require__.bind(__webpack_require__, 5288))); } } const spa_Logging = (/* unused pure expression or super */ null & (spa_logging_instrument_Instrument)); ;// ./src/cdn/spa.js /** * Copyright 2020-2025 New Relic, Inc. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ /** * @file Creates a "SPA" agent loader bundle composed of the core agent and all available feature modules. */ new spa_Agent({ features: [spa_ajax_instrument_Instrument, spa_Instrument, cdn_spa_instrument_Instrument, spa_session_trace_instrument_Instrument, spa_session_replay_instrument_Instrument, spa_metrics_instrument_Instrument, spa_jserrors_instrument_Instrument, spa_generic_events_instrument_Instrument, spa_logging_instrument_Instrument, spa_soft_navigations_instrument_Instrument, spa_spa_instrument_Instrument // either the softnav or the old spa will be used (not both), but we still need to pack both to avoid dynamic import for instrument files ], loaderType: 'spa' }); })(); /******/ })() ; (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};m[i].l=1*new Date();for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");ym(92306955, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true});(function (d, w, c) {(w[c] = w[c] || []).push(function() {try {w.yaCounter92137959 = new Ya.Metrika2({id:92137959,clickmap:true,trackLinks:true,accurateTrackBounce:true});} catch(e) { }});var n = d.getElementsByTagName("script")[0],s = d.createElement("script"),f = function () { n.parentNode.insertBefore(s, n); };s.type = "text/javascript";s.async = true;s.src = "https://mc.yandex.ru/metrika/tag.js";if (w.opera == "[object Opera]") {d.addEventListener("DOMContentLoaded", f, false);} else { f(); }})(document, window, "yandex_metrika_callbacks2"); !function e(t){for(var n=t+"=",r=document.cookie.split(";"),o=0;o<r.length;o++){for(var i=r[o];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(n))return i.substring(n.length,i.length)}return null}("prefix_views_counter")&function e(t){var n,r;if(!t||(window.XMLHttpRequest&(n=new window.XMLHttpRequest),!n))return!1;r="action="+encodeURIComponent(t);try{n.open("POST","/user.php",!0),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.onload=function(){200===n.status&function e(t,n,r){if(r){var o=new Date;o.setTime(o.getTime()+864e5*r);var i="; expires="+o.toGMTString()}else var i="";document.cookie=t+"=1"+i+"; path=/"}("prefix_views_counter",1,1)},n.send(r)}catch(o){}return!0}('869c1902685bda952431d93a839c7688'); (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(92138131, "init", {clickmap:true,trackLinks:true,accurateTrackBounce:true }); 2i2563