{"mappings":"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","names":["DEBUG_BUILD","getRating","value","thresholds","bindReporter","callback","metric","reportAllChanges","prevValue","delta","forceReport","WINDOW","GLOBAL_OBJ","generateUniqueID","getNavigationEntry","checkResponseStart","navigationEntry","WINDOW","getActivationStart","getNavigationEntry","initMetric","name","value","navEntry","getNavigationEntry","navigationType","WINDOW","getActivationStart","generateUniqueID","observe","type","callback","opts","po","list","onHidden","cb","onHiddenOrPageHide","event","WINDOW","runOnce","cb","called","firstHiddenTime","initHiddenTime","WINDOW","onVisibilityUpdate","event","removeChangeListeners","addChangeListeners","getVisibilityWatcher","whenActivated","callback","WINDOW","FCPThresholds","onFCP","onReport","opts","whenActivated","visibilityWatcher","getVisibilityWatcher","metric","initMetric","report","po","observe","entries","entry","getActivationStart","bindReporter","CLSThresholds","onCLS","onReport","opts","onFCP","runOnce","metric","initMetric","report","sessionValue","sessionEntries","handleEntries","entries","entry","firstSessionEntry","lastSessionEntry","po","observe","bindReporter","onHidden","FIDThresholds","onFID","onReport","opts","whenActivated","visibilityWatcher","getVisibilityWatcher","metric","initMetric","report","handleEntry","entry","handleEntries","entries","po","observe","bindReporter","onHidden","runOnce","interactionCountEstimate","minKnownInteractionId","maxKnownInteractionId","updateEstimate","entries","po","getInteractionCount","initInteractionCountPolyfill","observe","longestInteractionList","longestInteractionMap","DEFAULT_DURATION_THRESHOLD","prevInteractionCount","getInteractionCountForNavigation","getInteractionCount","estimateP98LongestInteraction","candidateInteractionIndex","MAX_INTERACTIONS_TO_CONSIDER","entryPreProcessingCallbacks","processInteractionEntry","entry","cb","minLongestInteraction","existingInteraction","interaction","a","b","i","whenIdle","cb","rIC","WINDOW","handle","runOnce","onHidden","INPThresholds","onINP","onReport","opts","WINDOW","whenActivated","initInteractionCountPolyfill","metric","initMetric","report","handleEntries","entries","whenIdle","processInteractionEntry","inp","estimateP98LongestInteraction","po","observe","DEFAULT_DURATION_THRESHOLD","bindReporter","onHidden","LCPThresholds","reportedMetricIDs","onLCP","onReport","opts","whenActivated","visibilityWatcher","getVisibilityWatcher","metric","initMetric","report","handleEntries","entries","entry","getActivationStart","po","observe","bindReporter","stopListening","runOnce","type","WINDOW","whenIdle","onHidden","TTFBThresholds","whenReady","callback","WINDOW","whenActivated","onTTFB","onReport","opts","metric","initMetric","report","bindReporter","navigationEntry","getNavigationEntry","getActivationStart","handlers","instrumented","_previousCls","_previousFid","_previousLcp","_previousTtfb","_previousInp","addClsInstrumentationHandler","callback","stopOnCallback","addMetricObserver","instrumentCls","addLcpInstrumentationHandler","instrumentLcp","addFidInstrumentationHandler","instrumentFid","addTtfbInstrumentationHandler","instrumentTtfb","addInpInstrumentationHandler","instrumentInp","addPerformanceInstrumentationHandler","type","addHandler","instrumentPerformanceObserver","getCleanupCallback","triggerHandlers","data","typeHandlers","handler","e","DEBUG_BUILD","logger","getFunctionName","onCLS","metric","onFID","onLCP","onTTFB","onINP","instrumentFn","previousValue","stopListening","options","observe","entries","index","isPerformanceEventTiming","entry","isMeasurementValue","value","startAndEndSpan","parentSpan","startTimeInSeconds","endTime","ctx","parentStartTime","spanToJSON","withActiveSpan","span","startInactiveSpan","startStandaloneWebVitalSpan","options","client","getClient","name","transaction","passedAttributes","startTime","release","environment","sendDefaultPii","replayId","scope","getCurrentScope","user","userDisplay","profileId","attributes","WINDOW","getBrowserPerformanceAPI","msToSec","time","extractNetworkProtocol","nextHopProtocol","version","_name","char","trackClsAsStandaloneSpan","standaloneCLsValue","standaloneClsEntry","pageloadSpanId","supportsLayoutShift","sentSpan","_collectClsOnce","sendStandaloneClsSpan","cleanupClsHandler","addClsInstrumentationHandler","metric","entry","onHidden","client","getClient","unsubscribeStartNavigation","activeSpan","getActiveSpan","rootSpan","getRootSpan","spanToJSON","clsValue","DEBUG_BUILD","logger","startTime","msToSec","browserPerformanceTimeOrigin","routeName","getCurrentScope","name","htmlTreeAsString","attributes","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME","span","startStandaloneWebVitalSpan","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE","MAX_INT_AS_BYTES","_performanceCursor","_measurements","_lcpEntry","_clsEntry","startTrackingWebVitals","recordClsStandaloneSpans","performance","getBrowserPerformanceAPI","browserPerformanceTimeOrigin","WINDOW","fidCleanupCallback","_trackFID","lcpCleanupCallback","_trackLCP","ttfbCleanupCallback","_trackTtfb","clsCleanupCallback","trackClsAsStandaloneSpan","_trackCLS","startTrackingLongTasks","addPerformanceInstrumentationHandler","entries","parent","getActiveSpan","parentOp","parentStartTimestamp","spanToJSON","entry","startTime","msToSec","duration","startAndEndSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startTrackingLongAnimationFrames","list","attributes","initialScript","invoker","invokerType","sourceURL","sourceFunctionName","sourceCharPosition","startTrackingInteractions","spanOptions","htmlTreeAsString","componentName","getComponentName","addClsInstrumentationHandler","metric","addLcpInstrumentationHandler","addFidInstrumentationHandler","timeOrigin","addTtfbInstrumentationHandler","addPerformanceEntries","span","options","origin","performanceEntries","op","transactionStartTime","_addNavigationSpans","_addMeasureSpans","firstHidden","getVisibilityWatcher","shouldRecord","_addResourceSpans","_trackNavigator","_addTtfbRequestTimeToMeasurements","fidMark","measurementName","measurement","setMeasurement","getActivationStart","_setWebVitalAttributes","navEntry","getNavigationEntry","requestTime","measureStartTimestamp","startTimeStamp","measureEndTimestamp","event","_addPerformanceNavigationTiming","_addRequest","name","eventEnd","_getEndPropertyNameForNavigationTiming","end","start","requestStartTimestamp","responseEndTimestamp","responseStartTimestamp","resourceUrl","parsedUrl","parseUrl","setResourceEntrySizeData","deliveryType","renderBlockingStatus","version","extractNetworkProtocol","startTimestamp","endTimestamp","navigator","connection","isMeasurementValue","source","index","key","dataKey","entryVal","responseStart","requestStart","DEBOUNCE_DURATION","debounceTimerID","lastCapturedEventType","lastCapturedEventTargetId","addClickKeypressInstrumentationHandler","handler","addHandler","maybeInstrument","instrumentDOM","WINDOW","triggerDOMHandler","triggerHandlers","globalDOMEventHandler","makeDOMEventHandler","target","proto","fill","originalAddEventListener","type","listener","options","handlers","handlerForType","originalRemoveEventListener","isSimilarToLastCapturedEvent","event","shouldSkipDOMEvent","eventType","globalListener","getEventTarget","addNonEnumerableProperty","uuid4","name","lastHref","addHistoryInstrumentationHandler","handler","type","addHandler","maybeInstrument","instrumentHistory","WINDOW","to","from","triggerHandlers","supportsHistory","historyReplacementFunction","originalHistoryFunction","args","url","fill","cachedImplementations","getNativeImplementation","name","cached","impl","WINDOW","isNativeFunction","document","sandbox","contentWindow","e","DEBUG_BUILD","logger","clearCachedImplementation","fetch","rest","setTimeout","SENTRY_XHR_DATA_KEY","addXhrInstrumentationHandler","handler","addHandler","maybeInstrument","instrumentXHR","WINDOW","xhrproto","originalOpen","xhrOpenThisArg","xhrOpenArgArray","virtualError","startTimestamp","timestampInSeconds","method","isString","url","parseXhrUrlArg","onreadystatechangeHandler","xhrInfo","handlerData","triggerHandlers","originalOnreadystatechange","onreadystatechangeThisArg","onreadystatechangeArgArray","originalSetRequestHeader","setRequestHeaderThisArg","setRequestHeaderArgArray","header","value","originalSend","sendThisArg","sendArgArray","sentryXhrData","serializeFormData","formData","getBodyString","body","_logger","logger","error","DEBUG_BUILD","getFetchRequestArgBody","fetchArgs","LAST_INTERACTIONS","INTERACTIONS_SPAN_MAP","startTrackingINP","getBrowserPerformanceAPI","browserPerformanceTimeOrigin","inpCallback","_trackINP","INP_ENTRY_MAP","addInpInstrumentationHandler","metric","entry","interactionId","interactionType","startTime","msToSec","duration","activeSpan","getActiveSpan","rootSpan","getRootSpan","spanToUse","routeName","spanToJSON","getCurrentScope","name","htmlTreeAsString","attributes","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME","span","startStandaloneWebVitalSpan","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE","registerInpInteractionListener","handleEntries","entries","activeRootSpan","isPerformanceEventTiming","last","addPerformanceInstrumentationHandler"],"sources":["../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/debug-build.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/bindReporter.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/types.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/generateUniqueID.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/getActivationStart.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/initMetric.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/observe.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/onHidden.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/runOnce.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/whenActivated.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/onFCP.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getCLS.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getFID.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/interactions.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/whenIdle.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getINP.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getLCP.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/onTTFB.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/instrument.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/utils.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/cls.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/browserMetrics.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/instrument/dom.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/instrument/history.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/getNativeImplementation.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/instrument/xhr.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/networkUtils.ts","../esm/npm/@sentry-internal/browser-utils@9.17.0/node_modules/@sentry-internal/browser-utils/src/metrics/inp.ts"],"sourcesContent":["declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { MetricRatingThresholds, MetricType } from '../types';\n\nconst getRating = (value: number, thresholds: MetricRatingThresholds): MetricType['rating'] =\u003e {\n  if (value \u003e thresholds[1]) {\n    return 'poor';\n  }\n  if (value \u003e thresholds[0]) {\n    return 'needs-improvement';\n  }\n  return 'good';\n};\n\nexport const bindReporter = \u003cMetricName extends MetricType['name']\u003e(\n  callback: (metric: Extract\u003cMetricType, { name: MetricName }\u003e) =\u003e void,\n  metric: Extract\u003cMetricType, { name: MetricName }\u003e,\n  thresholds: MetricRatingThresholds,\n  reportAllChanges?: boolean,\n) =\u003e {\n  let prevValue: number;\n  let delta: number;\n  return (forceReport?: boolean) =\u003e {\n    if (metric.value \u003e= 0) {\n      if (forceReport || reportAllChanges) {\n        delta = metric.value - (prevValue || 0);\n\n        // Report the metric if there's a non-zero delta or if no previous\n        // value exists (which can happen in the case of the document becoming\n        // hidden when the metric value is 0).\n        // See: https://github.com/GoogleChrome/web-vitals/issues/14\n        if (delta || prevValue === undefined) {\n          prevValue = metric.value;\n          metric.delta = delta;\n          metric.rating = getRating(metric.value, thresholds);\n          callback(metric);\n        }\n      }\n    }\n  };\n};\n","import type {\n  FetchBreadcrumbHint,\n  HandlerDataFetch,\n  SentryWrappedXMLHttpRequest,\n  XhrBreadcrumbHint,\n} from '@sentry/core';\nimport { GLOBAL_OBJ } from '@sentry/core';\n\nexport const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ \u0026\n  // document is not available in all browser environments (webworkers). We make it optional so you have to explicitly check for it\n  Omit\u003cWindow, 'document'\u003e \u0026\n  Partial\u003cPick\u003cWindow, 'document'\u003e\u003e;\n\nexport type NetworkMetaWarning =\n  | 'MAYBE_JSON_TRUNCATED'\n  | 'TEXT_TRUNCATED'\n  | 'URL_SKIPPED'\n  | 'BODY_PARSE_ERROR'\n  | 'BODY_PARSE_TIMEOUT'\n  | 'UNPARSEABLE_BODY_TYPE';\n\ntype RequestBody = null | Blob | BufferSource | FormData | URLSearchParams | string;\n\nexport type XhrHint = XhrBreadcrumbHint \u0026 {\n  xhr: XMLHttpRequest \u0026 SentryWrappedXMLHttpRequest;\n  input?: RequestBody;\n};\nexport type FetchHint = FetchBreadcrumbHint \u0026 {\n  input: HandlerDataFetch['args'];\n  response: Response;\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Performantly generate a unique, 30-char string by combining a version\n * number, the current timestamp with a 13-digit number integer.\n * @return {string}\n */\nexport const generateUniqueID = () =\u003e {\n  return `v4-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;\n};\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\n// sentry-specific change:\n// add optional param to not check for responseStart (see comment below)\nexport const getNavigationEntry = (checkResponseStart = true): PerformanceNavigationTiming | void =\u003e {\n  const navigationEntry = WINDOW.performance?.getEntriesByType?.('navigation')[0];\n  // Check to ensure the `responseStart` property is present and valid.\n  // In some cases no value is reported by the browser (for\n  // privacy/security reasons), and in other cases (bugs) the value is\n  // negative or is larger than the current page time. Ignore these cases:\n  // https://github.com/GoogleChrome/web-vitals/issues/137\n  // https://github.com/GoogleChrome/web-vitals/issues/162\n  // https://github.com/GoogleChrome/web-vitals/issues/275\n  if (\n    // sentry-specific change:\n    // We don't want to check for responseStart for our own use of `getNavigationEntry`\n    !checkResponseStart ||\n    (navigationEntry \u0026\u0026 navigationEntry.responseStart \u003e 0 \u0026\u0026 navigationEntry.responseStart \u003c performance.now())\n  ) {\n    return navigationEntry;\n  }\n};\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getNavigationEntry } from './getNavigationEntry';\n\nexport const getActivationStart = (): number =\u003e {\n  const navEntry = getNavigationEntry();\n  return navEntry?.activationStart || 0;\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\nimport type { MetricType } from '../types';\nimport { generateUniqueID } from './generateUniqueID';\nimport { getActivationStart } from './getActivationStart';\nimport { getNavigationEntry } from './getNavigationEntry';\n\nexport const initMetric = \u003cMetricName extends MetricType['name']\u003e(name: MetricName, value?: number) =\u003e {\n  const navEntry = getNavigationEntry();\n  let navigationType: MetricType['navigationType'] = 'navigate';\n\n  if (navEntry) {\n    if (WINDOW.document?.prerendering || getActivationStart() \u003e 0) {\n      navigationType = 'prerender';\n    } else if (WINDOW.document?.wasDiscarded) {\n      navigationType = 'restore';\n    } else if (navEntry.type) {\n      navigationType = navEntry.type.replace(/_/g, '-') as MetricType['navigationType'];\n    }\n  }\n\n  // Use `entries` type specific for the metric.\n  const entries: Extract\u003cMetricType, { name: MetricName }\u003e['entries'] = [];\n\n  return {\n    name,\n    value: typeof value === 'undefined' ? -1 : value,\n    rating: 'good' as const, // If needed, will be updated when reported. `const` to keep the type from widening to `string`.\n    delta: 0,\n    entries,\n    id: generateUniqueID(),\n    navigationType,\n  };\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ninterface PerformanceEntryMap {\n  event: PerformanceEventTiming[];\n  'first-input': PerformanceEventTiming[];\n  'layout-shift': LayoutShift[];\n  'largest-contentful-paint': LargestContentfulPaint[];\n  'long-animation-frame': PerformanceLongAnimationFrameTiming[];\n  paint: PerformancePaintTiming[];\n  navigation: PerformanceNavigationTiming[];\n  resource: PerformanceResourceTiming[];\n  // Sentry-specific change:\n  // We add longtask as a supported entry type as we use this in\n  // our `instrumentPerformanceObserver` function also observes 'longtask'\n  // entries.\n  longtask: PerformanceEntry[];\n}\n\n/**\n * Takes a performance entry type and a callback function, and creates a\n * `PerformanceObserver` instance that will observe the specified entry type\n * with buffering enabled and call the callback _for each entry_.\n *\n * This function also feature-detects entry support and wraps the logic in a\n * try/catch to avoid errors in unsupporting browsers.\n */\nexport const observe = \u003cK extends keyof PerformanceEntryMap\u003e(\n  type: K,\n  callback: (entries: PerformanceEntryMap[K]) =\u003e void,\n  opts?: PerformanceObserverInit,\n): PerformanceObserver | undefined =\u003e {\n  try {\n    if (PerformanceObserver.supportedEntryTypes.includes(type)) {\n      const po = new PerformanceObserver(list =\u003e {\n        // Delay by a microtask to workaround a bug in Safari where the\n        // callback is invoked immediately, rather than in a separate task.\n        // See: https://github.com/GoogleChrome/web-vitals/issues/277\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        Promise.resolve().then(() =\u003e {\n          callback(list.getEntries() as PerformanceEntryMap[K]);\n        });\n      });\n      po.observe(\n        Object.assign(\n          {\n            type,\n            buffered: true,\n          },\n          opts || {},\n        ) as PerformanceObserverInit,\n      );\n      return po;\n    }\n  } catch (e) {\n    // Do nothing.\n  }\n  return;\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\nexport interface OnHiddenCallback {\n  (event: Event): void;\n}\n\n// Sentry-specific change:\n// This function's logic was NOT updated to web-vitals 4.2.4 but we continue\n// to use the web-vitals 3.5.2 due to us having stricter browser support.\n// PR with context that made the changes: https://github.com/GoogleChrome/web-vitals/pull/442/files#r1530492402\n// The PR removed listening to the `pagehide` event, in favour of only listening to `visibilitychange` event.\n// This is \"more correct\" but some browsers we still support (Safari 12.1-14.0) don't fully support `visibilitychange`\n// or have known bugs w.r.t the `visibilitychange` event.\n// TODO (v9): If we decide to drop support for Safari 12.1-14.0, we can use the logic from web-vitals 4.2.4\n// In this case, we also need to update the integration tests that currently trigger the `pagehide` event to\n// simulate the page being hidden.\nexport const onHidden = (cb: OnHiddenCallback) =\u003e {\n  const onHiddenOrPageHide = (event: Event) =\u003e {\n    if (event.type === 'pagehide' || WINDOW.document?.visibilityState === 'hidden') {\n      cb(event);\n    }\n  };\n\n  if (WINDOW.document) {\n    addEventListener('visibilitychange', onHiddenOrPageHide, true);\n    // Some browsers have buggy implementations of visibilitychange,\n    // so we use pagehide in addition, just to be safe.\n    addEventListener('pagehide', onHiddenOrPageHide, true);\n  }\n};\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const runOnce = (cb: () =\u003e void) =\u003e {\n  let called = false;\n  return () =\u003e {\n    if (!called) {\n      cb();\n      called = true;\n    }\n  };\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\nlet firstHiddenTime = -1;\n\nconst initHiddenTime = () =\u003e {\n  // If the document is hidden when this code runs, assume it was always\n  // hidden and the page was loaded in the background, with the one exception\n  // that visibility state is always 'hidden' during prerendering, so we have\n  // to ignore that case until prerendering finishes (see: `prerenderingchange`\n  // event logic below).\n  return WINDOW.document!.visibilityState === 'hidden' \u0026\u0026 !WINDOW.document!.prerendering ? 0 : Infinity;\n};\n\nconst onVisibilityUpdate = (event: Event) =\u003e {\n  // If the document is 'hidden' and no previous hidden timestamp has been\n  // set, update it based on the current event data.\n  if (WINDOW.document!.visibilityState === 'hidden' \u0026\u0026 firstHiddenTime \u003e -1) {\n    // If the event is a 'visibilitychange' event, it means the page was\n    // visible prior to this change, so the event timestamp is the first\n    // hidden time.\n    // However, if the event is not a 'visibilitychange' event, then it must\n    // be a 'prerenderingchange' event, and the fact that the document is\n    // still 'hidden' from the above check means the tab was activated\n    // in a background state and so has always been hidden.\n    firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0;\n\n    // Remove all listeners now that a `firstHiddenTime` value has been set.\n    removeChangeListeners();\n  }\n};\n\nconst addChangeListeners = () =\u003e {\n  addEventListener('visibilitychange', onVisibilityUpdate, true);\n  // IMPORTANT: when a page is prerendering, its `visibilityState` is\n  // 'hidden', so in order to account for cases where this module checks for\n  // visibility during prerendering, an additional check after prerendering\n  // completes is also required.\n  addEventListener('prerenderingchange', onVisibilityUpdate, true);\n};\n\nconst removeChangeListeners = () =\u003e {\n  removeEventListener('visibilitychange', onVisibilityUpdate, true);\n  removeEventListener('prerenderingchange', onVisibilityUpdate, true);\n};\n\nexport const getVisibilityWatcher = () =\u003e {\n  if (WINDOW.document \u0026\u0026 firstHiddenTime \u003c 0) {\n    // If the document is hidden when this code runs, assume it was hidden\n    // since navigation start. This isn't a perfect heuristic, but it's the\n    // best we can do until an API is available to support querying past\n    // visibilityState.\n    firstHiddenTime = initHiddenTime();\n    addChangeListeners();\n  }\n  return {\n    get firstHiddenTime() {\n      return firstHiddenTime;\n    },\n  };\n};\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\nexport const whenActivated = (callback: () =\u003e void) =\u003e {\n  if (WINDOW.document?.prerendering) {\n    addEventListener('prerenderingchange', () =\u003e callback(), true);\n  } else {\n    callback();\n  }\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { whenActivated } from './lib/whenActivated';\nimport type { FCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */\nexport const FCPThresholds: MetricRatingThresholds = [1800, 3000];\n\n/**\n * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `paint` performance entry used to determine the value. The reported\n * value is a `DOMHighResTimeStamp`.\n */\nexport const onFCP = (onReport: (metric: FCPMetric) =\u003e void, opts: ReportOpts = {}) =\u003e {\n  whenActivated(() =\u003e {\n    const visibilityWatcher = getVisibilityWatcher();\n    const metric = initMetric('FCP');\n    let report: ReturnType\u003ctypeof bindReporter\u003e;\n\n    const handleEntries = (entries: FCPMetric['entries']) =\u003e {\n      entries.forEach(entry =\u003e {\n        if (entry.name === 'first-contentful-paint') {\n          po!.disconnect();\n\n          // Only report if the page wasn't hidden prior to the first paint.\n          if (entry.startTime \u003c visibilityWatcher.firstHiddenTime) {\n            // The activationStart reference is used because FCP should be\n            // relative to page activation rather than navigation start if the\n            // page was prerendered. But in cases where `activationStart` occurs\n            // after the FCP, this time should be clamped at 0.\n            metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n            metric.entries.push(entry);\n            report(true);\n          }\n        }\n      });\n    };\n\n    const po = observe('paint', handleEntries);\n\n    if (po) {\n      report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);\n    }\n  });\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { runOnce } from './lib/runOnce';\nimport { onFCP } from './onFCP';\nimport type { CLSMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */\nexport const CLSThresholds: MetricRatingThresholds = [0.1, 0.25];\n\n/**\n * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and\n * calls the `callback` function once the value is ready to be reported, along\n * with all `layout-shift` performance entries that were used in the metric\n * value calculation. The reported value is a `double` (corresponding to a\n * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** CLS should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nexport const onCLS = (onReport: (metric: CLSMetric) =\u003e void, opts: ReportOpts = {}) =\u003e {\n  // Start monitoring FCP so we can only report CLS if FCP is also reported.\n  // Note: this is done to match the current behavior of CrUX.\n  onFCP(\n    runOnce(() =\u003e {\n      const metric = initMetric('CLS', 0);\n      let report: ReturnType\u003ctypeof bindReporter\u003e;\n\n      let sessionValue = 0;\n      let sessionEntries: LayoutShift[] = [];\n\n      const handleEntries = (entries: LayoutShift[]) =\u003e {\n        entries.forEach(entry =\u003e {\n          // Only count layout shifts without recent user input.\n          if (!entry.hadRecentInput) {\n            const firstSessionEntry = sessionEntries[0];\n            const lastSessionEntry = sessionEntries[sessionEntries.length - 1];\n\n            // If the entry occurred less than 1 second after the previous entry\n            // and less than 5 seconds after the first entry in the session,\n            // include the entry in the current session. Otherwise, start a new\n            // session.\n            if (\n              sessionValue \u0026\u0026\n              firstSessionEntry \u0026\u0026\n              lastSessionEntry \u0026\u0026\n              entry.startTime - lastSessionEntry.startTime \u003c 1000 \u0026\u0026\n              entry.startTime - firstSessionEntry.startTime \u003c 5000\n            ) {\n              sessionValue += entry.value;\n              sessionEntries.push(entry);\n            } else {\n              sessionValue = entry.value;\n              sessionEntries = [entry];\n            }\n          }\n        });\n\n        // If the current session value is larger than the current CLS value,\n        // update CLS and the entries contributing to it.\n        if (sessionValue \u003e metric.value) {\n          metric.value = sessionValue;\n          metric.entries = sessionEntries;\n          report();\n        }\n      };\n\n      const po = observe('layout-shift', handleEntries);\n      if (po) {\n        report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);\n\n        onHidden(() =\u003e {\n          handleEntries(po.takeRecords() as CLSMetric['entries']);\n          report(true);\n        });\n\n        // Queue a task to report (if nothing else triggers a report first).\n        // This allows CLS to be reported as soon as FCP fires when\n        // `reportAllChanges` is true.\n        setTimeout(report, 0);\n      }\n    }),\n  );\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport type { FIDMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */\nexport const FIDThresholds: MetricRatingThresholds = [100, 300];\n\n/**\n * Calculates the [FID](https://web.dev/articles/fid) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `first-input` performance entry used to determine the value. The\n * reported value is a `DOMHighResTimeStamp`.\n *\n * _**Important:** since FID is only reported after the user interacts with the\n * page, it's possible that it will not be reported for some page loads._\n */\nexport const onFID = (onReport: (metric: FIDMetric) =\u003e void, opts: ReportOpts = {}) =\u003e {\n  whenActivated(() =\u003e {\n    const visibilityWatcher = getVisibilityWatcher();\n    const metric = initMetric('FID');\n    // eslint-disable-next-line prefer-const\n    let report: ReturnType\u003ctypeof bindReporter\u003e;\n\n    const handleEntry = (entry: PerformanceEventTiming): void =\u003e {\n      // Only report if the page wasn't hidden prior to the first input.\n      if (entry.startTime \u003c visibilityWatcher.firstHiddenTime) {\n        metric.value = entry.processingStart - entry.startTime;\n        metric.entries.push(entry);\n        report(true);\n      }\n    };\n\n    const handleEntries = (entries: FIDMetric['entries']) =\u003e {\n      (entries as PerformanceEventTiming[]).forEach(handleEntry);\n    };\n\n    const po = observe('first-input', handleEntries);\n\n    report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);\n\n    if (po) {\n      onHidden(\n        runOnce(() =\u003e {\n          handleEntries(po.takeRecords() as FIDMetric['entries']);\n          po.disconnect();\n        }),\n      );\n    }\n  });\n};\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { observe } from '../observe';\n\ndeclare global {\n  interface Performance {\n    interactionCount: number;\n  }\n}\n\nlet interactionCountEstimate = 0;\nlet minKnownInteractionId = Infinity;\nlet maxKnownInteractionId = 0;\n\nconst updateEstimate = (entries: PerformanceEventTiming[]) =\u003e {\n  entries.forEach(e =\u003e {\n    if (e.interactionId) {\n      minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId);\n      maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId);\n\n      interactionCountEstimate = maxKnownInteractionId ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1 : 0;\n    }\n  });\n};\n\nlet po: PerformanceObserver | undefined;\n\n/**\n * Returns the `interactionCount` value using the native API (if available)\n * or the polyfill estimate in this module.\n */\nexport const getInteractionCount = (): number =\u003e {\n  return po ? interactionCountEstimate : performance.interactionCount || 0;\n};\n\n/**\n * Feature detects native support or initializes the polyfill if needed.\n */\nexport const initInteractionCountPolyfill = (): void =\u003e {\n  if ('interactionCount' in performance || po) return;\n\n  po = observe('event', updateEstimate, {\n    type: 'event',\n    buffered: true,\n    durationThreshold: 0,\n  } as PerformanceObserverInit);\n};\n","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInteractionCount } from './polyfills/interactionCountPolyfill';\n\ninterface Interaction {\n  id: number;\n  latency: number;\n  entries: PerformanceEventTiming[];\n}\n\ninterface EntryPreProcessingHook {\n  (entry: PerformanceEventTiming): void;\n}\n\n// A list of longest interactions on the page (by latency) sorted so the\n// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long.\nexport const longestInteractionList: Interaction[] = [];\n\n// A mapping of longest interactions by their interaction ID.\n// This is used for faster lookup.\nexport const longestInteractionMap: Map\u003cnumber, Interaction\u003e = new Map();\n\n// The default `durationThreshold` used across this library for observing\n// `event` entries via PerformanceObserver.\nexport const DEFAULT_DURATION_THRESHOLD = 40;\n\n// Used to store the interaction count after a bfcache restore, since p98\n// interaction latencies should only consider the current navigation.\nlet prevInteractionCount = 0;\n\n/**\n * Returns the interaction count since the last bfcache restore (or for the\n * full page lifecycle if there were no bfcache restores).\n */\nconst getInteractionCountForNavigation = () =\u003e {\n  return getInteractionCount() - prevInteractionCount;\n};\n\nexport const resetInteractions = () =\u003e {\n  prevInteractionCount = getInteractionCount();\n  longestInteractionList.length = 0;\n  longestInteractionMap.clear();\n};\n\n/**\n * Returns the estimated p98 longest interaction based on the stored\n * interaction candidates and the interaction count for the current page.\n */\nexport const estimateP98LongestInteraction = () =\u003e {\n  const candidateInteractionIndex = Math.min(\n    longestInteractionList.length - 1,\n    Math.floor(getInteractionCountForNavigation() / 50),\n  );\n\n  return longestInteractionList[candidateInteractionIndex];\n};\n\n// To prevent unnecessary memory usage on pages with lots of interactions,\n// store at most 10 of the longest interactions to consider as INP candidates.\nconst MAX_INTERACTIONS_TO_CONSIDER = 10;\n\n/**\n * A list of callback functions to run before each entry is processed.\n * Exposing this list allows the attribution build to hook into the\n * entry processing pipeline.\n */\nexport const entryPreProcessingCallbacks: EntryPreProcessingHook[] = [];\n\n/**\n * Takes a performance entry and adds it to the list of worst interactions\n * if its duration is long enough to make it among the worst. If the\n * entry is part of an existing interaction, it is merged and the latency\n * and entries list is updated as needed.\n */\nexport const processInteractionEntry = (entry: PerformanceEventTiming) =\u003e {\n  entryPreProcessingCallbacks.forEach(cb =\u003e cb(entry));\n\n  // Skip further processing for entries that cannot be INP candidates.\n  if (!(entry.interactionId || entry.entryType === 'first-input')) return;\n\n  // The least-long of the 10 longest interactions.\n  const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];\n\n  const existingInteraction = longestInteractionMap.get(entry.interactionId!);\n\n  // Only process the entry if it's possibly one of the ten longest,\n  // or if it's part of an existing interaction.\n  if (\n    existingInteraction ||\n    longestInteractionList.length \u003c MAX_INTERACTIONS_TO_CONSIDER ||\n    (minLongestInteraction \u0026\u0026 entry.duration \u003e minLongestInteraction.latency)\n  ) {\n    // If the interaction already exists, update it. Otherwise create one.\n    if (existingInteraction) {\n      // If the new entry has a longer duration, replace the old entries,\n      // otherwise add to the array.\n      if (entry.duration \u003e existingInteraction.latency) {\n        existingInteraction.entries = [entry];\n        existingInteraction.latency = entry.duration;\n      } else if (\n        entry.duration === existingInteraction.latency \u0026\u0026\n        entry.startTime === existingInteraction.entries[0]?.startTime\n      ) {\n        existingInteraction.entries.push(entry);\n      }\n    } else {\n      const interaction = {\n        id: entry.interactionId!,\n        latency: entry.duration,\n        entries: [entry],\n      };\n      longestInteractionMap.set(interaction.id, interaction);\n      longestInteractionList.push(interaction);\n    }\n\n    // Sort the entries by latency (descending) and keep only the top ten.\n    longestInteractionList.sort((a, b) =\u003e b.latency - a.latency);\n    if (longestInteractionList.length \u003e MAX_INTERACTIONS_TO_CONSIDER) {\n      longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i =\u003e longestInteractionMap.delete(i.id));\n    }\n  }\n};\n","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\nimport { onHidden } from './onHidden';\nimport { runOnce } from './runOnce';\n\n/**\n * Runs the passed callback during the next idle period, or immediately\n * if the browser's visibility state is (or becomes) hidden.\n */\nexport const whenIdle = (cb: () =\u003e void): number =\u003e {\n  const rIC = WINDOW.requestIdleCallback || WINDOW.setTimeout;\n\n  let handle = -1;\n  // eslint-disable-next-line no-param-reassign\n  cb = runOnce(cb) as () =\u003e void;\n  // If the document is hidden, run the callback immediately, otherwise\n  // race an idle callback with the next `visibilitychange` event.\n  if (WINDOW.document?.visibilityState === 'hidden') {\n    cb();\n  } else {\n    handle = rIC(cb);\n    onHidden(cb);\n  }\n  return handle;\n};\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../types';\nimport { bindReporter } from './lib/bindReporter';\nimport { initMetric } from './lib/initMetric';\nimport { DEFAULT_DURATION_THRESHOLD, estimateP98LongestInteraction, processInteractionEntry } from './lib/interactions';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdle } from './lib/whenIdle';\nimport type { INPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */\nexport const INPThresholds: MetricRatingThresholds = [200, 500];\n\n/**\n * Calculates the [INP](https://web.dev/articles/inp) value for the current\n * page and calls the `callback` function once the value is ready, along with\n * the `event` performance entries reported for that interaction. The reported\n * value is a `DOMHighResTimeStamp`.\n *\n * A custom `durationThreshold` configuration option can optionally be passed to\n * control what `event-timing` entries are considered for INP reporting. The\n * default threshold is `40`, which means INP scores of less than 40 are\n * reported as 0. Note that this will not affect your 75th percentile INP value\n * unless that value is also less than 40 (well below the recommended\n * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** INP should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nexport const onINP = (onReport: (metric: INPMetric) =\u003e void, opts: ReportOpts = {}) =\u003e {\n  // Return if the browser doesn't support all APIs needed to measure INP.\n  if (!('PerformanceEventTiming' in WINDOW \u0026\u0026 'interactionId' in PerformanceEventTiming.prototype)) {\n    return;\n  }\n\n  whenActivated(() =\u003e {\n    // TODO(philipwalton): remove once the polyfill is no longer needed.\n    initInteractionCountPolyfill();\n\n    const metric = initMetric('INP');\n    // eslint-disable-next-line prefer-const\n    let report: ReturnType\u003ctypeof bindReporter\u003e;\n\n    const handleEntries = (entries: INPMetric['entries']) =\u003e {\n      // Queue the `handleEntries()` callback in the next idle task.\n      // This is needed to increase the chances that all event entries that\n      // occurred between the user interaction and the next paint\n      // have been dispatched. Note: there is currently an experiment\n      // running in Chrome (EventTimingKeypressAndCompositionInteractionId)\n      // 123+ that if rolled out fully may make this no longer necessary.\n      whenIdle(() =\u003e {\n        entries.forEach(processInteractionEntry);\n\n        const inp = estimateP98LongestInteraction();\n\n        if (inp \u0026\u0026 inp.latency !== metric.value) {\n          metric.value = inp.latency;\n          metric.entries = inp.entries;\n          report();\n        }\n      });\n    };\n\n    const po = observe('event', handleEntries, {\n      // Event Timing entries have their durations rounded to the nearest 8ms,\n      // so a duration of 40ms would be any event that spans 2.5 or more frames\n      // at 60Hz. This threshold is chosen to strike a balance between usefulness\n      // and performance. Running this callback for any interaction that spans\n      // just one or two frames is likely not worth the insight that could be\n      // gained.\n      durationThreshold: opts.durationThreshold != null ? opts.durationThreshold : DEFAULT_DURATION_THRESHOLD,\n    });\n\n    report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);\n\n    if (po) {\n      // Also observe entries of type `first-input`. This is useful in cases\n      // where the first interaction is less than the `durationThreshold`.\n      po.observe({ type: 'first-input', buffered: true });\n\n      onHidden(() =\u003e {\n        handleEntries(po.takeRecords() as INPMetric['entries']);\n        report(true);\n      });\n    }\n  });\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../types';\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdle } from './lib/whenIdle';\nimport type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds: MetricRatingThresholds = [2500, 4000];\n\nconst reportedMetricIDs: Record\u003cstring, boolean\u003e = {};\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport: (metric: LCPMetric) =\u003e void, opts: ReportOpts = {}) =\u003e {\n  whenActivated(() =\u003e {\n    const visibilityWatcher = getVisibilityWatcher();\n    const metric = initMetric('LCP');\n    let report: ReturnType\u003ctypeof bindReporter\u003e;\n\n    const handleEntries = (entries: LCPMetric['entries']) =\u003e {\n      // If reportAllChanges is set then call this function for each entry,\n      // otherwise only consider the last one.\n      if (!opts.reportAllChanges) {\n        // eslint-disable-next-line no-param-reassign\n        entries = entries.slice(-1);\n      }\n\n      entries.forEach(entry =\u003e {\n        // Only report if the page wasn't hidden prior to LCP.\n        if (entry.startTime \u003c visibilityWatcher.firstHiddenTime) {\n          // The startTime attribute returns the value of the renderTime if it is\n          // not 0, and the value of the loadTime otherwise. The activationStart\n          // reference is used because LCP should be relative to page activation\n          // rather than navigation start if the page was pre-rendered. But in cases\n          // where `activationStart` occurs after the LCP, this time should be\n          // clamped at 0.\n          metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n          metric.entries = [entry];\n          report();\n        }\n      });\n    };\n\n    const po = observe('largest-contentful-paint', handleEntries);\n\n    if (po) {\n      report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n      const stopListening = runOnce(() =\u003e {\n        if (!reportedMetricIDs[metric.id]) {\n          handleEntries(po.takeRecords() as LCPMetric['entries']);\n          po.disconnect();\n          reportedMetricIDs[metric.id] = true;\n          report(true);\n        }\n      });\n\n      // Stop listening after input. Note: while scrolling is an input that\n      // stops LCP observation, it's unreliable since it can be programmatically\n      // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75\n      ['keydown', 'click'].forEach(type =\u003e {\n        // Wrap in a setTimeout so the callback is run in a separate task\n        // to avoid extending the keyboard/click handler to reduce INP impact\n        // https://github.com/GoogleChrome/web-vitals/issues/383\n        if (WINDOW.document) {\n          addEventListener(type, () =\u003e whenIdle(stopListening as () =\u003e void), {\n            once: true,\n            capture: true,\n          });\n        }\n      });\n\n      onHidden(stopListening);\n    }\n  });\n};\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../types';\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getNavigationEntry } from './lib/getNavigationEntry';\nimport { initMetric } from './lib/initMetric';\nimport { whenActivated } from './lib/whenActivated';\nimport type { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types';\n\n/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */\nexport const TTFBThresholds: MetricRatingThresholds = [800, 1800];\n\n/**\n * Runs in the next task after the page is done loading and/or prerendering.\n * @param callback\n */\nconst whenReady = (callback: () =\u003e void) =\u003e {\n  if (WINDOW.document?.prerendering) {\n    whenActivated(() =\u003e whenReady(callback));\n  } else if (WINDOW.document?.readyState !== 'complete') {\n    addEventListener('load', () =\u003e whenReady(callback), true);\n  } else {\n    // Queue a task so the callback runs after `loadEventEnd`.\n    setTimeout(callback, 0);\n  }\n};\n\n/**\n * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the\n * current page and calls the `callback` function once the page has loaded,\n * along with the relevant `navigation` performance entry used to determine the\n * value. The reported value is a `DOMHighResTimeStamp`.\n *\n * Note, this function waits until after the page is loaded to call `callback`\n * in order to ensure all properties of the `navigation` entry are populated.\n * This is useful if you want to report on other metrics exposed by the\n * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For\n * example, the TTFB metric starts from the page's [time\n * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it\n * includes time spent on DNS lookup, connection negotiation, network latency,\n * and server processing time.\n */\nexport const onTTFB = (onReport: (metric: TTFBMetric) =\u003e void, opts: ReportOpts = {}) =\u003e {\n  const metric = initMetric('TTFB');\n  const report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);\n\n  whenReady(() =\u003e {\n    const navigationEntry = getNavigationEntry();\n\n    if (navigationEntry) {\n      // The activationStart reference is used because TTFB should be\n      // relative to page activation rather than navigation start if the\n      // page was prerendered. But in cases where `activationStart` occurs\n      // after the first byte is received, this time should be clamped at 0.\n      metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0);\n\n      metric.entries = [navigationEntry];\n      report(true);\n    }\n  });\n};\n","import { getFunctionName, logger } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { onCLS } from './web-vitals/getCLS';\nimport { onFID } from './web-vitals/getFID';\nimport { onINP } from './web-vitals/getINP';\nimport { onLCP } from './web-vitals/getLCP';\nimport { observe } from './web-vitals/lib/observe';\nimport { onTTFB } from './web-vitals/onTTFB';\n\ntype InstrumentHandlerTypePerformanceObserver =\n  | 'longtask'\n  | 'event'\n  | 'navigation'\n  | 'paint'\n  | 'resource'\n  | 'first-input';\n\ntype InstrumentHandlerTypeMetric = 'cls' | 'lcp' | 'fid' | 'ttfb' | 'inp';\n\n// We provide this here manually instead of relying on a global, as this is not available in non-browser environements\n// And we do not want to expose such types\ninterface PerformanceEntry {\n  readonly duration: number;\n  readonly entryType: string;\n  readonly name: string;\n  readonly startTime: number;\n  toJSON(): Record\u003cstring, unknown\u003e;\n}\ninterface PerformanceEventTiming extends PerformanceEntry {\n  processingStart: number;\n  processingEnd: number;\n  duration: number;\n  cancelable?: boolean;\n  target?: unknown | null;\n  interactionId?: number;\n}\n\ninterface PerformanceScriptTiming extends PerformanceEntry {\n  sourceURL: string;\n  sourceFunctionName: string;\n  sourceCharPosition: number;\n  invoker: string;\n  invokerType: string;\n}\nexport interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {\n  scripts: PerformanceScriptTiming[];\n}\n\ninterface Metric {\n  /**\n   * The name of the metric (in acronym form).\n   */\n  name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';\n\n  /**\n   * The current value of the metric.\n   */\n  value: number;\n\n  /**\n   * The rating as to whether the metric value is within the \"good\",\n   * \"needs improvement\", or \"poor\" thresholds of the metric.\n   */\n  rating: 'good' | 'needs-improvement' | 'poor';\n\n  /**\n   * The delta between the current value and the last-reported value.\n   * On the first report, `delta` and `value` will always be the same.\n   */\n  delta: number;\n\n  /**\n   * A unique ID representing this particular metric instance. This ID can\n   * be used by an analytics tool to dedupe multiple values sent for the same\n   * metric instance, or to group multiple deltas together and calculate a\n   * total. It can also be used to differentiate multiple different metric\n   * instances sent from the same page, which can happen if the page is\n   * restored from the back/forward cache (in that case new metrics object\n   * get created).\n   */\n  id: string;\n\n  /**\n   * Any performance entries relevant to the metric value calculation.\n   * The array may also be empty if the metric value was not based on any\n   * entries (e.g. a CLS value of 0 given no layout shifts).\n   */\n  entries: PerformanceEntry[];\n\n  /**\n   * The type of navigation\n   *\n   * Navigation Timing API (or `undefined` if the browser doesn't\n   * support that API). For pages that are restored from the bfcache, this\n   * value will be 'back-forward-cache'.\n   */\n  navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore';\n}\n\ntype InstrumentHandlerType = InstrumentHandlerTypeMetric | InstrumentHandlerTypePerformanceObserver;\n\ntype StopListening = undefined | void | (() =\u003e void);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstrumentHandlerCallback = (data: any) =\u003e void;\n\ntype CleanupHandlerCallback = () =\u003e void;\n\nconst handlers: { [key in InstrumentHandlerType]?: InstrumentHandlerCallback[] } = {};\nconst instrumented: { [key in InstrumentHandlerType]?: boolean } = {};\n\nlet _previousCls: Metric | undefined;\nlet _previousFid: Metric | undefined;\nlet _previousLcp: Metric | undefined;\nlet _previousTtfb: Metric | undefined;\nlet _previousInp: Metric | undefined;\n\n/**\n * Add a callback that will be triggered when a CLS metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n *\n * Pass `stopOnCallback = true` to stop listening for CLS when the cleanup callback is called.\n * This will lead to the CLS being finalized and frozen.\n */\nexport function addClsInstrumentationHandler(\n  callback: (data: { metric: Metric }) =\u003e void,\n  stopOnCallback = false,\n): CleanupHandlerCallback {\n  return addMetricObserver('cls', callback, instrumentCls, _previousCls, stopOnCallback);\n}\n\n/**\n * Add a callback that will be triggered when a LCP metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n *\n * Pass `stopOnCallback = true` to stop listening for LCP when the cleanup callback is called.\n * This will lead to the LCP being finalized and frozen.\n */\nexport function addLcpInstrumentationHandler(\n  callback: (data: { metric: Metric }) =\u003e void,\n  stopOnCallback = false,\n): CleanupHandlerCallback {\n  return addMetricObserver('lcp', callback, instrumentLcp, _previousLcp, stopOnCallback);\n}\n\n/**\n * Add a callback that will be triggered when a FID metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nexport function addFidInstrumentationHandler(callback: (data: { metric: Metric }) =\u003e void): CleanupHandlerCallback {\n  return addMetricObserver('fid', callback, instrumentFid, _previousFid);\n}\n\n/**\n * Add a callback that will be triggered when a FID metric is available.\n */\nexport function addTtfbInstrumentationHandler(callback: (data: { metric: Metric }) =\u003e void): CleanupHandlerCallback {\n  return addMetricObserver('ttfb', callback, instrumentTtfb, _previousTtfb);\n}\n\n/**\n * Add a callback that will be triggered when a INP metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nexport function addInpInstrumentationHandler(\n  callback: (data: { metric: Omit\u003cMetric, 'entries'\u003e \u0026 { entries: PerformanceEventTiming[] } }) =\u003e void,\n): CleanupHandlerCallback {\n  return addMetricObserver('inp', callback, instrumentInp, _previousInp);\n}\n\nexport function addPerformanceInstrumentationHandler(\n  type: 'event',\n  callback: (data: { entries: ((PerformanceEntry \u0026 { target?: unknown | null }) | PerformanceEventTiming)[] }) =\u003e void,\n): CleanupHandlerCallback;\nexport function addPerformanceInstrumentationHandler(\n  type: InstrumentHandlerTypePerformanceObserver,\n  callback: (data: { entries: PerformanceEntry[] }) =\u003e void,\n): CleanupHandlerCallback;\n\n/**\n * Add a callback that will be triggered when a performance observer is triggered,\n * and receives the entries of the observer.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nexport function addPerformanceInstrumentationHandler(\n  type: InstrumentHandlerTypePerformanceObserver,\n  callback: (data: { entries: PerformanceEntry[] }) =\u003e void,\n): CleanupHandlerCallback {\n  addHandler(type, callback);\n\n  if (!instrumented[type]) {\n    instrumentPerformanceObserver(type);\n    instrumented[type] = true;\n  }\n\n  return getCleanupCallback(type, callback);\n}\n\n/** Trigger all handlers of a given type. */\nfunction triggerHandlers(type: InstrumentHandlerType, data: unknown): void {\n  const typeHandlers = handlers[type];\n\n  if (!typeHandlers?.length) {\n    return;\n  }\n\n  for (const handler of typeHandlers) {\n    try {\n      handler(data);\n    } catch (e) {\n      DEBUG_BUILD \u0026\u0026\n        logger.error(\n          `Error while triggering instrumentation handler.\\nType: ${type}\\nName: ${getFunctionName(handler)}\\nError:`,\n          e,\n        );\n    }\n  }\n}\n\nfunction instrumentCls(): StopListening {\n  return onCLS(\n    metric =\u003e {\n      triggerHandlers('cls', {\n        metric,\n      });\n      _previousCls = metric;\n    },\n    // We want the callback to be called whenever the CLS value updates.\n    // By default, the callback is only called when the tab goes to the background.\n    { reportAllChanges: true },\n  );\n}\n\nfunction instrumentFid(): void {\n  return onFID(metric =\u003e {\n    triggerHandlers('fid', {\n      metric,\n    });\n    _previousFid = metric;\n  });\n}\n\nfunction instrumentLcp(): StopListening {\n  return onLCP(\n    metric =\u003e {\n      triggerHandlers('lcp', {\n        metric,\n      });\n      _previousLcp = metric;\n    },\n    // We want the callback to be called whenever the LCP value updates.\n    // By default, the callback is only called when the tab goes to the background.\n    { reportAllChanges: true },\n  );\n}\n\nfunction instrumentTtfb(): StopListening {\n  return onTTFB(metric =\u003e {\n    triggerHandlers('ttfb', {\n      metric,\n    });\n    _previousTtfb = metric;\n  });\n}\n\nfunction instrumentInp(): void {\n  return onINP(metric =\u003e {\n    triggerHandlers('inp', {\n      metric,\n    });\n    _previousInp = metric;\n  });\n}\n\nfunction addMetricObserver(\n  type: InstrumentHandlerTypeMetric,\n  callback: InstrumentHandlerCallback,\n  instrumentFn: () =\u003e StopListening,\n  previousValue: Metric | undefined,\n  stopOnCallback = false,\n): CleanupHandlerCallback {\n  addHandler(type, callback);\n\n  let stopListening: StopListening | undefined;\n\n  if (!instrumented[type]) {\n    stopListening = instrumentFn();\n    instrumented[type] = true;\n  }\n\n  if (previousValue) {\n    callback({ metric: previousValue });\n  }\n\n  return getCleanupCallback(type, callback, stopOnCallback ? stopListening : undefined);\n}\n\nfunction instrumentPerformanceObserver(type: InstrumentHandlerTypePerformanceObserver): void {\n  const options: PerformanceObserverInit = {};\n\n  // Special per-type options we want to use\n  if (type === 'event') {\n    options.durationThreshold = 0;\n  }\n\n  observe(\n    type,\n    entries =\u003e {\n      triggerHandlers(type, { entries });\n    },\n    options,\n  );\n}\n\nfunction addHandler(type: InstrumentHandlerType, handler: InstrumentHandlerCallback): void {\n  handlers[type] = handlers[type] || [];\n  (handlers[type] as InstrumentHandlerCallback[]).push(handler);\n}\n\n// Get a callback which can be called to remove the instrumentation handler\nfunction getCleanupCallback(\n  type: InstrumentHandlerType,\n  callback: InstrumentHandlerCallback,\n  stopListening: StopListening,\n): CleanupHandlerCallback {\n  return () =\u003e {\n    if (stopListening) {\n      stopListening();\n    }\n\n    const typeHandlers = handlers[type];\n\n    if (!typeHandlers) {\n      return;\n    }\n\n    const index = typeHandlers.indexOf(callback);\n    if (index !== -1) {\n      typeHandlers.splice(index, 1);\n    }\n  };\n}\n\n/**\n * Check if a PerformanceEntry is a PerformanceEventTiming by checking for the `duration` property.\n */\nexport function isPerformanceEventTiming(entry: PerformanceEntry): entry is PerformanceEventTiming {\n  return 'duration' in entry;\n}\n","import type { Integration, SentrySpan, Span, SpanAttributes, SpanTimeInput, StartSpanOptions } from '@sentry/core';\nimport { getClient, getCurrentScope, spanToJSON, startInactiveSpan, withActiveSpan } from '@sentry/core';\nimport { WINDOW } from '../types';\n\n/**\n * Checks if a given value is a valid measurement value.\n */\nexport function isMeasurementValue(value: unknown): value is number {\n  return typeof value === 'number' \u0026\u0026 isFinite(value);\n}\n\n/**\n * Helper function to start child on transactions. This function will make sure that the transaction will\n * use the start timestamp of the created child span if it is earlier than the transactions actual\n * start timestamp.\n */\nexport function startAndEndSpan(\n  parentSpan: Span,\n  startTimeInSeconds: number,\n  endTime: SpanTimeInput,\n  { ...ctx }: StartSpanOptions,\n): Span | undefined {\n  const parentStartTime = spanToJSON(parentSpan).start_timestamp;\n  if (parentStartTime \u0026\u0026 parentStartTime \u003e startTimeInSeconds) {\n    // We can only do this for SentrySpans...\n    if (typeof (parentSpan as Partial\u003cSentrySpan\u003e).updateStartTime === 'function') {\n      (parentSpan as SentrySpan).updateStartTime(startTimeInSeconds);\n    }\n  }\n\n  // The return value only exists for tests\n  return withActiveSpan(parentSpan, () =\u003e {\n    const span = startInactiveSpan({\n      startTime: startTimeInSeconds,\n      ...ctx,\n    });\n\n    if (span) {\n      span.end(endTime);\n    }\n\n    return span;\n  });\n}\n\ninterface StandaloneWebVitalSpanOptions {\n  name: string;\n  transaction?: string;\n  attributes: SpanAttributes;\n  startTime: number;\n}\n\n/**\n * Starts an inactive, standalone span used to send web vital values to Sentry.\n * DO NOT use this for arbitrary spans, as these spans require special handling\n * during ingestion to extract metrics.\n *\n * This function adds a bunch of attributes and data to the span that's shared\n * by all web vital standalone spans. However, you need to take care of adding\n * the actual web vital value as an event to the span. Also, you need to assign\n * a transaction name and some other values that are specific to the web vital.\n *\n * Ultimately, you also need to take care of ending the span to send it off.\n *\n * @param options\n *\n * @returns an inactive, standalone and NOT YET ended span\n */\nexport function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptions): Span | undefined {\n  const client = getClient();\n  if (!client) {\n    return;\n  }\n\n  const { name, transaction, attributes: passedAttributes, startTime } = options;\n\n  const { release, environment, sendDefaultPii } = client.getOptions();\n  // We need to get the replay, user, and activeTransaction from the current scope\n  // so that we can associate replay id, profile id, and a user display to the span\n  const replay = client.getIntegrationByName\u003cIntegration \u0026 { getReplayId: () =\u003e string }\u003e('Replay');\n  const replayId = replay?.getReplayId();\n\n  const scope = getCurrentScope();\n\n  const user = scope.getUser();\n  const userDisplay = user !== undefined ? user.email || user.id || user.ip_address : undefined;\n\n  let profileId: string | undefined;\n  try {\n    // @ts-expect-error skip optional chaining to save bundle size with try catch\n    profileId = scope.getScopeData().contexts.profile.profile_id;\n  } catch {\n    // do nothing\n  }\n\n  const attributes: SpanAttributes = {\n    release,\n    environment,\n\n    user: userDisplay || undefined,\n    profile_id: profileId || undefined,\n    replay_id: replayId || undefined,\n\n    transaction,\n\n    // Web vital score calculation relies on the user agent to account for different\n    // browsers setting different thresholds for what is considered a good/meh/bad value.\n    // For example: Chrome vs. Chrome Mobile\n    'user_agent.original': WINDOW.navigator?.userAgent,\n\n    // This tells Sentry to infer the IP address from the request\n    'client.address': sendDefaultPii ? '{{auto}}' : undefined,\n\n    ...passedAttributes,\n  };\n\n  return startInactiveSpan({\n    name,\n    attributes,\n    startTime,\n    experimental: {\n      standalone: true,\n    },\n  });\n}\n\n/** Get the browser performance API. */\nexport function getBrowserPerformanceAPI(): Performance | undefined {\n  // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n  return WINDOW.addEventListener \u0026\u0026 WINDOW.performance;\n}\n\n/**\n * Converts from milliseconds to seconds\n * @param time time in ms\n */\nexport function msToSec(time: number): number {\n  return time / 1000;\n}\n\n/**\n * Converts ALPN protocol ids to name and version.\n *\n * (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)\n * @param nextHopProtocol PerformanceResourceTiming.nextHopProtocol\n */\nexport function extractNetworkProtocol(nextHopProtocol: string): { name: string; version: string } {\n  let name = 'unknown';\n  let version = 'unknown';\n  let _name = '';\n  for (const char of nextHopProtocol) {\n    // http/1.1 etc.\n    if (char === '/') {\n      [name, version] = nextHopProtocol.split('/') as [string, string];\n      break;\n    }\n    // h2, h3 etc.\n    if (!isNaN(Number(char))) {\n      name = _name === 'h' ? 'http' : _name;\n      version = nextHopProtocol.split(_name)[1] as string;\n      break;\n    }\n    _name += char;\n  }\n  if (_name === nextHopProtocol) {\n    // webrtc, ftp, etc.\n    name = _name;\n  }\n  return { name, version };\n}\n","import type { SpanAttributes } from '@sentry/core';\nimport {\n  browserPerformanceTimeOrigin,\n  getActiveSpan,\n  getClient,\n  getCurrentScope,\n  getRootSpan,\n  htmlTreeAsString,\n  logger,\n  SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  spanToJSON,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { addClsInstrumentationHandler } from './instrument';\nimport { msToSec, startStandaloneWebVitalSpan } from './utils';\nimport { onHidden } from './web-vitals/lib/onHidden';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value once\n *\n * - the page visibility is hidden\n * - a navigation span is started (to stop CLS measurement for SPA soft navigations)\n *\n * Once either of these events triggers, the CLS value is sent as a standalone span and we stop\n * measuring CLS.\n */\nexport function trackClsAsStandaloneSpan(): void {\n  let standaloneCLsValue = 0;\n  let standaloneClsEntry: LayoutShift | undefined;\n  let pageloadSpanId: string | undefined;\n\n  if (!supportsLayoutShift()) {\n    return;\n  }\n\n  let sentSpan = false;\n  function _collectClsOnce() {\n    if (sentSpan) {\n      return;\n    }\n    sentSpan = true;\n    if (pageloadSpanId) {\n      sendStandaloneClsSpan(standaloneCLsValue, standaloneClsEntry, pageloadSpanId);\n    }\n    cleanupClsHandler();\n  }\n\n  const cleanupClsHandler = addClsInstrumentationHandler(({ metric }) =\u003e {\n    const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n    if (!entry) {\n      return;\n    }\n    standaloneCLsValue = metric.value;\n    standaloneClsEntry = entry;\n  }, true);\n\n  // use pagehide event from web-vitals\n  onHidden(() =\u003e {\n    _collectClsOnce();\n  });\n\n  // Since the call chain of this function is synchronous and evaluates before the SDK client is created,\n  // we need to wait with subscribing to a client hook until the client is created. Therefore, we defer\n  // to the next tick after the SDK setup.\n  setTimeout(() =\u003e {\n    const client = getClient();\n\n    if (!client) {\n      return;\n    }\n\n    const unsubscribeStartNavigation = client.on('startNavigationSpan', () =\u003e {\n      _collectClsOnce();\n      unsubscribeStartNavigation?.();\n    });\n\n    const activeSpan = getActiveSpan();\n    if (activeSpan) {\n      const rootSpan = getRootSpan(activeSpan);\n      const spanJSON = spanToJSON(rootSpan);\n      if (spanJSON.op === 'pageload') {\n        pageloadSpanId = rootSpan.spanContext().spanId;\n      }\n    }\n  }, 0);\n}\n\nfunction sendStandaloneClsSpan(clsValue: number, entry: LayoutShift | undefined, pageloadSpanId: string) {\n  DEBUG_BUILD \u0026\u0026 logger.log(`Sending CLS span (${clsValue})`);\n\n  const startTime = msToSec((browserPerformanceTimeOrigin() || 0) + (entry?.startTime || 0));\n  const routeName = getCurrentScope().getScopeData().transactionName;\n\n  const name = entry ? htmlTreeAsString(entry.sources[0]?.node) : 'Layout shift';\n\n  const attributes: SpanAttributes = {\n    [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.cls',\n    [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.webvital.cls',\n    [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry?.duration || 0,\n    // attach the pageload span id to the CLS span so that we can link them in the UI\n    'sentry.pageload.span_id': pageloadSpanId,\n  };\n\n  const span = startStandaloneWebVitalSpan({\n    name,\n    transaction: routeName,\n    attributes,\n    startTime,\n  });\n\n  if (span) {\n    span.addEvent('cls', {\n      [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: '',\n      [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: clsValue,\n    });\n\n    // LayoutShift performance entries always have a duration of 0, so we don't need to add `entry.duration` here\n    // see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/duration\n    span.end(startTime);\n  }\n}\n\nfunction supportsLayoutShift(): boolean {\n  try {\n    return PerformanceObserver.supportedEntryTypes.includes('layout-shift');\n  } catch {\n    return false;\n  }\n}\n","/* eslint-disable max-lines */\nimport type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n  browserPerformanceTimeOrigin,\n  getActiveSpan,\n  getComponentName,\n  htmlTreeAsString,\n  parseUrl,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  setMeasurement,\n  spanToJSON,\n} from '@sentry/core';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n  type PerformanceLongAnimationFrameTiming,\n  addClsInstrumentationHandler,\n  addFidInstrumentationHandler,\n  addLcpInstrumentationHandler,\n  addPerformanceInstrumentationHandler,\n  addTtfbInstrumentationHandler,\n} from './instrument';\nimport {\n  extractNetworkProtocol,\n  getBrowserPerformanceAPI,\n  isMeasurementValue,\n  msToSec,\n  startAndEndSpan,\n} from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\n\ninterface NavigatorNetworkInformation {\n  readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n  // http://wicg.github.io/netinfo/#type-attribute\n  readonly type?: ConnectionType;\n  // http://wicg.github.io/netinfo/#effectivetype-attribute\n  readonly effectiveType?: EffectiveConnectionType;\n  // http://wicg.github.io/netinfo/#downlinkmax-attribute\n  readonly downlinkMax?: Megabit;\n  // http://wicg.github.io/netinfo/#downlink-attribute\n  readonly downlink?: Megabit;\n  // http://wicg.github.io/netinfo/#rtt-attribute\n  readonly rtt?: Millisecond;\n  // http://wicg.github.io/netinfo/#savedata-attribute\n  readonly saveData?: boolean;\n  // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n  onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n  readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n  recordClsStandaloneSpans: boolean;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking \u0026 ensure all measurements are final \u0026 captured.\n *\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTrackingWebVitalsOptions): () =\u003e void {\n  const performance = getBrowserPerformanceAPI();\n  if (performance \u0026\u0026 browserPerformanceTimeOrigin()) {\n    // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n    if (performance.mark) {\n      WINDOW.performance.mark('sentry-tracing-init');\n    }\n    const fidCleanupCallback = _trackFID();\n    const lcpCleanupCallback = _trackLCP();\n    const ttfbCleanupCallback = _trackTtfb();\n    const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n    return (): void =\u003e {\n      fidCleanupCallback();\n      lcpCleanupCallback();\n      ttfbCleanupCallback();\n      clsCleanupCallback?.();\n    };\n  }\n\n  return () =\u003e undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n  addPerformanceInstrumentationHandler('longtask', ({ entries }) =\u003e {\n    const parent = getActiveSpan();\n    if (!parent) {\n      return;\n    }\n\n    const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n    for (const entry of entries) {\n      const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n      const duration = msToSec(entry.duration);\n\n      if (parentOp === 'navigation' \u0026\u0026 parentStartTimestamp \u0026\u0026 startTime \u003c parentStartTimestamp) {\n        // Skip adding a span if the long task started before the navigation started.\n        // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n        // time, potentially skewing the duration of the actual navigation as reported via our\n        // routing instrumentations\n        continue;\n      }\n\n      startAndEndSpan(parent, startTime, startTime + duration, {\n        name: 'Main UI thread blocked',\n        op: 'ui.long-task',\n        attributes: {\n          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n        },\n      });\n    }\n  });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n  // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n  // we directly observe `long-animation-frame` events instead of through the web-vitals\n  // `observe` helper function.\n  const observer = new PerformanceObserver(list =\u003e {\n    const parent = getActiveSpan();\n    if (!parent) {\n      return;\n    }\n    for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n      if (!entry.scripts[0]) {\n        continue;\n      }\n\n      const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n\n      const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n      if (parentOp === 'navigation' \u0026\u0026 parentStartTimestamp \u0026\u0026 startTime \u003c parentStartTimestamp) {\n        // Skip adding the span if the long animation frame started before the navigation started.\n        // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n        // time, potentially skewing the duration of the actual navigation as reported via our\n        // routing instrumentations\n        continue;\n      }\n      const duration = msToSec(entry.duration);\n\n      const attributes: SpanAttributes = {\n        [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      };\n\n      const initialScript = entry.scripts[0];\n      const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n      attributes['browser.script.invoker'] = invoker;\n      attributes['browser.script.invoker_type'] = invokerType;\n      if (sourceURL) {\n        attributes['code.filepath'] = sourceURL;\n      }\n      if (sourceFunctionName) {\n        attributes['code.function'] = sourceFunctionName;\n      }\n      if (sourceCharPosition !== -1) {\n        attributes['browser.script.source_char_position'] = sourceCharPosition;\n      }\n\n      startAndEndSpan(parent, startTime, startTime + duration, {\n        name: 'Main UI thread blocked',\n        op: 'ui.long-animation-frame',\n        attributes,\n      });\n    }\n  });\n\n  observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n  addPerformanceInstrumentationHandler('event', ({ entries }) =\u003e {\n    const parent = getActiveSpan();\n    if (!parent) {\n      return;\n    }\n    for (const entry of entries) {\n      if (entry.name === 'click') {\n        const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n        const duration = msToSec(entry.duration);\n\n        const spanOptions: StartSpanOptions \u0026 Required\u003cPick\u003cStartSpanOptions, 'attributes'\u003e\u003e = {\n          name: htmlTreeAsString(entry.target),\n          op: `ui.interaction.${entry.name}`,\n          startTime: startTime,\n          attributes: {\n            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n          },\n        };\n\n        const componentName = getComponentName(entry.target);\n        if (componentName) {\n          spanOptions.attributes['ui.component_name'] = componentName;\n        }\n\n        startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n      }\n    }\n  });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () =\u003e void {\n  return addClsInstrumentationHandler(({ metric }) =\u003e {\n    const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n    if (!entry) {\n      return;\n    }\n    _measurements['cls'] = { value: metric.value, unit: '' };\n    _clsEntry = entry;\n  }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () =\u003e void {\n  return addLcpInstrumentationHandler(({ metric }) =\u003e {\n    const entry = metric.entries[metric.entries.length - 1];\n    if (!entry) {\n      return;\n    }\n\n    _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n    _lcpEntry = entry as LargestContentfulPaint;\n  }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID(): () =\u003e void {\n  return addFidInstrumentationHandler(({ metric }) =\u003e {\n    const entry = metric.entries[metric.entries.length - 1];\n    if (!entry) {\n      return;\n    }\n\n    const timeOrigin = msToSec(browserPerformanceTimeOrigin() as number);\n    const startTime = msToSec(entry.startTime);\n    _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n    _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n  });\n}\n\nfunction _trackTtfb(): () =\u003e void {\n  return addTtfbInstrumentationHandler(({ metric }) =\u003e {\n    const entry = metric.entries[metric.entries.length - 1];\n    if (!entry) {\n      return;\n    }\n\n    _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n  });\n}\n\ninterface AddPerformanceEntriesOptions {\n  /**\n   * Flag to determine if CLS should be recorded as a measurement on the span or\n   * sent as a standalone span instead.\n   */\n  recordClsOnPageloadSpan: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n  const performance = getBrowserPerformanceAPI();\n  const origin = browserPerformanceTimeOrigin();\n  if (!performance?.getEntries || !origin) {\n    // Gatekeeper if performance API not available\n    return;\n  }\n\n  const timeOrigin = msToSec(origin);\n\n  const performanceEntries = performance.getEntries();\n\n  const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n  performanceEntries.slice(_performanceCursor).forEach(entry =\u003e {\n    const startTime = msToSec(entry.startTime);\n    const duration = msToSec(\n      // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n      // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n      // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n      // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n      Math.max(0, entry.duration),\n    );\n\n    if (op === 'navigation' \u0026\u0026 transactionStartTime \u0026\u0026 timeOrigin + startTime \u003c transactionStartTime) {\n      return;\n    }\n\n    switch (entry.entryType) {\n      case 'navigation': {\n        _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n        break;\n      }\n      case 'mark':\n      case 'paint':\n      case 'measure': {\n        _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n        // capture web vitals\n        const firstHidden = getVisibilityWatcher();\n        // Only report if the page wasn't hidden prior to the web vital.\n        const shouldRecord = entry.startTime \u003c firstHidden.firstHiddenTime;\n\n        if (entry.name === 'first-paint' \u0026\u0026 shouldRecord) {\n          _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n        }\n        if (entry.name === 'first-contentful-paint' \u0026\u0026 shouldRecord) {\n          _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n        }\n        break;\n      }\n      case 'resource': {\n        _addResourceSpans(span, entry as PerformanceResourceTiming, entry.name, startTime, duration, timeOrigin);\n        break;\n      }\n      // Ignore other entry types.\n    }\n  });\n\n  _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n  _trackNavigator(span);\n\n  // Measurements are only available for pageload transactions\n  if (op === 'pageload') {\n    _addTtfbRequestTimeToMeasurements(_measurements);\n\n    const fidMark = _measurements['mark.fid'];\n    if (fidMark \u0026\u0026 _measurements['fid']) {\n      // create span for FID\n      startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n        name: 'first input delay',\n        op: 'ui.action',\n        attributes: {\n          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n        },\n      });\n\n      // Delete mark.fid as we don't want it to be part of final payload\n      delete _measurements['mark.fid'];\n    }\n\n    // If FCP is not recorded we should not record the cls value\n    // according to the new definition of CLS.\n    // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n    if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n      delete _measurements.cls;\n    }\n\n    Object.entries(_measurements).forEach(([measurementName, measurement]) =\u003e {\n      setMeasurement(measurementName, measurement.value, measurement.unit);\n    });\n\n    // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n    span.setAttribute('performance.timeOrigin', timeOrigin);\n\n    // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n    // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n    // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n    // time where the user actively started the navigation, for example by clicking a link.\n    // This is user action is called \"activation\" and the time between navigation and activation is stored in\n    // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n    span.setAttribute('performance.activationStart', getActivationStart());\n\n    _setWebVitalAttributes(span);\n  }\n\n  _lcpEntry = undefined;\n  _clsEntry = undefined;\n  _measurements = {};\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n  span: Span,\n  entry: PerformanceEntry,\n  startTime: number,\n  duration: number,\n  timeOrigin: number,\n): void {\n  const navEntry = getNavigationEntry(false);\n  const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n  // Because performance.measure accepts arbitrary timestamps it can produce\n  // spans that happen before the browser even makes a request for the page.\n  //\n  // An example of this is the automatically generated Next.js-before-hydration\n  // spans created by the Next.js framework.\n  //\n  // To prevent this we will pin the start timestamp to the request start time\n  // This does make duration inaccurate, so if this does happen, we will add\n  // an attribute to the span\n  const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n  const startTimeStamp = timeOrigin + startTime;\n  const measureEndTimestamp = startTimeStamp + duration;\n\n  const attributes: SpanAttributes = {\n    [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n  };\n\n  if (measureStartTimestamp !== startTimeStamp) {\n    attributes['sentry.browser.measure_happened_before_request'] = true;\n    attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n  }\n\n  // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process.\n  if (measureStartTimestamp \u003c= measureEndTimestamp) {\n    startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n      name: entry.name as string,\n      op: entry.entryType as string,\n      attributes,\n    });\n  }\n}\n\n/**\n * Instrument navigation entries\n * exported only for tests\n */\nexport function _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n  (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event =\u003e {\n    _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n  });\n  _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n  _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n  _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n  _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n  | 'secureConnection'\n  | 'fetch'\n  | 'domainLookup'\n  | 'unloadEvent'\n  | 'redirect'\n  | 'connect'\n  | 'domContentLoadedEvent'\n  | 'loadEvent';\n\ntype EndEventName =\n  | 'connectEnd'\n  | 'domainLookupStart'\n  | 'domainLookupEnd'\n  | 'unloadEventEnd'\n  | 'redirectEnd'\n  | 'connectEnd'\n  | 'domContentLoadedEventEnd'\n  | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n  span: Span,\n  entry: PerformanceNavigationTiming,\n  event: StartEventName,\n  timeOrigin: number,\n  name: string = event,\n): void {\n  const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n  const end = entry[eventEnd];\n  const start = entry[`${event}Start`];\n  if (!start || !end) {\n    return;\n  }\n  startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n    op: `browser.${name}`,\n    name: entry.name,\n    attributes: {\n      [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      ...(event === 'redirect' \u0026\u0026 entry.redirectCount != null ? { 'http.redirect_count': entry.redirectCount } : {}),\n    },\n  });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n  if (event === 'secureConnection') {\n    return 'connectEnd';\n  }\n  if (event === 'fetch') {\n    return 'domainLookupStart';\n  }\n  return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n  const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart as number);\n  const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd as number);\n  const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart as number);\n  if (entry.responseEnd) {\n    // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n    // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n    // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n    // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n    startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n      op: 'browser.request',\n      name: entry.name,\n      attributes: {\n        [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      },\n    });\n\n    startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n      op: 'browser.response',\n      name: entry.name,\n      attributes: {\n        [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      },\n    });\n  }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n  span: Span,\n  entry: PerformanceResourceTiming,\n  resourceUrl: string,\n  startTime: number,\n  duration: number,\n  timeOrigin: number,\n): void {\n  // we already instrument based on fetch and xhr, so we don't need to\n  // duplicate spans here.\n  if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n    return;\n  }\n\n  const parsedUrl = parseUrl(resourceUrl);\n\n  const attributes: SpanAttributes = {\n    [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n  };\n  setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n  setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n  setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n  // `deliveryType` is experimental and does not exist everywhere\n  const deliveryType = (entry as { deliveryType?: 'cache' | 'navigational-prefetch' | '' }).deliveryType;\n  if (deliveryType != null) {\n    attributes['http.response_delivery_type'] = deliveryType;\n  }\n\n  // Types do not reflect this property yet\n  const renderBlockingStatus = (entry as { renderBlockingStatus?: 'render-blocking' | 'non-render-blocking' })\n    .renderBlockingStatus;\n  if (renderBlockingStatus) {\n    attributes['resource.render_blocking_status'] = renderBlockingStatus;\n  }\n\n  if (parsedUrl.protocol) {\n    attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n  }\n\n  if (parsedUrl.host) {\n    attributes['server.address'] = parsedUrl.host;\n  }\n\n  attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n  const { name, version } = extractNetworkProtocol(entry.nextHopProtocol);\n  attributes['network.protocol.name'] = name;\n  attributes['network.protocol.version'] = version;\n\n  const startTimestamp = timeOrigin + startTime;\n  const endTimestamp = startTimestamp + duration;\n\n  startAndEndSpan(span, startTimestamp, endTimestamp, {\n    name: resourceUrl.replace(WINDOW.location.origin, ''),\n    op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n    attributes,\n  });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span: Span): void {\n  const navigator = WINDOW.navigator as null | (Navigator \u0026 NavigatorNetworkInformation \u0026 NavigatorDeviceMemory);\n  if (!navigator) {\n    return;\n  }\n\n  // track network connectivity\n  const connection = navigator.connection;\n  if (connection) {\n    if (connection.effectiveType) {\n      span.setAttribute('effectiveConnectionType', connection.effectiveType);\n    }\n\n    if (connection.type) {\n      span.setAttribute('connectionType', connection.type);\n    }\n\n    if (isMeasurementValue(connection.rtt)) {\n      _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n    }\n  }\n\n  if (isMeasurementValue(navigator.deviceMemory)) {\n    span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n  }\n\n  if (isMeasurementValue(navigator.hardwareConcurrency)) {\n    span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n  }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span): void {\n  if (_lcpEntry) {\n    // Capture Properties of the LCP element that contributes to the LCP.\n\n    if (_lcpEntry.element) {\n      span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n    }\n\n    if (_lcpEntry.id) {\n      span.setAttribute('lcp.id', _lcpEntry.id);\n    }\n\n    if (_lcpEntry.url) {\n      // Trim URL to the first 200 characters.\n      span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n    }\n\n    if (_lcpEntry.loadTime != null) {\n      // loadTime is the time of LCP that's related to receiving the LCP element response..\n      span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n    }\n\n    if (_lcpEntry.renderTime != null) {\n      // renderTime is loadTime + rendering time\n      // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n      // `Timing-Allow-Origin` header.\n      span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n    }\n\n    span.setAttribute('lcp.size', _lcpEntry.size);\n  }\n\n  // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n  if (_clsEntry?.sources) {\n    _clsEntry.sources.forEach((source, index) =\u003e\n      span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n    );\n  }\n}\n\nfunction setResourceEntrySizeData(\n  attributes: SpanAttributes,\n  entry: PerformanceResourceTiming,\n  key: keyof Pick\u003cPerformanceResourceTiming, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'\u003e,\n  dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',\n): void {\n  const entryVal = entry[key];\n  if (entryVal != null \u0026\u0026 entryVal \u003c MAX_INT_AS_BYTES) {\n    attributes[dataKey] = entryVal;\n  }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n  const navEntry = getNavigationEntry(false);\n  if (!navEntry) {\n    return;\n  }\n\n  const { responseStart, requestStart } = navEntry;\n\n  if (requestStart \u003c= responseStart) {\n    _measurements['ttfb.requestTime'] = {\n      value: responseStart - requestStart,\n      unit: 'millisecond',\n    };\n  }\n}\n","import type { HandlerDataDom } from '@sentry/core';\nimport { addHandler, addNonEnumerableProperty, fill, maybeInstrument, triggerHandlers, uuid4 } from '@sentry/core';\nimport { WINDOW } from '../types';\n\ntype SentryWrappedTarget = HTMLElement \u0026 { _sentryId?: string };\n\ntype AddEventListener = (\n  type: string,\n  listener: EventListenerOrEventListenerObject,\n  options?: boolean | AddEventListenerOptions,\n) =\u003e void;\ntype RemoveEventListener = (\n  type: string,\n  listener: EventListenerOrEventListenerObject,\n  options?: boolean | EventListenerOptions,\n) =\u003e void;\n\ntype InstrumentedElement = Element \u0026 {\n  __sentry_instrumentation_handlers__?: {\n    [key in 'click' | 'keypress']?: {\n      handler?: unknown;\n      /** The number of custom listeners attached to this element */\n      refCount: number;\n    };\n  };\n};\n\nconst DEBOUNCE_DURATION = 1000;\n\nlet debounceTimerID: number | undefined;\nlet lastCapturedEventType: string | undefined;\nlet lastCapturedEventTargetId: string | undefined;\n\n/**\n * Add an instrumentation handler for when a click or a keypress happens.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addClickKeypressInstrumentationHandler(handler: (data: HandlerDataDom) =\u003e void): void {\n  const type = 'dom';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentDOM);\n}\n\n/** Exported for tests only. */\nexport function instrumentDOM(): void {\n  if (!WINDOW.document) {\n    return;\n  }\n\n  // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom\n  // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before\n  // we instrument `addEventListener` so that we don't end up attaching this handler twice.\n  const triggerDOMHandler = triggerHandlers.bind(null, 'dom');\n  const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);\n  WINDOW.document.addEventListener('click', globalDOMEventHandler, false);\n  WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);\n\n  // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled\n  // clicks \u0026 keypresses, by adding an event listener of our own to any element to which they add a listener. That\n  // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler\n  // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still\n  // guaranteed to fire at least once.)\n  ['EventTarget', 'Node'].forEach((target: string) =\u003e {\n    const globalObject = WINDOW as unknown as Record\u003cstring, { prototype?: object }\u003e;\n    const proto = globalObject[target]?.prototype;\n\n    // eslint-disable-next-line no-prototype-builtins\n    if (!proto?.hasOwnProperty?.('addEventListener')) {\n      return;\n    }\n\n    fill(proto, 'addEventListener', function (originalAddEventListener: AddEventListener): AddEventListener {\n      return function (this: InstrumentedElement, type, listener, options): AddEventListener {\n        if (type === 'click' || type == 'keypress') {\n          try {\n            const handlers = (this.__sentry_instrumentation_handlers__ =\n              this.__sentry_instrumentation_handlers__ || {});\n            const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });\n\n            if (!handlerForType.handler) {\n              const handler = makeDOMEventHandler(triggerDOMHandler);\n              handlerForType.handler = handler;\n              originalAddEventListener.call(this, type, handler, options);\n            }\n\n            handlerForType.refCount++;\n          } catch (e) {\n            // Accessing dom properties is always fragile.\n            // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n          }\n        }\n\n        return originalAddEventListener.call(this, type, listener, options);\n      };\n    });\n\n    fill(\n      proto,\n      'removeEventListener',\n      function (originalRemoveEventListener: RemoveEventListener): RemoveEventListener {\n        return function (this: InstrumentedElement, type, listener, options): () =\u003e void {\n          if (type === 'click' || type == 'keypress') {\n            try {\n              const handlers = this.__sentry_instrumentation_handlers__ || {};\n              const handlerForType = handlers[type];\n\n              if (handlerForType) {\n                handlerForType.refCount--;\n                // If there are no longer any custom handlers of the current type on this element, we can remove ours, too.\n                if (handlerForType.refCount \u003c= 0) {\n                  originalRemoveEventListener.call(this, type, handlerForType.handler, options);\n                  handlerForType.handler = undefined;\n                  delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete\n                }\n\n                // If there are no longer any custom handlers of any type on this element, cleanup everything.\n                if (Object.keys(handlers).length === 0) {\n                  delete this.__sentry_instrumentation_handlers__;\n                }\n              }\n            } catch (e) {\n              // Accessing dom properties is always fragile.\n              // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n            }\n          }\n\n          return originalRemoveEventListener.call(this, type, listener, options);\n        };\n      },\n    );\n  });\n}\n\n/**\n * Check whether the event is similar to the last captured one. For example, two click events on the same button.\n */\nfunction isSimilarToLastCapturedEvent(event: Event): boolean {\n  // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.\n  if (event.type !== lastCapturedEventType) {\n    return false;\n  }\n\n  try {\n    // If both events have the same type, it's still possible that actions were performed on different targets.\n    // e.g. 2 clicks on different buttons.\n    if (!event.target || (event.target as SentryWrappedTarget)._sentryId !== lastCapturedEventTargetId) {\n      return false;\n    }\n  } catch (e) {\n    // just accessing `target` property can throw an exception in some rare circumstances\n    // see: https://github.com/getsentry/sentry-javascript/issues/838\n  }\n\n  // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_\n  // to which an event listener was attached), we treat them as the same action, as we want to capture\n  // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.\n  return true;\n}\n\n/**\n * Decide whether an event should be captured.\n * @param event event to be captured\n */\nfunction shouldSkipDOMEvent(eventType: string, target: SentryWrappedTarget | null): boolean {\n  // We are only interested in filtering `keypress` events for now.\n  if (eventType !== 'keypress') {\n    return false;\n  }\n\n  if (!target?.tagName) {\n    return true;\n  }\n\n  // Only consider keypress events on actual input elements. This will disregard keypresses targeting body\n  // e.g.tabbing through elements, hotkeys, etc.\n  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Wraps addEventListener to capture UI breadcrumbs\n */\nfunction makeDOMEventHandler(\n  handler: (data: HandlerDataDom) =\u003e void,\n  globalListener: boolean = false,\n): (event: Event) =\u003e void {\n  return (event: Event \u0026 { _sentryCaptured?: true }): void =\u003e {\n    // It's possible this handler might trigger multiple times for the same\n    // event (e.g. event propagation through node ancestors).\n    // Ignore if we've already captured that event.\n    if (!event || event['_sentryCaptured']) {\n      return;\n    }\n\n    const target = getEventTarget(event);\n\n    // We always want to skip _some_ events.\n    if (shouldSkipDOMEvent(event.type, target)) {\n      return;\n    }\n\n    // Mark event as \"seen\"\n    addNonEnumerableProperty(event, '_sentryCaptured', true);\n\n    if (target \u0026\u0026 !target._sentryId) {\n      // Add UUID to event target so we can identify if\n      addNonEnumerableProperty(target, '_sentryId', uuid4());\n    }\n\n    const name = event.type === 'keypress' ? 'input' : event.type;\n\n    // If there is no last captured event, it means that we can safely capture the new event and store it for future comparisons.\n    // If there is a last captured event, see if the new event is different enough to treat it as a unique one.\n    // If that's the case, emit the previous event and store locally the newly-captured DOM event.\n    if (!isSimilarToLastCapturedEvent(event)) {\n      const handlerData: HandlerDataDom = { event, name, global: globalListener };\n      handler(handlerData);\n      lastCapturedEventType = event.type;\n      lastCapturedEventTargetId = target ? target._sentryId : undefined;\n    }\n\n    // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.\n    clearTimeout(debounceTimerID);\n    debounceTimerID = WINDOW.setTimeout(() =\u003e {\n      lastCapturedEventTargetId = undefined;\n      lastCapturedEventType = undefined;\n    }, DEBOUNCE_DURATION);\n  };\n}\n\nfunction getEventTarget(event: Event): SentryWrappedTarget | null {\n  try {\n    return event.target as SentryWrappedTarget | null;\n  } catch (e) {\n    // just accessing `target` property can throw an exception in some rare circumstances\n    // see: https://github.com/getsentry/sentry-javascript/issues/838\n    return null;\n  }\n}\n","import type { HandlerDataHistory } from '@sentry/core';\nimport { addHandler, fill, maybeInstrument, supportsHistory, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nlet lastHref: string | undefined;\n\n/**\n * Add an instrumentation handler for when a fetch request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addHistoryInstrumentationHandler(handler: (data: HandlerDataHistory) =\u003e void): void {\n  const type = 'history';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentHistory);\n}\n\n/**\n * Exported just for testing\n */\nexport function instrumentHistory(): void {\n  // The `popstate` event may also be triggered on `pushState`, but it may not always reliably be emitted by the browser\n  // Which is why we also monkey-patch methods below, in addition to this\n  WINDOW.addEventListener('popstate', () =\u003e {\n    const to = WINDOW.location.href;\n    // keep track of the current URL state, as we always receive only the updated state\n    const from = lastHref;\n    lastHref = to;\n\n    if (from === to) {\n      return;\n    }\n\n    const handlerData = { from, to } satisfies HandlerDataHistory;\n    triggerHandlers('history', handlerData);\n  });\n\n  // Just guard against this not being available, in weird environments\n  if (!supportsHistory()) {\n    return;\n  }\n\n  function historyReplacementFunction(originalHistoryFunction: () =\u003e void): () =\u003e void {\n    return function (this: History, ...args: unknown[]): void {\n      const url = args.length \u003e 2 ? args[2] : undefined;\n      if (url) {\n        // coerce to string (this is what pushState does)\n        const from = lastHref;\n        const to = String(url);\n        // keep track of the current URL state, as we always receive only the updated state\n        lastHref = to;\n\n        if (from === to) {\n          return originalHistoryFunction.apply(this, args);\n        }\n\n        const handlerData = { from, to } satisfies HandlerDataHistory;\n        triggerHandlers('history', handlerData);\n      }\n      return originalHistoryFunction.apply(this, args);\n    };\n  }\n\n  fill(WINDOW.history, 'pushState', historyReplacementFunction);\n  fill(WINDOW.history, 'replaceState', historyReplacementFunction);\n}\n","import { isNativeFunction, logger } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport { WINDOW } from './types';\n\n/**\n * We generally want to use window.fetch / window.setTimeout.\n * However, in some cases this may be wrapped (e.g. by Zone.js for Angular),\n * so we try to get an unpatched version of this from a sandboxed iframe.\n */\n\ninterface CacheableImplementations {\n  setTimeout: typeof WINDOW.setTimeout;\n  fetch: typeof WINDOW.fetch;\n}\n\nconst cachedImplementations: Partial\u003cCacheableImplementations\u003e = {};\n\n/**\n * Get the native implementation of a browser function.\n *\n * This can be used to ensure we get an unwrapped version of a function, in cases where a wrapped function can lead to problems.\n *\n * The following methods can be retrieved:\n * - `setTimeout`: This can be wrapped by e.g. Angular, causing change detection to be triggered.\n * - `fetch`: This can be wrapped by e.g. ad-blockers, causing an infinite loop when a request is blocked.\n */\nexport function getNativeImplementation\u003cT extends keyof CacheableImplementations\u003e(\n  name: T,\n): CacheableImplementations[T] {\n  const cached = cachedImplementations[name];\n  if (cached) {\n    return cached;\n  }\n\n  let impl = WINDOW[name] as CacheableImplementations[T];\n\n  // Fast path to avoid DOM I/O\n  if (isNativeFunction(impl)) {\n    return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]);\n  }\n\n  const document = WINDOW.document;\n  // eslint-disable-next-line deprecation/deprecation\n  if (document \u0026\u0026 typeof document.createElement === 'function') {\n    try {\n      const sandbox = document.createElement('iframe');\n      sandbox.hidden = true;\n      document.head.appendChild(sandbox);\n      const contentWindow = sandbox.contentWindow;\n      if (contentWindow?.[name]) {\n        impl = contentWindow[name] as CacheableImplementations[T];\n      }\n      document.head.removeChild(sandbox);\n    } catch (e) {\n      // Could not create sandbox iframe, just use window.xxx\n      DEBUG_BUILD \u0026\u0026 logger.warn(`Could not create sandbox iframe for ${name} check, bailing to window.${name}: `, e);\n    }\n  }\n\n  // Sanity check: This _should_ not happen, but if it does, we just skip caching...\n  // This can happen e.g. in tests where fetch may not be available in the env, or similar.\n  if (!impl) {\n    return impl;\n  }\n\n  return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]);\n}\n\n/** Clear a cached implementation. */\nexport function clearCachedImplementation(name: keyof CacheableImplementations): void {\n  cachedImplementations[name] = undefined;\n}\n\n/**\n * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.\n * Whenever someone wraps the Fetch API and returns the wrong promise chain,\n * this chain becomes orphaned and there is no possible way to capture it's rejections\n * other than allowing it bubble up to this very handler. eg.\n *\n * const f = window.fetch;\n * window.fetch = function () {\n *   const p = f.apply(this, arguments);\n *\n *   p.then(function() {\n *     console.log('hi.');\n *   });\n *\n *   return p;\n * }\n *\n * `p.then(function () { ... })` is producing a completely separate promise chain,\n * however, what's returned is `p` - the result of original `fetch` call.\n *\n * This mean, that whenever we use the Fetch API to send our own requests, _and_\n * some ad-blocker blocks it, this orphaned chain will _always_ reject,\n * effectively causing another event to be captured.\n * This makes a whole process become an infinite loop, which we need to somehow\n * deal with, and break it in one way or another.\n *\n * To deal with this issue, we are making sure that we _always_ use the real\n * browser Fetch API, instead of relying on what `window.fetch` exposes.\n * The only downside to this would be missing our own requests as breadcrumbs,\n * but because we are already not doing this, it should be just fine.\n *\n * Possible failed fetch error messages per-browser:\n *\n * Chrome:  Failed to fetch\n * Edge:    Failed to Fetch\n * Firefox: NetworkError when attempting to fetch resource\n * Safari:  resource blocked by content blocker\n */\nexport function fetch(...rest: Parameters\u003ctypeof WINDOW.fetch\u003e): ReturnType\u003ctypeof WINDOW.fetch\u003e {\n  return getNativeImplementation('fetch')(...rest);\n}\n\n/**\n * Get an unwrapped `setTimeout` method.\n * This ensures that even if e.g. Angular wraps `setTimeout`, we get the native implementation,\n * avoiding triggering change detection.\n */\nexport function setTimeout(...rest: Parameters\u003ctypeof WINDOW.setTimeout\u003e): ReturnType\u003ctypeof WINDOW.setTimeout\u003e {\n  return getNativeImplementation('setTimeout')(...rest);\n}\n","import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nexport const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\ntype WindowWithXhr = Window \u0026 { XMLHttpRequest?: typeof XMLHttpRequest };\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) =\u003e void): void {\n  const type = 'xhr';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nexport function instrumentXHR(): void {\n  if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {\n    return;\n  }\n\n  const xhrproto = XMLHttpRequest.prototype;\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  xhrproto.open = new Proxy(xhrproto.open, {\n    apply(\n      originalOpen,\n      xhrOpenThisArg: XMLHttpRequest \u0026 SentryWrappedXMLHttpRequest,\n      xhrOpenArgArray:\n        | [method: string, url: string | URL]\n        | [method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null],\n    ) {\n      // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n      //       it means the error, that was caused by your XHR call did not\n      //       have a stack trace. If you are using HttpClient integration,\n      //       this is the expected behavior, as we are using this virtual error to capture\n      //       the location of your XHR call, and group your HttpClient events accordingly.\n      const virtualError = new Error();\n\n      const startTimestamp = timestampInSeconds() * 1000;\n\n      // open() should always be called with two or more arguments\n      // But to be on the safe side, we actually validate this and bail out if we don't have a method \u0026 url\n      const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n      const url = parseXhrUrlArg(xhrOpenArgArray[1]);\n\n      if (!method || !url) {\n        return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n      }\n\n      xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n        method,\n        url,\n        request_headers: {},\n      };\n\n      // if Sentry key appears in URL, don't capture it as a request\n      if (method === 'POST' \u0026\u0026 url.match(/sentry_key/)) {\n        xhrOpenThisArg.__sentry_own_request__ = true;\n      }\n\n      const onreadystatechangeHandler: () =\u003e void = () =\u003e {\n        // For whatever reason, this is not the same instance here as from the outer method\n        const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n        if (!xhrInfo) {\n          return;\n        }\n\n        if (xhrOpenThisArg.readyState === 4) {\n          try {\n            // touching statusCode in some platforms throws\n            // an exception\n            xhrInfo.status_code = xhrOpenThisArg.status;\n          } catch (e) {\n            /* do nothing */\n          }\n\n          const handlerData: HandlerDataXhr = {\n            endTimestamp: timestampInSeconds() * 1000,\n            startTimestamp,\n            xhr: xhrOpenThisArg,\n            virtualError,\n          };\n          triggerHandlers('xhr', handlerData);\n        }\n      };\n\n      if ('onreadystatechange' in xhrOpenThisArg \u0026\u0026 typeof xhrOpenThisArg.onreadystatechange === 'function') {\n        xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n          apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray: unknown[]) {\n            onreadystatechangeHandler();\n            return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n          },\n        });\n      } else {\n        xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n      }\n\n      // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n      // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n      // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n      xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n        apply(\n          originalSetRequestHeader,\n          setRequestHeaderThisArg: SentryWrappedXMLHttpRequest,\n          setRequestHeaderArgArray: unknown[],\n        ) {\n          const [header, value] = setRequestHeaderArgArray;\n\n          const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n          if (xhrInfo \u0026\u0026 isString(header) \u0026\u0026 isString(value)) {\n            xhrInfo.request_headers[header.toLowerCase()] = value;\n          }\n\n          return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n        },\n      });\n\n      return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n    },\n  });\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  xhrproto.send = new Proxy(xhrproto.send, {\n    apply(originalSend, sendThisArg: XMLHttpRequest \u0026 SentryWrappedXMLHttpRequest, sendArgArray: unknown[]) {\n      const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n      if (!sentryXhrData) {\n        return originalSend.apply(sendThisArg, sendArgArray);\n      }\n\n      if (sendArgArray[0] !== undefined) {\n        sentryXhrData.body = sendArgArray[0];\n      }\n\n      const handlerData: HandlerDataXhr = {\n        startTimestamp: timestampInSeconds() * 1000,\n        xhr: sendThisArg,\n      };\n      triggerHandlers('xhr', handlerData);\n\n      return originalSend.apply(sendThisArg, sendArgArray);\n    },\n  });\n}\n\n/**\n * Parses the URL argument of a XHR method to a string.\n *\n * See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open#url\n * url: A string or any other object with a stringifier — including a URL object — that provides the URL of the resource to send the request to.\n *\n * @param url - The URL argument of an XHR method\n * @returns The parsed URL string or undefined if the URL is invalid\n */\nfunction parseXhrUrlArg(url: unknown): string | undefined {\n  if (isString(url)) {\n    return url;\n  }\n\n  try {\n    // If the passed in argument is not a string, it should have a `toString` method as a stringifier.\n    // If that fails, we just return undefined (like in IE11 where URL is not available)\n    return (url as URL).toString();\n  } catch {} // eslint-disable-line no-empty\n\n  return undefined;\n}\n","import type { Logger } from '@sentry/core';\nimport { logger } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { NetworkMetaWarning } from './types';\n\n/**\n * Serializes FormData.\n *\n * This is a bit simplified, but gives us a decent estimate.\n * This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith\u0026age=13'.\n *\n */\nexport function serializeFormData(formData: FormData): string {\n  // @ts-expect-error passing FormData to URLSearchParams actually works\n  return new URLSearchParams(formData).toString();\n}\n\n/** Get the string representation of a body. */\nexport function getBodyString(body: unknown, _logger: Logger = logger): [string | undefined, NetworkMetaWarning?] {\n  try {\n    if (typeof body === 'string') {\n      return [body];\n    }\n\n    if (body instanceof URLSearchParams) {\n      return [body.toString()];\n    }\n\n    if (body instanceof FormData) {\n      return [serializeFormData(body)];\n    }\n\n    if (!body) {\n      return [undefined];\n    }\n  } catch (error) {\n    DEBUG_BUILD \u0026\u0026 _logger.error(error, 'Failed to serialize body', body);\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  DEBUG_BUILD \u0026\u0026 _logger.info('Skipping network body because of body type', body);\n\n  return [undefined, 'UNPARSEABLE_BODY_TYPE'];\n}\n\n/**\n * Parses the fetch arguments to extract the request payload.\n *\n * We only support getting the body from the fetch options.\n */\nexport function getFetchRequestArgBody(fetchArgs: unknown[] = []): RequestInit['body'] | undefined {\n  if (fetchArgs.length !== 2 || typeof fetchArgs[1] !== 'object') {\n    return undefined;\n  }\n\n  return (fetchArgs[1] as RequestInit).body;\n}\n","import type { Span, SpanAttributes } from '@sentry/core';\nimport {\n  browserPerformanceTimeOrigin,\n  getActiveSpan,\n  getCurrentScope,\n  getRootSpan,\n  htmlTreeAsString,\n  SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  spanToJSON,\n} from '@sentry/core';\nimport {\n  addInpInstrumentationHandler,\n  addPerformanceInstrumentationHandler,\n  isPerformanceEventTiming,\n} from './instrument';\nimport { getBrowserPerformanceAPI, msToSec, startStandaloneWebVitalSpan } from './utils';\n\nconst LAST_INTERACTIONS: number[] = [];\nconst INTERACTIONS_SPAN_MAP = new Map\u003cnumber, Span\u003e();\n\n/**\n * Start tracking INP webvital events.\n */\nexport function startTrackingINP(): () =\u003e void {\n  const performance = getBrowserPerformanceAPI();\n  if (performance \u0026\u0026 browserPerformanceTimeOrigin()) {\n    const inpCallback = _trackINP();\n\n    return (): void =\u003e {\n      inpCallback();\n    };\n  }\n\n  return () =\u003e undefined;\n}\n\nconst INP_ENTRY_MAP: Record\u003cstring, 'click' | 'hover' | 'drag' | 'press'\u003e = {\n  click: 'click',\n  pointerdown: 'click',\n  pointerup: 'click',\n  mousedown: 'click',\n  mouseup: 'click',\n  touchstart: 'click',\n  touchend: 'click',\n  mouseover: 'hover',\n  mouseout: 'hover',\n  mouseenter: 'hover',\n  mouseleave: 'hover',\n  pointerover: 'hover',\n  pointerout: 'hover',\n  pointerenter: 'hover',\n  pointerleave: 'hover',\n  dragstart: 'drag',\n  dragend: 'drag',\n  drag: 'drag',\n  dragenter: 'drag',\n  dragleave: 'drag',\n  dragover: 'drag',\n  drop: 'drag',\n  keydown: 'press',\n  keyup: 'press',\n  keypress: 'press',\n  input: 'press',\n};\n\n/** Starts tracking the Interaction to Next Paint on the current page. */\nfunction _trackINP(): () =\u003e void {\n  return addInpInstrumentationHandler(({ metric }) =\u003e {\n    if (metric.value == undefined) {\n      return;\n    }\n\n    const entry = metric.entries.find(entry =\u003e entry.duration === metric.value \u0026\u0026 INP_ENTRY_MAP[entry.name]);\n\n    if (!entry) {\n      return;\n    }\n\n    const { interactionId } = entry;\n    const interactionType = INP_ENTRY_MAP[entry.name];\n\n    /** Build the INP span, create an envelope from the span, and then send the envelope */\n    const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n    const duration = msToSec(metric.value);\n    const activeSpan = getActiveSpan();\n    const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n    // We first try to lookup the span from our INTERACTIONS_SPAN_MAP,\n    // where we cache the route per interactionId\n    const cachedSpan = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;\n\n    const spanToUse = cachedSpan || rootSpan;\n\n    // Else, we try to use the active span.\n    // Finally, we fall back to look at the transactionName on the scope\n    const routeName = spanToUse ? spanToJSON(spanToUse).description : getCurrentScope().getScopeData().transactionName;\n\n    const name = htmlTreeAsString(entry.target);\n    const attributes: SpanAttributes = {\n      [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.inp',\n      [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `ui.interaction.${interactionType}`,\n      [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry.duration,\n    };\n\n    const span = startStandaloneWebVitalSpan({\n      name,\n      transaction: routeName,\n      attributes,\n      startTime,\n    });\n\n    if (span) {\n      span.addEvent('inp', {\n        [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: 'millisecond',\n        [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: metric.value,\n      });\n\n      span.end(startTime + duration);\n    }\n  });\n}\n\n/**\n * Register a listener to cache route information for INP interactions.\n */\nexport function registerInpInteractionListener(): void {\n  const handleEntries = ({ entries }: { entries: PerformanceEntry[] }): void =\u003e {\n    const activeSpan = getActiveSpan();\n    const activeRootSpan = activeSpan \u0026\u0026 getRootSpan(activeSpan);\n\n    entries.forEach(entry =\u003e {\n      if (!isPerformanceEventTiming(entry) || !activeRootSpan) {\n        return;\n      }\n\n      const interactionId = entry.interactionId;\n      if (interactionId == null) {\n        return;\n      }\n\n      // If the interaction was already recorded before, nothing more to do\n      if (INTERACTIONS_SPAN_MAP.has(interactionId)) {\n        return;\n      }\n\n      // We keep max. 10 interactions in the list, then remove the oldest one \u0026 clean up\n      if (LAST_INTERACTIONS.length \u003e 10) {\n        const last = LAST_INTERACTIONS.shift() as number;\n        INTERACTIONS_SPAN_MAP.delete(last);\n      }\n\n      // We add the interaction to the list of recorded interactions\n      // and store the span for this interaction\n      LAST_INTERACTIONS.push(interactionId);\n      INTERACTIONS_SPAN_MAP.set(interactionId, activeRootSpan);\n    });\n  };\n\n  addPerformanceInstrumentationHandler('event', handleEntries);\n  addPerformanceInstrumentationHandler('first-input', handleEntries);\n}\n"],"version":3}
