@pendo/agent 2.295.0 → 2.296.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3527,6 +3527,7 @@ var ConfigReader = (function () {
3527
3527
  addOption('enableAllEmbeddedGuideEvents', [PENDO_CONFIG_SRC], false);
3528
3528
  // Form Validation
3529
3529
  addOption('formValidation', [PENDO_CONFIG_SRC], false);
3530
+ addOption('performanceMetricsEnabled', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
3530
3531
  }
3531
3532
  initializeOptions();
3532
3533
  var sourceGetters = {};
@@ -3658,10 +3659,10 @@ var ConfigReader = (function () {
3658
3659
  /* eslint-enable no-console */
3659
3660
  })();
3660
3661
 
3661
- var EXTENSION_INSTALL_TYPE = 'extension';
3662
- var NATIVE_INSTALL_TYPE = 'native';
3662
+ const EXTENSION_INSTALL_TYPE = 'extension';
3663
+ const NATIVE_INSTALL_TYPE = 'native';
3663
3664
  function getInstallType() {
3664
- var installType = ConfigReader.get('installType') || getPendoConfigFromEnclosingScope().installType;
3665
+ const installType = ConfigReader.get('installType') || getPendoConfigFromEnclosingScope().installType;
3665
3666
  return installType || NATIVE_INSTALL_TYPE;
3666
3667
  }
3667
3668
  function isExtensionAgent() {
@@ -3891,8 +3892,8 @@ let SERVER = '';
3891
3892
  let ASSET_HOST = '';
3892
3893
  let ASSET_PATH = '';
3893
3894
  let DESIGNER_SERVER = '';
3894
- let VERSION = '2.295.0_';
3895
- let PACKAGE_VERSION = '2.295.0';
3895
+ let VERSION = '2.296.0_';
3896
+ let PACKAGE_VERSION = '2.296.0';
3896
3897
  let LOADER = 'xhr';
3897
3898
  /* eslint-enable agent-eslint-rules/no-gulp-env-references */
3898
3899
  /**
@@ -9772,6 +9773,33 @@ function writeErrorPOST(msg) {
9772
9773
  return writeMessage('Failed to write error to server using POST endpoint: ' + e);
9773
9774
  }
9774
9775
  }
9776
+ /**
9777
+ * @access private
9778
+ * @param {Object} payload of named metrics to send to backend
9779
+ * @returns void
9780
+ */
9781
+ function writeMetricsPOST(payload) {
9782
+ if (_.size(payload).length < 1)
9783
+ return;
9784
+ try {
9785
+ const url = `${HOST}/data/agentmetrics?apiKey=${pendo$1.apiKey}`;
9786
+ log.debug(`Will send ${payload} to ${url} using ${fetchKeepalive.supported() ? 'fetch' : 'xhr'} once the endpoint exists`);
9787
+ if (fetchKeepalive.supported()) {
9788
+ // fetch(url, {
9789
+ // method: 'POST',
9790
+ // keepalive: true,
9791
+ // body: JSON.stringify(payload),
9792
+ // headers: { 'Content-Type': 'application/json' }
9793
+ // });
9794
+ }
9795
+ else {
9796
+ // ajax.postJSON(url, payload);
9797
+ }
9798
+ }
9799
+ catch (e) {
9800
+ log.critical(`Failed to write metrics payload to server: ${e}`);
9801
+ }
9802
+ }
9775
9803
  /**
9776
9804
  * @access private
9777
9805
  * @param {string} src to apply to {Image}
@@ -11188,11 +11216,11 @@ class DomObserver {
11188
11216
  this._teardown = () => observer.disconnect;
11189
11217
  }
11190
11218
  else {
11191
- const handle = setTimeout$1(() => {
11219
+ const handle = setInterval(() => {
11192
11220
  this.signal();
11193
11221
  }, 500);
11194
11222
  this._teardown = () => {
11195
- clearTimeout(handle);
11223
+ clearInterval(handle);
11196
11224
  };
11197
11225
  }
11198
11226
  }
@@ -11418,7 +11446,7 @@ function isTrustedOrigin(host) {
11418
11446
  /^https:\/\/([0-9]{8}t[0-9]{4}-dot-)pendo-(au|eu|govramp|hsbc|io|jp-prod|us1)\.appspot\.com$/,
11419
11447
  /^https:\/\/hotfix-(ops|app)-([0-9]+-dot-)pendo-(au|eu|govramp|hsbc|io|jp-prod|us1)\.appspot\.com$/,
11420
11448
  /^https:\/\/pendo-(au|eu|govramp|hsbc|io|jp-prod|us1)-static\.storage\.googleapis\.com$/,
11421
- /^https:\/\/([a-zA-Z0-9-]+\.?)*\.pendo-dev\.com$/,
11449
+ /^https:\/\/([a-zA-Z0-9-]+\.)*pendo-dev\.com$/,
11422
11450
  /^https:\/\/([a-zA-Z0-9-]+-dot-)?pendo-(apollo|armada|atlas|batman|calypso|dap|dev|dr-us-east1|eu-dev|freeze|helix|link|magic|mcfly|ml|mobile-fbi|mobile-guides|mobile-hummus|mobile-plat|perfserf|voc|wildlings|ionchef|scrum-ops|security|test|uat|au|eu|govramp|hsbc|io|jp-prod|us1)\.appspot\.com$/,
11423
11451
  /^https:\/\/(via|adopt|local)\.pendo\.(local|io):\d{4}$/,
11424
11452
  /^https:\/\/pendo-(apollo|armada|atlas|batman|calypso|dap|dev|dr-us-east1|eu-dev|freeze|helix|link|magic|mcfly|ml|mobile-fbi|mobile-guides|mobile-hummus|mobile-plat|perfserf|voc|wildlings|ionchef|scrum-ops|security|test|uat)-static\.storage\.googleapis\.com$/
@@ -12168,27 +12196,55 @@ class LocalStorageEventBuffer {
12168
12196
  }
12169
12197
  var localStorageEventBuffer = new LocalStorageEventBuffer();
12170
12198
 
12199
+ /*
12200
+ * These implementations are meant to help keep the agent's metrics usage aligned with
12201
+ * the expectations for the backend's open telemetry.
12202
+ *
12203
+ * We're leveraging the details attribute that is optionally defined on all Performance
12204
+ * API marks.
12205
+ *
12206
+ * See https://opentelemetry.io/docs/concepts/signals/metrics/#metric-instruments
12207
+ */
12208
+ const count = (entries) => {
12209
+ if (!entries)
12210
+ return 0;
12211
+ if (entries instanceof Array) {
12212
+ return _.reduce(entries, (count, e) => {
12213
+ const incr = e.detail && e.detail.incr ? e.detail.incr : 1;
12214
+ return count + incr;
12215
+ }, 0);
12216
+ }
12217
+ return 0;
12218
+ };
12219
+
12220
+ const METRIC_GUIDELOOP_TIMEOUT = 'agent-guideloop-timeout';
12221
+ const Metrics = {};
12222
+ Metrics[METRIC_GUIDELOOP_TIMEOUT] = {
12223
+ displayName: 'Guide Loop Timeouts',
12224
+ name: METRIC_GUIDELOOP_TIMEOUT,
12225
+ instrument: count
12226
+ };
12227
+
12228
+ const PERF_INTERVAL = 1000 * 60 * 10;
12171
12229
  class PerformanceMonitor {
12172
12230
  constructor() {
12173
12231
  this._isPerformanceApiAvailable = this._checkPerformanceApi();
12174
12232
  this._measuringPerformance = false;
12175
- this._marks = {};
12176
- this._measures = {};
12233
+ this.marks = new Set();
12234
+ this.measures = new Set();
12177
12235
  }
12178
12236
  initialize() {
12179
12237
  this._measuringPerformance = true;
12180
12238
  this._markPerformance('initialize');
12181
- // temporary clear interval while working on send implementation
12182
12239
  this.interval = setInterval(() => {
12183
- this._clearMarksAndMeasures();
12184
- }, 1000 * 60 * 10);
12240
+ this.send();
12241
+ }, PERF_INTERVAL);
12185
12242
  return () => {
12186
12243
  this.teardown();
12187
12244
  };
12188
12245
  }
12189
12246
  teardown() {
12190
12247
  this._measuringPerformance = false;
12191
- this._markPerformance('teardown');
12192
12248
  this._clearMarksAndMeasures();
12193
12249
  clearInterval(this.interval);
12194
12250
  }
@@ -12199,16 +12255,23 @@ class PerformanceMonitor {
12199
12255
  this._markPerformance(`${name}-stop`);
12200
12256
  this._measurePerformance(name);
12201
12257
  }
12202
- track(name) {
12203
- this._markPerformance(name);
12258
+ count(name, incr = 1) {
12259
+ this._markPerformance(name, {
12260
+ detail: { type: 'count', incr }
12261
+ });
12204
12262
  }
12205
12263
  send() {
12206
- performance.getEntries();
12207
- // TODO: implement filter/send process
12264
+ const payload = _.reduce(_.keys(Metrics), (acc, name) => {
12265
+ const entries = performance.getEntriesByName(name);
12266
+ const result = Metrics[name].instrument(entries);
12267
+ acc[name] = result;
12268
+ }, {});
12208
12269
  this._clearMarksAndMeasures();
12270
+ writeMetricsPOST(payload);
12209
12271
  }
12210
12272
  _checkPerformanceApi() {
12211
- return detectNativeBrowserAPI('performance.mark') &&
12273
+ return ConfigReader.get('performanceMetricsEnabled') &&
12274
+ detectNativeBrowserAPI('performance.mark') &&
12212
12275
  detectNativeBrowserAPI('performance.measure') &&
12213
12276
  detectNativeBrowserAPI('performance.getEntries') &&
12214
12277
  detectNativeBrowserAPI('performance.getEntriesByName') &&
@@ -12218,12 +12281,12 @@ class PerformanceMonitor {
12218
12281
  _shouldMeasurePerformance() {
12219
12282
  return this._isPerformanceApiAvailable && this._measuringPerformance;
12220
12283
  }
12221
- _markPerformance(name) {
12284
+ _markPerformance(name, attr) {
12222
12285
  if (!this._shouldMeasurePerformance())
12223
12286
  return;
12224
12287
  name = `pendo-${name}`;
12225
12288
  performance.mark(name);
12226
- this._count(this._marks, name);
12289
+ this.marks.add(name);
12227
12290
  }
12228
12291
  _measurePerformance(name) {
12229
12292
  if (!this._shouldMeasurePerformance())
@@ -12233,29 +12296,21 @@ class PerformanceMonitor {
12233
12296
  const stopMark = `${name}-stop`;
12234
12297
  if (performance.getEntriesByName(startMark).length && performance.getEntriesByName(stopMark).length) {
12235
12298
  performance.measure(name, startMark, stopMark);
12236
- this._count(this._measures, name);
12237
- }
12238
- }
12239
- _count(registry, name) {
12240
- if (!registry[name]) {
12241
- registry[name] = 1;
12242
- }
12243
- else {
12244
- registry[name]++;
12299
+ this.measures.add(name);
12245
12300
  }
12246
12301
  }
12247
12302
  _clearMarksAndMeasures() {
12248
- _.each(this._marks, (count, name) => {
12303
+ _.each(this.marks.entries, (name) => {
12249
12304
  performance.clearMarks(name);
12250
12305
  });
12251
- _.each(this._measures, (count, name) => {
12306
+ this.marks.clear();
12307
+ _.each(this.measures.entries, (name) => {
12252
12308
  performance.clearMeasures(name);
12253
12309
  });
12254
- this._marks = {};
12255
- this._measures = {};
12310
+ this.measures.clear();
12256
12311
  }
12257
12312
  }
12258
- var PerformanceMonitor$1 = new PerformanceMonitor();
12313
+ const _PerformanceMonitor = new PerformanceMonitor();
12259
12314
 
12260
12315
  var defaultTrackName = '_PENDO_UNNAMED_';
12261
12316
  var SILO_AVG_COMPRESSION_RATIO = 5;
@@ -12757,7 +12812,7 @@ function createSendQueue(options, send, guaranteedSend) {
12757
12812
  }
12758
12813
  });
12759
12814
  queue.onTimeout = function () {
12760
- PerformanceMonitor$1.track(`${options.beacon}-gif-failure`);
12815
+ _PerformanceMonitor.track(`${options.beacon}-gif-failure`);
12761
12816
  };
12762
12817
  queue.retryPending = true;
12763
12818
  return queue;
@@ -13287,7 +13342,7 @@ var getValidTarget = function (node) {
13287
13342
  */
13288
13343
  var handle_event = function (evt) {
13289
13344
  try {
13290
- PerformanceMonitor$1.startTimer('event-captured');
13345
+ _PerformanceMonitor.startTimer('event-captured');
13291
13346
  if (dom.data.get(evt, 'counted'))
13292
13347
  return;
13293
13348
  dom.data.set(evt, 'counted', true);
@@ -13328,7 +13383,7 @@ var handle_event = function (evt) {
13328
13383
  log.critical('pendo.io while handling event', { error: e });
13329
13384
  }
13330
13385
  finally {
13331
- PerformanceMonitor$1.stopTimer('event-captured');
13386
+ _PerformanceMonitor.stopTimer('event-captured');
13332
13387
  }
13333
13388
  };
13334
13389
  function getClickEventProperties(target) {
@@ -13456,7 +13511,7 @@ function wireSyntheticClicks(handle_event, attach, interceptElementRemoval, inte
13456
13511
  ignoreNextClick = false;
13457
13512
  if (!e || !downEvent)
13458
13513
  return;
13459
- if (interceptMouseUp && getTarget(downEvent) !== getTarget(e)) {
13514
+ if (interceptMouseUp && getTarget(downEvent) !== getTarget(e) && isInDocument(getTarget(downEvent))) {
13460
13515
  ignoreNextClick = true;
13461
13516
  handle_event(downEvent);
13462
13517
  }
@@ -16875,7 +16930,7 @@ function sizeElements(guide) {
16875
16930
  const targetEleGrowHeightParent = targetEle.parentNode.closest('[data-pendo-grow-height="true"]');
16876
16931
  if (targetEleGrowHeightParent) {
16877
16932
  // Sizing will be ineffective on nested elements of grow height elements that are not resized, so skip if grow height parent is not sized
16878
- if (!sizedElements.includes(targetEleGrowHeightParent))
16933
+ if (!_.contains(sizedElements, targetEleGrowHeightParent))
16879
16934
  continue;
16880
16935
  containerEle = targetEleGrowHeightParent;
16881
16936
  }
@@ -21167,6 +21222,7 @@ class UpdateRunner {
21167
21222
  monitor.start();
21168
21223
  promise = currentPhase.process(monitor);
21169
21224
  if (!promise && monitor.isTimeExceeded()) {
21225
+ _PerformanceMonitor.count(METRIC_GUIDELOOP_TIMEOUT);
21170
21226
  if (currentPhase.handleProcessTimeExceeded) {
21171
21227
  currentPhase.handleProcessTimeExceeded(monitor);
21172
21228
  }
@@ -21355,6 +21411,7 @@ class GuideTypeIdentifier {
21355
21411
  const GuideMonitor = (() => {
21356
21412
  const guideTypeMap = {};
21357
21413
  const onFetchFail = ({ data }) => {
21414
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
21358
21415
  const [contentContainer, error] = data;
21359
21416
  const { guideId } = contentContainer;
21360
21417
  const guide = findGuideById(guideId);
@@ -23961,35 +24018,37 @@ function onTurbolinksPageLoad(document, onPageLoad, beforeTurboCache) {
23961
24018
  };
23962
24019
  }
23963
24020
 
23964
- var EMPTY_ARRAY_JZB = 'eJwFwIEIAAAAwDDQd3-N1QABFQC5';
23965
- var AD_BLOCK_STORAGE_KEY = 'guides_blocked';
23966
- var GUIDE_GIF_BLOCKED = '1';
23967
- var GUIDE_GIF_NOT_BLOCKED = '0';
23968
- var GUIDE_GIF_BLOCKED_MSG = 'Guides disabled: unreachable endpoint guide.gif';
24021
+ const EMPTY_ARRAY_JZB = 'eJwFwIEIAAAAwDDQd3-N1QABFQC5';
24022
+ const AD_BLOCK_STORAGE_KEY = 'guides_blocked';
24023
+ const BLOCKED_STORAGE_DURATION = 1800000; // 30 minutes
24024
+ const NOT_BLOCKED_STORAGE_DURATION = 14400000; // 4 hours
24025
+ const GUIDE_GIF_BLOCKED = '1';
24026
+ const GUIDE_GIF_NOT_BLOCKED = '0';
24027
+ const GUIDE_GIF_BLOCKED_MSG = 'Guides disabled: unreachable endpoint guide.gif';
23969
24028
  function areGuidesBlocked() {
23970
- var blocked = agentStorage.read(AD_BLOCK_STORAGE_KEY);
24029
+ const blocked = agentStorage.read(AD_BLOCK_STORAGE_KEY);
23971
24030
  return blocked === GUIDE_GIF_BLOCKED;
23972
24031
  }
23973
24032
  function setGuidesBlocked(testGuideGifResult) {
23974
24033
  if (testGuideGifResult.cached)
23975
24034
  return;
23976
24035
  if (testGuideGifResult.success) {
23977
- agentStorage.write(AD_BLOCK_STORAGE_KEY, GUIDE_GIF_NOT_BLOCKED);
24036
+ agentStorage.write(AD_BLOCK_STORAGE_KEY, GUIDE_GIF_NOT_BLOCKED, NOT_BLOCKED_STORAGE_DURATION);
23978
24037
  }
23979
24038
  else {
23980
24039
  log.info(GUIDE_GIF_BLOCKED_MSG);
23981
- agentStorage.write(AD_BLOCK_STORAGE_KEY, GUIDE_GIF_BLOCKED);
24040
+ agentStorage.write(AD_BLOCK_STORAGE_KEY, GUIDE_GIF_BLOCKED, BLOCKED_STORAGE_DURATION);
23982
24041
  }
23983
24042
  }
23984
24043
  function testGuideGifEndpoint(loader, apiKey) {
23985
- var blocked = agentStorage.read(AD_BLOCK_STORAGE_KEY);
24044
+ const blocked = agentStorage.read(AD_BLOCK_STORAGE_KEY);
23986
24045
  if (blocked === GUIDE_GIF_BLOCKED) {
23987
24046
  log.info(GUIDE_GIF_BLOCKED_MSG);
23988
24047
  return q.resolve({ success: false, cached: true });
23989
24048
  }
23990
24049
  if (blocked === GUIDE_GIF_NOT_BLOCKED)
23991
24050
  return q.resolve({ success: true, cached: true });
23992
- var url = buildBaseDataUrl('guide.gif', apiKey, {
24051
+ const url = buildBaseDataUrl('guide.gif', apiKey, {
23993
24052
  jzb: EMPTY_ARRAY_JZB,
23994
24053
  ct: getNow(),
23995
24054
  v: VERSION
@@ -27636,7 +27695,7 @@ var ResourceCenterActivity = (function () {
27636
27695
  }
27637
27696
  function getResourceCenterModule(appData) {
27638
27697
  var classes = appData.cls.split(' ');
27639
- if (classes.indexOf('_pendo-resource-center-module-list-item') !== -1) {
27698
+ if (_.contains(classes, '_pendo-resource-center-module-list-item')) {
27640
27699
  var moduleElement = dom('#' + appData.id).closest('[data-pendo-module-guide-id]');
27641
27700
  return { type: 'BUTTON', elementId: moduleElement.attr('data-pendo-module-guide-id') };
27642
27701
  }
@@ -27651,8 +27710,8 @@ var ResourceCenterActivity = (function () {
27651
27710
  }
27652
27711
  function getResourceCenterModuleItem(appData) {
27653
27712
  var classes = appData.cls.split(' ');
27654
- if (classes.indexOf('_pendo-resource-center-guidelist-module-listed-guide') !== -1 ||
27655
- classes.indexOf('_pendo-resource-center-onboarding-module-listed-guide') !== -1) {
27713
+ if (_.contains(classes, '_pendo-resource-center-guidelist-module-listed-guide') ||
27714
+ _.contains(classes, '_pendo-resource-center-onboarding-module-listed-guide')) {
27656
27715
  const activeRC = BuildingBlockResourceCenter.getResourceCenter();
27657
27716
  if (activeRC) {
27658
27717
  var itemIndex = appData.id.split('-').pop();
@@ -28101,7 +28160,7 @@ const initialize = makeSafe(function (options) {
28101
28160
  Events.appUsage.on(GuideActivity.handler);
28102
28161
  Events.appUsage.on(ResourceCenterActivity.handler);
28103
28162
  teardownFns.push(flushEvery(SEND_INTERVAL));
28104
- teardownFns.push(PerformanceMonitor$1.initialize());
28163
+ teardownFns.push(_PerformanceMonitor.initialize());
28105
28164
  }
28106
28165
  Events.appHidden.on(() => {
28107
28166
  flushNow(true, { hidden: true });
@@ -29352,7 +29411,7 @@ var validateNativeMethods = function (skipLogging) {
29352
29411
  _.each(keys, function (propName) {
29353
29412
  try {
29354
29413
  if (propName && nativeType[propName] && typeof nativeType[propName] === 'function') {
29355
- var isNativeImplementation = nativeType[propName].toString().includes('[native code]');
29414
+ var isNativeImplementation = nativeType[propName].toString().indexOf('[native code]') !== -1;
29356
29415
  if (!isNativeImplementation)
29357
29416
  nonNativeImplementations.push(propName);
29358
29417
  }
@@ -29758,8 +29817,8 @@ UrlTransform.fromJSON = function (obj) {
29758
29817
  }
29759
29818
  catch (error) {
29760
29819
  // If it's already a detailed error from our validation, re-throw it
29761
- if (error.message.includes('Invalid attribute') || error.message.includes('Invalid action') ||
29762
- error.message.includes('requires') || error.message.includes('expects')) {
29820
+ if (error.message.indexOf('Invalid attribute') !== -1 || error.message.indexOf('Invalid action') !== -1 ||
29821
+ error.message.indexOf('requires') !== -1 || error.message.indexOf('expects') !== -1) {
29763
29822
  throw error;
29764
29823
  }
29765
29824
  // Otherwise, wrap the original error with context
@@ -33140,12 +33199,12 @@ var GuideUpdateModule = (function () {
33140
33199
  state.scheduledUpdate = scheduledUpdate;
33141
33200
  },
33142
33201
  startUpdate(state, time) {
33143
- PerformanceMonitor$1.startTimer('guide-loop');
33202
+ _PerformanceMonitor.startTimer('guide-loop');
33144
33203
  state.needsUpdate = false;
33145
33204
  state.updateId = time;
33146
33205
  },
33147
33206
  completeUpdate(state, time) {
33148
- PerformanceMonitor$1.stopTimer('guide-loop');
33207
+ _PerformanceMonitor.stopTimer('guide-loop');
33149
33208
  state.updateId = null;
33150
33209
  state.updateCompleteTime = time;
33151
33210
  }
@@ -37652,7 +37711,7 @@ const buildGuideBehaviors = function ({ globalPendo, pluginApi }) {
37652
37711
  const firstStep = _.first(guide.steps);
37653
37712
  if (guide.forceShowFirstStep) {
37654
37713
  guide.forceShowFirstStep = false;
37655
- return firstStep.show('reason');
37714
+ return firstStep.show(reason);
37656
37715
  }
37657
37716
  const steps = guide.steps.map((step) => {
37658
37717
  // The stored step state is most up to date. Fallback to the guides payload
@@ -38242,7 +38301,7 @@ const paidMediumRegex = new RegExp('^(.*cp.*|ppc|retargeting|paid)$');
38242
38301
  // add other email-related values here, if needed
38243
38302
  const emailRegex = new RegExp('(.*email.*|.*e_mail.*|.*e mail.*|.*e-mail.*)', 'i');
38244
38303
  function utmIncludesValue(utm = '', value) {
38245
- return utm.replace(/[^a-zA-Z]/g, '').includes(value);
38304
+ return utm.replace(/[^a-zA-Z]/g, '').indexOf(value) !== -1;
38246
38305
  }
38247
38306
  // order is critical here, as the first match is returned, consider this when adding new channels and updating conditions
38248
38307
  const channels = [
@@ -39662,6 +39721,7 @@ const PollBranching = {
39662
39721
  .attr({ title: 'Custom Branching Added' });
39663
39722
  let dataPendoPollId = question.getAttribute('data-pendo-poll-id');
39664
39723
  if (pendo.dom(`._pendo-multi-choice-poll-question[data-pendo-poll-id=${dataPendoPollId}]`)[0]) {
39724
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
39665
39725
  pendo
39666
39726
  .dom(`._pendo-multi-choice-poll-question[data-pendo-poll-id=${dataPendoPollId}]`)[0]
39667
39727
  .textContent.trim();
@@ -40062,7 +40122,7 @@ const RequiredQuestions = {
40062
40122
  return input[0].value;
40063
40123
  }
40064
40124
  }));
40065
- if (responses.includes(undefined) || pendo._.isEmpty(responses)) {
40125
+ if (pendo._.contains(responses, undefined) || pendo._.isEmpty(responses)) {
40066
40126
  allRequiredComplete = false;
40067
40127
  }
40068
40128
  if (allRequiredComplete) {
@@ -40095,6 +40155,7 @@ const RequiredQuestions = {
40095
40155
  return !pendo._.isUndefined(requiredQuestions) && pendo._.size(requiredQuestions);
40096
40156
  },
40097
40157
  designerListener(pendo) {
40158
+ const requiredQuestions = [];
40098
40159
  const target = pendo.dom.getBody();
40099
40160
  const config = {
40100
40161
  attributeFilter: ['data-layout'],
@@ -40126,7 +40187,7 @@ const RequiredQuestions = {
40126
40187
  if (pendo.dom(`[class*="-poll-question"][data-pendo-poll-id=${dataPendoPollId}]`)[0]) {
40127
40188
  questionText = pendo.dom(`[class*="-poll-question"][data-pendo-poll-id=${dataPendoPollId}]`)[0].textContent;
40128
40189
  }
40129
- if (questionText.includes('{required/}')) {
40190
+ if (pendo._.contains(questionText, '{required/}')) {
40130
40191
  pendo._.each(pendo.dom(`[data-pendo-poll-id=${dataPendoPollId}]:not(.pendo-radio)`), (element) => {
40131
40192
  pendo._.each(pendo.dom(`#${element.id} *:not(".pendo-radio"), #${element.id}:not(".pendo-radio")`), (item) => {
40132
40193
  guideMarkdownUtil.removeMarkdownSyntax(item, '{required/}', '', pendo);
@@ -40139,6 +40200,23 @@ const RequiredQuestions = {
40139
40200
  else {
40140
40201
  pendo.dom(`.bb-text[data-pendo-poll-id=${dataPendoPollId}]`).append(requiredElement);
40141
40202
  }
40203
+ if (pendo._.contains(requiredQuestions, dataPendoPollId)) {
40204
+ let questionIndex = requiredQuestions.indexOf(dataPendoPollId);
40205
+ if (questionIndex !== -1) {
40206
+ requiredQuestions.splice(questionIndex, 1);
40207
+ }
40208
+ }
40209
+ else {
40210
+ requiredQuestions.push(dataPendoPollId);
40211
+ }
40212
+ }
40213
+ else {
40214
+ if (pendo._.contains(requiredQuestions, dataPendoPollId)) {
40215
+ let index = requiredQuestions.indexOf(dataPendoPollId);
40216
+ if (index !== -1) {
40217
+ requiredQuestions.splice(index, 1);
40218
+ }
40219
+ }
40142
40220
  }
40143
40221
  });
40144
40222
  }
@@ -40214,8 +40292,8 @@ const SkipToEligibleStep = {
40214
40292
  },
40215
40293
  test(step, guide, pendo) {
40216
40294
  var _a;
40217
- let guideContainerAriaLabel = (_a = step.guideElement) === null || _a === void 0 ? void 0 : _a.find('#pendo-guide-container').attr('aria-label');
40218
- return !pendo._.isUndefined(guideContainerAriaLabel) && (guideContainerAriaLabel === null || guideContainerAriaLabel === void 0 ? void 0 : guideContainerAriaLabel.includes('{skipStep'));
40295
+ const guideContainerAriaLabel = (_a = step.guideElement) === null || _a === void 0 ? void 0 : _a.find('#pendo-guide-container').attr('aria-label');
40296
+ return pendo._.isString(guideContainerAriaLabel) && guideContainerAriaLabel.indexOf('{skipStep') !== -1;
40219
40297
  },
40220
40298
  designerListener(pendo) {
40221
40299
  const target = pendo.dom.getBody();
@@ -41273,7 +41351,7 @@ function VocPortal() {
41273
41351
  return;
41274
41352
  }
41275
41353
  const validUnits = ['px', '%', 'vh', 'vw'];
41276
- if (!validUnits.includes(widthUnit) || !validUnits.includes(heightUnit)) {
41354
+ if (!pendoGlobal._.contains(validUnits, widthUnit) || !pendoGlobal._.contains(validUnits, heightUnit)) {
41277
41355
  return;
41278
41356
  }
41279
41357
  const width = `${widthValue}${widthUnit}${widthIsImportant ? ' !important' : ''}`;
@@ -45982,7 +46060,7 @@ class IframeManager {
45982
46060
  this.loadListener = cb;
45983
46061
  }
45984
46062
  attachIframe(iframeEl, childSn) {
45985
- var _a2, _b;
46063
+ var _a2, _b, _c;
45986
46064
  this.mutationCb({
45987
46065
  adds: [
45988
46066
  {
@@ -45996,12 +46074,16 @@ class IframeManager {
45996
46074
  attributes: [],
45997
46075
  isAttachIframe: true
45998
46076
  });
45999
- if (this.recordCrossOriginIframes)
46077
+ if (this.recordCrossOriginIframes) {
46000
46078
  (_a2 = iframeEl.contentWindow) == null ? void 0 : _a2.addEventListener(
46001
46079
  "message",
46002
46080
  this.handleMessage.bind(this)
46003
46081
  );
46004
- (_b = this.loadListener) == null ? void 0 : _b.call(this, iframeEl);
46082
+ (_b = iframeEl.contentWindow) == null ? void 0 : _b.addEventListener("pagehide", () => {
46083
+ this.crossOriginIframeMap.delete(iframeEl.contentWindow);
46084
+ });
46085
+ }
46086
+ (_c = this.loadListener) == null ? void 0 : _c.call(this, iframeEl);
46005
46087
  if (iframeEl.contentDocument && iframeEl.contentDocument.adoptedStyleSheets && iframeEl.contentDocument.adoptedStyleSheets.length > 0)
46006
46088
  this.stylesheetManager.adoptStyleSheets(
46007
46089
  iframeEl.contentDocument.adoptedStyleSheets,
@@ -54373,6 +54455,16 @@ function scrubPII(string) {
54373
54455
  return Object.values(PII_PATTERN).reduce((str, pattern) => str.replace(pattern, PII_REPLACEMENT), string);
54374
54456
  }
54375
54457
 
54458
+ /**
54459
+ * Helper function to check if a string includes a substring (legacy IE compatible).
54460
+ *
54461
+ * @param {string} str - The string to search in
54462
+ * @param {string} substring - The substring to search for
54463
+ * @returns {boolean} True if the substring is found, false otherwise
54464
+ */
54465
+ function includes(str, substring) {
54466
+ return str.indexOf(substring) !== -1;
54467
+ }
54376
54468
  /**
54377
54469
  * Determines the type of resource that was blocked based on the blocked URI and CSP directive.
54378
54470
  *
@@ -54391,47 +54483,47 @@ function getResourceType(blockedURI, directive) {
54391
54483
  return 'resource';
54392
54484
  const d = directive.toLowerCase();
54393
54485
  if (blockedURI === 'inline') {
54394
- if (d.includes('script-src-attr')) {
54486
+ if (includes(d, 'script-src-attr')) {
54395
54487
  return 'inline event handler';
54396
54488
  }
54397
- if (d.includes('style-src-attr')) {
54489
+ if (includes(d, 'style-src-attr')) {
54398
54490
  return 'inline style attribute';
54399
54491
  }
54400
- if (d.includes('script')) {
54492
+ if (includes(d, 'script')) {
54401
54493
  return 'inline script';
54402
54494
  }
54403
- if (d.includes('style')) {
54495
+ if (includes(d, 'style')) {
54404
54496
  return 'inline style';
54405
54497
  }
54406
54498
  }
54407
54499
  if (blockedURI === 'eval') {
54408
54500
  return 'eval script execution';
54409
54501
  }
54410
- if (d.includes('worker'))
54502
+ if (includes(d, 'worker'))
54411
54503
  return 'worker';
54412
- if (d.includes('script')) {
54413
- return d.includes('elem') ? 'script element' : 'script';
54504
+ if (includes(d, 'script')) {
54505
+ return includes(d, 'elem') ? 'script element' : 'script';
54414
54506
  }
54415
- if (d.includes('style')) {
54416
- return d.includes('elem') ? 'style element' : 'stylesheet';
54507
+ if (includes(d, 'style')) {
54508
+ return includes(d, 'elem') ? 'style element' : 'stylesheet';
54417
54509
  }
54418
- if (d.includes('img'))
54510
+ if (includes(d, 'img'))
54419
54511
  return 'image';
54420
- if (d.includes('font'))
54512
+ if (includes(d, 'font'))
54421
54513
  return 'font';
54422
- if (d.includes('connect'))
54514
+ if (includes(d, 'connect'))
54423
54515
  return 'network request';
54424
- if (d.includes('media'))
54516
+ if (includes(d, 'media'))
54425
54517
  return 'media resource';
54426
- if (d.includes('frame-ancestors'))
54518
+ if (includes(d, 'frame-ancestors'))
54427
54519
  return 'display of your page in a frame';
54428
- if (d.includes('frame'))
54520
+ if (includes(d, 'frame'))
54429
54521
  return 'frame';
54430
- if (d.includes('manifest'))
54522
+ if (includes(d, 'manifest'))
54431
54523
  return 'manifest';
54432
- if (d.includes('base-uri'))
54524
+ if (includes(d, 'base-uri'))
54433
54525
  return 'base URI';
54434
- if (d.includes('form-action'))
54526
+ if (includes(d, 'form-action'))
54435
54527
  return 'form submission';
54436
54528
  return 'resource';
54437
54529
  }
@@ -54475,7 +54567,7 @@ function getArticle(phrase) {
54475
54567
  if (!phrase || typeof phrase !== 'string')
54476
54568
  return 'A';
54477
54569
  const c = phrase.trim().charAt(0).toLowerCase();
54478
- return 'aeiou'.includes(c) ? 'An' : 'A';
54570
+ return includes('aeiou', c) ? 'An' : 'A';
54479
54571
  }
54480
54572
  /**
54481
54573
  * Returns the original blocked URI when it looks like a URL or scheme,
@@ -54569,7 +54661,7 @@ class ConsoleCaptureBuffer {
54569
54661
  }
54570
54662
  push(event) {
54571
54663
  const { devLogLevel } = event;
54572
- if (!DEV_LOG_LEVELS.includes(devLogLevel))
54664
+ if (!this.pendo._.contains(DEV_LOG_LEVELS, devLogLevel))
54573
54665
  return false;
54574
54666
  this.refillTokens();
54575
54667
  if (this.tokens === 0)
@@ -55774,6 +55866,7 @@ var ConfigReader = (function () {
55774
55866
  addOption('enableAllEmbeddedGuideEvents', [PENDO_CONFIG_SRC], false);
55775
55867
  // Form Validation
55776
55868
  addOption('formValidation', [PENDO_CONFIG_SRC], false);
55869
+ addOption('performanceMetricsEnabled', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
55777
55870
  }
55778
55871
  initializeOptions();
55779
55872
  var sourceGetters = {};
@@ -56054,10 +56147,10 @@ store.subscribe(function (mutation, state) {
56054
56147
  // console.log(mutation, JSON.parse(JSON.stringify(state)));
56055
56148
  });
56056
56149
 
56057
- var EXTENSION_INSTALL_TYPE = 'extension';
56058
- var NATIVE_INSTALL_TYPE = 'native';
56150
+ const EXTENSION_INSTALL_TYPE = 'extension';
56151
+ const NATIVE_INSTALL_TYPE = 'native';
56059
56152
  function getInstallType() {
56060
- var installType = ConfigReader.get('installType') || getPendoConfigFromEnclosingScope().installType;
56153
+ const installType = ConfigReader.get('installType') || getPendoConfigFromEnclosingScope().installType;
56061
56154
  return installType || NATIVE_INSTALL_TYPE;
56062
56155
  }
56063
56156
  function isExtensionAgent() {
@@ -56580,7 +56673,7 @@ class ConsoleTransport {
56580
56673
  }
56581
56674
  params.jzb = jzb;
56582
56675
  const queryString = this.pendo._.map(params, (value, key) => `${key}=${value}`).join('&');
56583
- return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${queryString}`;
56676
+ return `${baseUrl}${baseUrl.indexOf('?') !== -1 ? '&' : '?'}${queryString}`;
56584
56677
  }
56585
56678
  get(url, options) {
56586
56679
  options.method = 'GET';